Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 画布双缓冲图形不工作_Java_Graphics_Awt_Double Buffering - Fatal编程技术网

Java 画布双缓冲图形不工作

Java 画布双缓冲图形不工作,java,graphics,awt,double-buffering,Java,Graphics,Awt,Double Buffering,我尝试为画布制作双缓冲图形,但它总是在渲染后立即消失,有时甚至无法渲染,下面是代码: package initilizer; import java.awt.AWTException; import java.awt.Canvas; import java.awt.Color; import java.awt.Cursor; import java.awt.Graphics; import java.awt.Image; import java.awt.MouseInfo; import jav

我尝试为画布制作双缓冲图形,但它总是在渲染后立即消失,有时甚至无法渲染,下面是代码:

package initilizer;
import java.awt.AWTException;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import input.Keyboard;

public class Main extends Canvas{

    static int width = 800;
    static int height = 600;
    int cx = width/2;
    int cy = height/2;
    boolean initilized = false;

    double FOV = 0.5 * Math.PI;

    Camera cam = new Camera(1.0, 5.0, 3.0);
    Camera cam1 = new Camera(10.0, 50.0, 30.0);
    long lastFpsCheck = System.currentTimeMillis();

    public static JFrame frame = new JFrame("3D Engine");

    Robot robot;

    static Keyboard keyboard = new Keyboard();

    Image img;


    public static void main(String[] args) {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Canvas canvas = new Main();
        canvas.setSize(width, height);
        canvas.addKeyListener(keyboard);
        canvas.setFocusable(true);
        canvas.setBackground(Color.black);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);
        BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);

        // Create a new blank cursor.
        Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
            cursorImg, new Point(0, 0), "blank cursor");

        // Set the blank cursor to the JFrame.
        canvas.setCursor(blankCursor);
    }

    void init() {
        try {
            robot = new Robot();
        } catch (AWTException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    double[] rotate2D(double[] pos,double[] rot) {
        double x = pos[0];
        double y = pos[1];

        double s = rot[0];
        double c = rot[1];

        double[] result = {(x * c) - (y * s), (y * c) + (x * s)};

        return result;
    }


    public void paint(Graphics MainGraphics) {
        Point startMousePos = MouseInfo.getPointerInfo().getLocation();
        double startMouseX = startMousePos.getX();
        double startMouseY = startMousePos.getY();

        if(img == null)
        {
            img = createImage(width, height);
        }
        Graphics g = img.getGraphics();;

        // First run initialization
        if (initilized == false) {
            initilized = true;
            init();
        }

        // Storing start time for FPS Counting
        long startTime = System.currentTimeMillis();

        // Clearing Last Frame
        //g.clearRect(0, 0, width, height);

        // Drawing Crosshair
        g.setColor(Color.white);
        g.fillRect(cx - 8, cy - 1, 16, 2);
        g.fillRect(cx - 1, cy - 8, 2, 16);


        // Drawing Debugger Menu
        g.drawString("HI WASSUp", 0, 16);





        g.dispose();


        if (frame.isFocused() == true) {
            robot.mouseMove(cx, cy);
            Point endMousePos = MouseInfo.getPointerInfo().getLocation();
            double endMouseX = endMousePos.getX();
            double endMouseY = endMousePos.getY();
            double[] rel = {startMouseX - endMouseX, startMouseY - endMouseY};
            cam.mouseMotion(rel);
        }




        // Limiting FPS
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Calculating FPS
        long endTime = System.currentTimeMillis();
        double delta_time = (endTime - startTime);
        if ((lastFpsCheck + 1000) < endTime) {
            lastFpsCheck = endTime;
            frame.setTitle("3D Engine - FPS: " + (int) (1000/delta_time));
        }

        // Controlling camera movement
        if (keyboard.getW() == true) {
            cam.update(delta_time, "W");
        }
        if (keyboard.getA() == true) {
            cam.update(delta_time, "A");
        }
        if (keyboard.getS() == true) {
            cam.update(delta_time, "S");
        }
        if (keyboard.getD() == true) {
            cam.update(delta_time, "D");
        }
        if (keyboard.getE() == true) {
            cam.update(delta_time, "E");
        }
        if (keyboard.getQ() == true) {
            cam.update(delta_time, "Q");
        }

        // Draw rendered frame
        MainGraphics.drawImage(img, 0,0, null);

        // Draw next frame
        repaint();
    }

}
包初始化器;
导入java.awt.AWTException;
导入java.awt.Canvas;
导入java.awt.Color;
导入java.awt.Cursor;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.MouseInfo;
导入java.awt.Point;
导入java.awt.Robot;
导入java.awt.Toolkit;
导入java.awt.image.buffereImage;
导入javax.swing.JFrame;
输入。键盘;
公共类Main扩展画布{
静态整数宽度=800;
静态内部高度=600;
int cx=宽度/2;
int cy=高度/2;
布尔初始化=假;
双视场=0.5*Math.PI;
摄像头=新摄像头(1.0、5.0、3.0);
摄像头cam1=新摄像头(10.0,50.0,30.0);
long lastFpsCheck=System.currentTimeMillis();
公共静态JFrame=新JFrame(“3D引擎”);
机器人;
静态键盘=新键盘();
图像img;
公共静态void main(字符串[]args){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Canvas Canvas=newmain();
画布。设置大小(宽度、高度);
addKeyListener(键盘);
canvas.setFocusable(true);
帆布背景(颜色:黑色);
frame.add(画布);
frame.pack();
frame.setVisible(true);
BuffereImage cursorImg=新的BuffereImage(16,16,BuffereImage.TYPE_INT_ARGB);
//创建一个新的空白光标。
Cursor blankCursor=Toolkit.getDefaultToolkit().createCustomCursor(
光标,新点(0,0),“空白光标”);
/将空白光标设置为JFrror。
canvas.setCursor(blankCursor);
}
void init(){
试一试{
机器人=新机器人();
}捕获(awtexe){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
双[]旋转2D(双[]位置,双[]旋转){
双x=位置[0];
双y=位置[1];
双s=rot[0];
双c=旋转[1];
双[]结果={(x*c)-(y*s),(y*c)+(x*s)};
返回结果;
}
公共空白绘制(图形主图形){
Point startMousePos=MouseInfo.getPointerInfo().getLocation();
double startMouseX=startMousePos.getX();
double startMouseY=startMousePos.getY();
如果(img==null)
{
img=createImage(宽度、高度);
}
Graphics g=img.getGraphics();;
//首次运行初始化
if(initilized==false){
initilized=true;
init();
}
//存储FPS计数的开始时间
long startTime=System.currentTimeMillis();
//清除最后一帧
//g、 clearRect(0,0,宽度,高度);
//画十字线
g、 setColor(Color.white);
g、 fillRect(cx-8,cy-1,16,2);
g、 fillRect(cx-1,cy-8,2,16);
//图形调试器菜单
g、 抽绳(“HI WASSUp”,0,16);
g、 处置();
if(frame.isFocused()==true){
mouseMove(cx,cy);
Point endMousePos=MouseInfo.getPointerInfo().getLocation();
double-endMouseX=endMousePos.getX();
double-endMouseY=endMousePos.getY();
double[]rel={startMouseX-endMouseX,startMouseY-endMouseY};
mouseMotion(rel);
}
//极限FPS
试一试{
睡眠(1000);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
//计算FPS
long-endTime=System.currentTimeMillis();
双增量时间=(结束时间-开始时间);
如果((lastFpsCheck+1000)<结束时间){
lastFpsCheck=结束时间;
frame.setTitle(“3D引擎-FPS:”+(int)(1000/delta_时间));
}
//控制摄像机运动
if(keyboard.getW()==true){
凸轮更新(增量时间,“W”);
}
if(keyboard.getA()==true){
凸轮更新(增量时间,“A”);
}
if(keyboard.get()==true){
凸轮更新(增量时间,“S”);
}
if(keyboard.getD()==true){
凸轮更新(增量时间,“D”);
}
if(keyboard.getE()==true){
凸轮更新(增量时间,“E”);
}
if(keyboard.getQ()==true){
凸轮更新(增量时间,“Q”);
}
//绘制渲染帧
MainGraphics.drawImage(img,0,0,空);
//画下一帧
重新油漆();
}
}

我最近发布了一个关于这段代码的问题,如果你愿意,你可以查看上一篇文章中的键盘java,但是请帮助我,我对java编程还不熟悉(我仍然有一些编程经验),谢谢你,你的问题的答案很复杂

  • 默认情况下,Java Swing
    JPanel
    (或
    JComponent
    )是双缓冲的
  • Swing已经有了一个您无法控制的绘画机制,所以您需要在它的功能范围内工作
  • 使用
    java.awt.Canvas
    的唯一真正原因是,如果希望完全控制绘制过程
  • 我建议你做的第一件事是看一看,更好地了解在Swing/AWT中绘画是如何工作的。这将使您更好地了解API,以及您是想使用它还是定义自己的API

    其他一些令人关注的领域:

    • 不要做
      Thread.sleep(1000)
      paint
      方法中,在
      paint
      方法返回之前,不会渲染任何内容。您希望将“更新过程”与“绘制过程”分开。绘画只靠绘画。你所有的决策都应该作为你的“更新通行证”的一部分来完成
      import java.awt.Dimension;
      import java.awt.EventQueue;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.Point;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.event.KeyEvent;
      import java.awt.event.MouseAdapter;
      import java.awt.event.MouseEvent;
      import java.time.Duration;
      import java.time.Instant;
      import java.util.HashSet;
      import java.util.Set;
      import java.util.StringJoiner;
      import javax.swing.AbstractAction;
      import javax.swing.ActionMap;
      import javax.swing.InputMap;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.KeyStroke;
      import javax.swing.Timer;
      
      public class Test {
      
          public static void main(String[] args) {
              new Test();
          }
      
          public Test() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      JFrame frame = new JFrame();
                      Main main = new Main();
                      frame.add(main);
                      frame.pack();
                      frame.setLocationRelativeTo(null);
                      frame.setVisible(true);
                      main.start();
                  }
              });
          }
      
          // Decouple the input from the implementation
          enum Input {
              UP, DOWN, LEFT, RIGHT
          }
      
          public class Main extends JPanel {
      
              boolean initilized = false;
      
              double FOV = 0.5 * Math.PI;
      
              private Instant lastFpsCheck = Instant.now();
              private Point mousePosition;
              private Timer timer;
      
              private Set<Input> input = new HashSet<>();
      
              public Main() {
                  MouseAdapter mouseHandler = new MouseAdapter() {
                      @Override
                      public void mouseMoved(MouseEvent e) {
                          // This is within the components coordinate space
                          mousePosition = e.getPoint();
                      }
      
                      @Override
                      public void mouseEntered(MouseEvent e) {
                          mousePosition = e.getPoint();
                      }
      
                      @Override
                      public void mouseExited(MouseEvent e) {
                          mousePosition = null;
                      }
                  };
      
                  addMouseMotionListener(mouseHandler);
                  addMouseListener(mouseHandler);
      
                  InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
                  ActionMap actionMap = getActionMap();
      
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Pressed.up");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Released.up");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Pressed.down");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Released.down");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "Pressed.left");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "Released.left");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "Pressed.right");
                  inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "Released.right");
      
                  actionMap.put("Pressed.up", new InputAction(input, Input.UP, true));
                  actionMap.put("Released.up", new InputAction(input, Input.UP, false));
                  actionMap.put("Pressed.down", new InputAction(input, Input.DOWN, true));
                  actionMap.put("Released.down", new InputAction(input, Input.DOWN, false));
                  actionMap.put("Pressed.left", new InputAction(input, Input.LEFT, true));
                  actionMap.put("Released.left", new InputAction(input, Input.LEFT, false));
                  actionMap.put("Pressed.right", new InputAction(input, Input.RIGHT, true));
                  actionMap.put("Released.right", new InputAction(input, Input.RIGHT, false));
      
                  timer = new Timer(15, new ActionListener() {
                      @Override
                      public void actionPerformed(ActionEvent evt) {
                          update();
                      }
                  });
              }
      
              public void start() {
                  startTime = Instant.now();
                  timer.start();
              }
      
              public void stop() {
                  timer.stop();
              }
      
              // The start time of a given cycle
              private Instant startTime;
              // The estimated number of frames per second
              private double fps = 0;
              // The number of acutal updates performed
              // within a given cycle
              private int updates = 0;
      
              protected void update() {
      
                  if (startTime == null) {
                      startTime = Instant.now();
                  }
      
                  if (input.contains(Input.UP)) {
                      //cam.update(delta_time, "W");
                  }
                  if (input.contains(Input.LEFT)) {
                      //cam.update(delta_time, "A");
                  }
                  if (input.contains(Input.DOWN)) {
                      //cam.update(delta_time, "S");
                  }
                  if (input.contains(Input.RIGHT)) {
                      //cam.update(delta_time, "D");
                  }
                  // Don't know what these do, so you will need to devices
                  // your own action
                  //if (input.contains(Input.UP)) {
                  //cam.update(delta_time, "E");
                  //}
                  //if (input.contains(Input.UP)) {
                  //cam.update(delta_time, "Q");
                  //}
      
                  Instant endTime = Instant.now();
                  Duration deltaTime = Duration.between(startTime, endTime);
                  if (lastFpsCheck.plusSeconds(1).isBefore(endTime)) {
                      System.out.println(deltaTime.toMillis());
                      lastFpsCheck = endTime;
                      fps = updates;
                      updates = 0;
                      startTime = Instant.now();
                  }
      
                  updates++;
                  repaint();
              }
      
              @Override
              public Dimension getPreferredSize() {
                  return new Dimension(800, 600);
              }
      
              double[] rotate2D(double[] pos, double[] rot) {
                  double x = pos[0];
                  double y = pos[1];
      
                  double s = rot[0];
                  double c = rot[1];
      
                  double[] result = {(x * c) - (y * s), (y * c) + (x * s)};
      
                  return result;
              }
      
              @Override
              protected void paintComponent(Graphics g) {
                  super.paintComponent(g);
                  //Point startMousePos = MouseInfo.getPointerInfo().getLocation();
                  //double startMouseX = startMousePos.getX();
                  //double startMouseY = startMousePos.getY();
      
                  Graphics2D g2d = (Graphics2D) g.create();
      
                  // Drawing Debugger Menu
                  g2d.drawString("HI WASSUp", 0, 20);
      
                  if (mousePosition != null) {
                      g2d.drawString(mousePosition.x + "x" + mousePosition.y, 0, 40);
                      // Your old code is broken, because MouseInfo.getPointerInfo 
                      // doesn't give you the position of the mouse from within
                      // the components coordinate space, but in the screen space
                      // instead
                      //robot.mouseMove(cx, cy);
                      //Point endMousePos = MouseInfo.getPointerInfo().getLocation();
                      //double endMouseX = endMousePos.getX();
                      //double endMouseY = endMousePos.getY();
                      //double[] rel = {startMouseX - endMouseX, startMouseY - endMouseY};
                      //cam.mouseMotion(rel);
                  }
      
                  g2d.drawString(Double.toString(fps), 0, 60);
      
                  StringJoiner sj = new StringJoiner(", ");
                  for (Input item : input) {
                      switch (item) {
                          case DOWN:
                              sj.add("down");
                              break;
                          case UP:
                              sj.add("up");
                              break;
                          case LEFT:
                              sj.add("left");
                              break;
                          case RIGHT:
                              sj.add("right");
                              break;
                      }
                  }
      
                  g2d.drawString(sj.toString(), 0, 80);
                  g2d.dispose();
              }
      
              public class InputAction extends AbstractAction {
      
                  private final Set<Input> input;
                  private final Input direction;
                  private final boolean add;
      
                  public InputAction(Set<Input> input, Input direction, boolean add) {
                      this.input = input;
                      this.direction = direction;
                      this.add = add;
                  }
      
                  @Override
                  public void actionPerformed(ActionEvent evt) {
                      if (add) {
                          input.add(direction);
                      } else {
                          input.remove(direction);
                      }
                  }
      
              }
      
          }
      }