Java 2D 游戏。除了调用 addnotify 之外,还能做什么?

标签 java graphics2d game-loop

我正在用 java 制作一个 2D 游戏。

到目前为止我的代码是这样的:

游戏.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 方法,但是我需要做什么才能获得相同的结果而不重写它?

最佳答案

将你的“游戏循环”分离到它自己的类中,可能实现Runnable。使用面板和“游戏循环”之间共享的某种模型。 “游戏循环”应该更新模型的状态,并且面板应该绘制它。

如果需要,您可以考虑使用一个允许“游戏循环”通知 UI 它应该自行更新的界面

创建 UI 后,您将构建“游戏循环”类并启动它

  • 不要使用KeyListener,使用Key bindings
  • 不要使用getGraphics,重写paintComponent并在那里执行自定义绘制。请参阅Performing Custom Painting更多细节。 Swing 使用被动渲染引擎,这意味着更新可以随时发生,大多数情况下您无需执行任何操作。使用 getGraphics 绘制的任何内容都将被绘制,这可能会导致意外且难以复制的闪烁
  • 不要处置不是您“创建”的Graphics上下文,这可能会阻止将来的更新
  • Swing 组件默认是双缓冲的,因此除非您有迫切需要,否则不需要重新发明轮子

关于Java 2D 游戏。除了调用 addnotify 之外,还能做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24965168/

相关文章:

java - LWJGL Display.update() 自动将 FPS 限制在 60

java - elasticsearch 分词器设置

java - 如何追溯这个编译错误?

java - 同步块(synchronized block)不会阻塞不同的对象

ios - 有没有比 'scheduledTimerWithTimeInterval' 更好的方法来制作游戏循环

c - 这是 FPS 独立游戏循环的良好实现吗?

java - 单链表还原中的错误

java - Java中如何计算Path2D的长度?

java - 这是 MVC 吗?简单的Java Graphics2D绘图程序

java - 在 java.awt.Graphics 上绘制 java.awt.Cursor