java图形中缓冲区的使用

java图形中缓冲区的使用,java,swing,graphics,Java,Swing,Graphics,我找到了一个在互联网上创建2D图形游戏的培训,并在此基础上编写了下面的代码,但当我编译时,什么都没有发生! 它只是显示一个没有任何内容的窗口。通过使用抽绳和抽绳,我真的希望看到一些东西,但窗户是空的!有什么问题吗? 代码错了吗?还是我使用了错误的方法 import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.image.

我找到了一个在互联网上创建2D图形游戏的培训,并在此基础上编写了下面的代码,但当我编译时,什么都没有发生! 它只是显示一个没有任何内容的窗口。通过使用抽绳和抽绳,我真的希望看到一些东西,但窗户是空的!有什么问题吗? 代码错了吗?还是我使用了错误的方法

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Game extends Canvas {
    BufferStrategy strategy;
    boolean gameRunning = true;

        public Game() {     
            JFrame jf = new JFrame("My Graphic thingy !");

        JPanel panel = (JPanel) jf.getContentPane();
        panel.setPreferredSize(new Dimension(800, 600));
        panel.setLayout(null);

        setBounds(0, 0, 800, 600);
        panel.add(this);

        setIgnoreRepaint(true);
        jf.pack();

        jf.setResizable(false);
        jf.setVisible(true);

        jf.createBufferStrategy(2);
        strategy = jf.getBufferStrategy();

    }

    public void gameLoop() {
        long lastLoopTime = System.currentTimeMillis();
        while (gameRunning) {
            lastLoopTime = System.currentTimeMillis();

            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
            g.setColor(Color.black);
            g.fillRect(0, 0, 800, 600);
            g.drawString("HellO", 12,12);
            g.drawLine(10, 10, 30, 30);
            g.dispose();
            strategy.show();
            try {
                    Thread.sleep(2000);
            } catch (Exception e) {
            }
        }
    }
    public static void main(String[] args) {
        Game g = new Game();

        g.gameLoop();
    }

}

您当前的循环可能会占用Swing事件调度线程,或EDT,从而有效地冻结您的应用程序,因为这个非常重要的线程无法执行它必须执行的操作—呈现您的应用程序并响应用户输入。您需要通过确保循环在后台线程中运行来考虑线程

话虽如此,如果您的教程建议您使用AWT组件(如Canvas)进行编码,并且建议您使用零布局和组件的绝对定位(即使用
setBounds(…)
),那么我必须质疑教程的质量、及时性和相关性。根据教程,使用所有Swing组件和Swing图形会更好

请看一看:

  • 基本Swing图形教程:
  • 更高级的Swing和AWT图形文章:
  • Swing线程教程:

编辑:还有

  • 您不应该尝试直接绘制到JFrame,而应该使用JPanel,通常使用它的
    paintComponent(…)
    方法,尽管有些游戏做的事情不同,并且使用主动渲染而不是典型的被动渲染
  • 不要使用与绘图文本相同的颜色作为背景,因为如果它们相同,您将永远看不到任何文本

编辑2:例如

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class Game2 extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;
   private static final int TIMER_DELAY = 50;
   private static final int DELTA_WIDTH = 50;
   private static final Color HELLO_COLOR = new Color(150, 150, 255);
   private int delta = 0;
   private BufferedImage img;

   public Game2() {
      img = createMyImage();
      setBackground(Color.BLACK);
      new Timer(TIMER_DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            delta++;
            repaint(delta - 10, delta - 10, DELTA_WIDTH + 20, DELTA_WIDTH + 20);
         }
      }).start();
   }

   private BufferedImage createMyImage() {
      BufferedImage myImg = new BufferedImage(DELTA_WIDTH, DELTA_WIDTH,
            BufferedImage.TYPE_INT_ARGB);
      Graphics g = myImg.getGraphics();
      g.setColor(HELLO_COLOR);
      g.drawString("Hello", 12, 12);
      g.setColor(Color.red);
      g.drawLine(10, 10, 30, 30);

      g.dispose();
      return myImg;
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(img, delta, delta, this);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Game2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new Game2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

您当前的循环可能会占用Swing事件调度线程,或EDT,从而有效地冻结您的应用程序,因为这个非常重要的线程无法执行它必须执行的操作—呈现您的应用程序并响应用户输入。您需要通过确保循环在后台线程中运行来考虑线程

话虽如此,如果您的教程建议您使用AWT组件(如Canvas)进行编码,并且建议您使用零布局和组件的绝对定位(即使用
setBounds(…)
),那么我必须质疑教程的质量、及时性和相关性。根据教程,使用所有Swing组件和Swing图形会更好

请看一看:

  • 基本Swing图形教程:
  • 更高级的Swing和AWT图形文章:
  • Swing线程教程:

编辑:还有

  • 您不应该尝试直接绘制到JFrame,而应该使用JPanel,通常使用它的
    paintComponent(…)
    方法,尽管有些游戏做的事情不同,并且使用主动渲染而不是典型的被动渲染
  • 不要使用与绘图文本相同的颜色作为背景,因为如果它们相同,您将永远看不到任何文本

编辑2:例如

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class Game2 extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;
   private static final int TIMER_DELAY = 50;
   private static final int DELTA_WIDTH = 50;
   private static final Color HELLO_COLOR = new Color(150, 150, 255);
   private int delta = 0;
   private BufferedImage img;

   public Game2() {
      img = createMyImage();
      setBackground(Color.BLACK);
      new Timer(TIMER_DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            delta++;
            repaint(delta - 10, delta - 10, DELTA_WIDTH + 20, DELTA_WIDTH + 20);
         }
      }).start();
   }

   private BufferedImage createMyImage() {
      BufferedImage myImg = new BufferedImage(DELTA_WIDTH, DELTA_WIDTH,
            BufferedImage.TYPE_INT_ARGB);
      Graphics g = myImg.getGraphics();
      g.setColor(HELLO_COLOR);
      g.drawString("Hello", 12, 12);
      g.setColor(Color.red);
      g.drawLine(10, 10, 30, 30);

      g.dispose();
      return myImg;
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(img, delta, delta, this);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Game2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new Game2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}