1

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

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();
    }

}
4

1 回答 1

5

您当前的循环可能会占用 Swing Event D ispatch T线程EDT从而有效地冻结您的应用程序,因为所有重要的线程都无法执行它必须做的事情——渲染您的应用程序并响应用户输入。您需要通过确保循环在后台线程中运行来考虑线程。

话虽如此,我必须质疑您的教程的质量、及时性和相关性,如果它建议您使用 Canvas 等 AWT 组件进行编码,并且它是否建议您使用 null 布局和组件的绝对定位(即使用setBounds(...))。按照教程使用所有 Swing 组件和 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();
         }
      });
   }
}
于 2013-07-02T21:58:14.113 回答