基本上,我正在制作一款更新球员位置的游戏,它使用这个帖子:
@Override
public void run() {
while(true) {
System.out.println();
updatePos(x, y);
}
}
哪个工作正常,但如果我删除System.out.println(),它就会停止运行。我不知道为什么会这样,全班如下:
public class Player extends Block implements KeyListener, Runnable {
int x;
int y;
int speed;
boolean upPressed;
boolean downPressed;
boolean rightPressed;
boolean leftPressed;
static Sprite sprite = new Sprite("grass.png");
public Player(int x, int y, int speed) {
super(x, y, sprite);
this.x = x;
this.y = y;
this.speed = speed;
Thread playerThread = new Thread(this, "Player Thread");
playerThread.start();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
y -= speed;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN)
downPressed = true;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
rightPressed = true;
if (e.getKeyCode() == KeyEvent.VK_LEFT)
leftPressed = true;
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP)
upPressed = false;
if (e.getKeyCode() == KeyEvent.VK_DOWN)
downPressed = false;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
rightPressed = false;
if (e.getKeyCode() == KeyEvent.VK_LEFT)
leftPressed = false;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void run() {
while(true) {
System.out.println();
updatePos(x, y);
}
}}
最后注意事项:在布尔值upPress和downPressed中,我唯一关注的是:
if (e.getKeyCode() == KeyEvent.VK_UP) {
y -= speed;
}
答案 0 :(得分:7)
像
这样的循环while(true) {
updatePos(x, y);
}
会完全占用CPU。使用println
开始表现更好的原因可能是因为I / O每次迭代产生几百个周期。
我建议您根据所需的帧速率添加一个小的睡眠方法:
while (true) {
try {
Thread.sleep(10); // for 100 FPS
} catch (InterruptedException ignore) {
}
updatePos(x, y);
}
或更好的是,使用事件驱动的方法,例如java.util.Timer
。 (这将是Java惯用语。)
答案 1 :(得分:1)
不知道是否会解决它,但看起来你给JVM带来了困难...... 尝试在每次updatePos(x,y)调用之前添加一个短暂的睡眠(这是实现游戏线程的正确方法)。
@Override
public void run() {
while(true) {
Try
{
Thread.sleep(50);
}
catch (Exception e){}
updatePos(x, y);
}
}}
答案 2 :(得分:1)
您没有将代码发布到updatePos
。但至少,您需要制作该方法,以及keyPressed
(以及使用x
和/或y
)synchronized
的任何其他方法。
或者,您可以同时制作x
和y
volatile
,但x
和y
可以更新锁定。
但是没有任何内存同步,一个线程的更改不能保证可以从另一个线程中观察到。
答案 3 :(得分:0)
还有另一个方法。您可以使用专用于执行计划任务的类java.util.Timer。如果您现在需要2个线程定期执行某种不同的操作,那么它非常有用。使用Timer,您只需使用一个线程就可以节省您的工作和计算机资源
答案 4 :(得分:0)
在某些情况下,Thread.yield()
也可以做到。
例如,请参见https://www.javamex.com/tutorials/threads/yield.shtml。
但是,此链接的作者不建议使用yield
。