【发布时间】:2015-12-11 08:39:34
【问题描述】:
我最近几天用 Java 编写了一个小型 2D 游戏。我只想使用普通的 Java SDK。到目前为止,一切都很好。我现在完成了,只有一个小问题: 我使用 Thread.sleep 方法来创建类似 gameloop/tick 的东西。由于我对面向对象编程不太熟悉,所以我不太确定我是否使用了正确的表达式,所以请忽略错误的表达式。
奇怪的是,如果我将等待时间(我称之为“Takt”)切换到 100 或以上,一切正常。我想把它改成50,但是一旦低于100,游戏就开始极度滞后(这个简单的乒乓球游戏所涉及的弹跳红球开始剧烈闪烁。
这是我的 Display 类的一段代码,它包括 paint();方法。如果您需要其他代码部分,请告诉我!请原谅我的变量名,我来自德国。代码如下:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
@SuppressWarnings("serial")
public class Output extends JFrame implements Runnable{
public static int W = 400;
public static int H = 700;
public static int Playerx;
public static int Playery = H-30;
public static int Punkte;
public static int Trash;
public static long Takt = 100;
public static boolean DrawGameOver;
public static boolean finished;
public static void main(String[] args) throws InterruptedException {
JOptionPane.showMessageDialog(null, "Das Spiel startet, sobald Sie auf OK drücken. Das Ziel ist es, möglichst viele Punkte zu erzielen.", "Ping-Pong-Solo", JOptionPane.NO_OPTION);
JOptionPane.showMessageDialog(null, "Mindstanforderungen: 1. Dual-Core Prozessor 2. Bildschirmauflösung mit mindestens 400*700p", "Systemanforderungen", JOptionPane.NO_OPTION);
Output Fenster = new Output();
Fenster.setSize(W, H);
Fenster.setResizable(false);
Fenster.setLocationRelativeTo(null);
Fenster.setVisible(true);
Fenster.setTitle("Ping Pong Release 1.0");
Fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Fenster.addKeyListener(new MyKeyListener());
new Physics();
new Thread(new Output()).start();
while(true){
if(DrawGameOver == false && finished){
Fenster.repaint();
}else{
GameOver();
}
try {
Thread.sleep(Takt);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!DrawGameOver){
Physics.Bewegung();
}
}
}
public static void GameOver(){
JOptionPane.showMessageDialog(null, "Sie erreichten "+Punkte+" Punkte. ", "Spiel beendet.", JOptionPane.NO_OPTION);
JOptionPane.showMessageDialog(null, "(c) Joel Krimmel", "Der Boss", JOptionPane.NO_OPTION);
System.exit(0);
}
public void paint(Graphics g){
finished = false;
g.setColor(Color.BLACK);
g.fillRect(0, 0, W, H);
g.setColor(Color.BLUE);
g.fillRect(Playerx, Playery, 100, 20);
g.setColor(Color.RED);
g.fillRoundRect(Physics.x, Physics.y, Physics.W, Physics.H, 500, 500);
g.setColor(Color.YELLOW);
g.drawString("Punkte: "+Punkte, W-100, 50);
finished = true;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
MyKeyListener.Verarbeitung();
}
}
}
【问题讨论】:
-
这样的问题很难回答。堆栈溢出规则规定您必须至少对问题有一个最低限度的了解。如果你能找到它滞后的原因,我们可以回答这个问题。
-
代码是脱节的,断章取义,你的绘画方法可能做错了什么可怕的错误,很难知道。考虑提供可运行的示例来演示您的问题。您也可以考虑使用 Swing Timer 而不是“while-lop”,但在我们看到更多信息之前,这只是一个猜测
-
为了证明这一点,您可以查看this example,这是一个简单的弹力球示例,this example 和this example 是关于渲染大量对象(如果不是 1000 则为 100 )...
-
另一方面,您将希望避免使用
KeyListener来支持键绑定API,这将解决与KeyListener相关的焦点问题。更多详情请见How to Use Key Bindings