我在java中使用2D游戏。
到目前为止,我的代码是:
Game.java:
package main;
import javax.swing.JFrame;
public class Game {
public static void main(String[] args) {
JFrame gameWindow = new JFrame("Snake! - By Casida");
gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameWindow.add(new GamePanel());
gameWindow.pack();
gameWindow.setResizable(false);
gameWindow.setVisible(true);
}
}
GamePanel.java,这是我覆盖addNotify()的地方。
package main;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable, KeyListener {
//Dimensions
public static final int WIDTH = 384;
public static final int HEIGHT = 384;
public static final int SCALE = 2;
//Game loop
private Thread thread;
private boolean running = false;
private int FPS = 60;
private long targetTime = 1000 / FPS;
//Image
private BufferedImage image;
private Graphics2D g;
public GamePanel() {
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setFocusable(true);
requestFocus();
}
@Override
public void addNotify() {
super.addNotify();
if(thread == null) {
thread = new Thread(this);
addKeyListener(this);
thread.start();
}
}
private void init() {
running = true;
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
}
@Override
public void run() {
init();
long start;
long elapsed;
long wait;
while(running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0)
wait = 5;
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update() {
}
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
}
public void drawToScreen() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
g2.dispose();
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
我已经看到不鼓励覆盖addNotify方法,但我需要做些什么来获得相同的结果,而不是覆盖它?
答案 0 :(得分:1)
分开你的游戏循环&#34;进入自己的类,可能实现Runnable
。使用面板和游戏循环之间共享的某种模型&#34;。 &#34;游戏循环&#34;应该更新模型的状态,面板应该绘制它。
如果需要,您可以考虑使用一个允许&#34;游戏循环的界面。通知UI它应该自行更新
一旦你创建了UI,你就构建了游戏循环&#34;上课并开始
KeyListener
,请使用Key bindings getGraphics
,覆盖paintComponent
并在那里执行自定义绘画。有关详细信息,请参阅Performing Custom Painting。 Swing使用被动渲染引擎,这意味着可以随时进行更新,大多数情况下都不会执行任何操作。使用getGraphics
进行绘画的任何内容都将被绘画,这可能会导致意外且难以复制的闪烁Graphics
上下文,这可能会阻止将来的更新发生