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 Thread ( EDT )を結びつけ、アプリケーションを効果的にフリーズさせます。これは、このすべての重要なスレッドが、アプリケーションのレンダリングとユーザー入力への応答という、本来行うべきことを実行できないためです。ループがバックグラウンド スレッドで実行されることを確認して、スレッド化を考慮する必要があります。

そうは言っても、Canvas などの AWT コンポーネントを使用してコーディングすることを推奨している場合、および null レイアウトとコンポーネントの絶対配置 (つまり、の使用setBounds(...)) を使用することを推奨している場合、チュートリアルの品質、適時性、および関連性を疑問視する必要があります。チュートリアルに従って、すべての Swing コンポーネントと Swing グラフィックスを使用する方がはるかに優れています。

ご覧ください:


編集:また、

  • JFrame に直接描画するのではなく、通常はそのpaintComponent(...)メソッドで JPanel を描画する必要がありますが、一部のゲームでは動作が異なり、通常のパッシブ レンダリングではなくアクティブ レンダリングを使用します。
  • 背景に描画テキストと同じ色を使用しないでください。同じ色を使用すると、テキストが表示されなくなります。

編集 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 に答える