gpt4 book ai didi

java - 如何创建无闪烁的 Java 游戏循环?

转载 作者:行者123 更新时间:2023-11-29 05:12:16 24 4
gpt4 key购买 nike

我一直在尝试创建一个 Java 游戏循环来显示一些简单的开始,但无论我尝试什么,我都无法让它停止闪烁。我已经尝试使用谷歌搜索解决方案,但要么是我的 google-fu 不够好,要么是我做错了一些严重的事情。

我将这段代码发布在这里,希望我只是做错了一些可以纠正的事情。在这一点上,我很想用另一种语言重新开始,上次我使用它时 SFML 很好。为可怕的代码道歉。

主要.java:

public class Main {
public static void main(String[] args) {
new GameFrame("Game");
}
}

游戏框架.java:

import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Toolkit;

import javax.swing.JFrame;

public class GameFrame extends JFrame {
protected GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();

public GameFrame(String title) {
super(title);
init();
}

public void init() {
setDefaultCloseOperation(EXIT_ON_CLOSE);

// Calculate the size of the window, taking into account the size of toolbars etc.
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(device.getDefaultConfiguration());
setSize(
(int) ((device.getDefaultConfiguration().getBounds().width - insets.left - insets.right) * 0.8),
(int) ((device.getDefaultConfiguration().getBounds().height - insets.top - insets.bottom) * 0.8)
);

// Centre and start maximised.
setLocationRelativeTo(null);
setExtendedState(MAXIMIZED_BOTH);

if(false) {
// Important otherwise you get an ugly border.
super.setVisible(false);
setUndecorated(true);
device.setFullScreenWindow(this);
} else {
setUndecorated(false);
device.setFullScreenWindow(null);
super.setVisible(true);
}

GamePanel panel = new GamePanel();

panel.setBackground(Color.BLACK);
new Thread(panel).start();

add(panel);
}
}

游戏面板.java:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;

import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable {
protected boolean running = false;

protected long lastTime;

protected int width = 0;
protected int height = 0;

protected Image image;
protected Graphics2D graphics;

protected double x = 0;
protected double y = 0;

protected void updateState(double delta) {
x = x + 0.00001 * delta;
y = y + 0.00001 * delta;
}

public void run() {
running = true;
lastTime = System.nanoTime();

while(width == 0 || height == 0) {
width = getBounds().width;
height = getBounds().height;
}

setDoubleBuffered(true);

while(running) {
long now = System.nanoTime();
long updateLength = now - lastTime;
double delta = updateLength / (10 ^ 9 / 60);

updateState(delta);

paintComponent(getGraphics());

lastTime = System.nanoTime();

try {Thread.sleep((now - lastTime + (10 ^ 9 / 60)) / (10 ^ 6));} catch (Exception e) {}
}
}

public void paintComponent(Graphics g) {
super.paintComponent(g);

if(isVisible() && width > 0 && height > 0) {

setDoubleBuffered(true);

if(image == null) {
image = createImage(width, height);
graphics = (Graphics2D) image.getGraphics();
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}

graphics.setColor(Color.black);
graphics.fillRect(0, 0, width, height);

graphics.setColor(Color.WHITE);
graphics.fillRect(100, 20, 100, 100);

graphics.fillOval((int) x, (int) y, 30, 30);

g.drawImage(image, 0, 0, this);
}
}
}

最佳答案

您的程序片段在几个方面是不正确的:

  • Swing GUI 对象应该event dispatch thread 上构造和操作.

  • 不要使用getGraphics();图形上下文paintComponent()中有效。

  • JPanel默认情况下是双缓冲的。

  • 使用 javax.swing.Timer 的实例调整动画的节奏;一个完整的例子可以在这个 AnimationTest 中看到.

关于java - 如何创建无闪烁的 Java 游戏循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28005553/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com