我正在从头开始构建2D游戏用于教育目的。现在,角色应该在瓷砖上移动。例如,如果按下左箭头,我希望角色向左移动整个图块然后停止。在此期间,它应该忽略所有其他按键,包括向上,向下和向右。到目前为止,我用一个keyListener和一个TimerTask处理了这个问题,它会在时间结束后检查键是否仍然被按下,然后让角色停止移动。然而,我注意到,keyPressed事件不断被触发,产生越来越多的TimerTasks,最终导致输入反应延迟。当我按下按键时,这就是我所做的:
private void moveLeft() {
if (map.getNextTile("Left").isPassable()){
if (moving.equals("")){
moving = "Left";
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (keyStillPressed[0] == false) {
xSpeed = 0;
moving = "";
timer.cancel();
timer.purge();
} else {
if (map.getNextTile("Left").isPassable()){
xSpeed = 1;
map.movePlayerLeft();
} else {
xSpeed = 0;
moving = "";
timer.cancel();
timer.purge();
}
}
}
}, 0, 320);
}
}
setFacing("Left");
}
我首先检查下一个瓷砖是否是可通过的地形。如果是,我检查角色当前是否正在移动。如果不是,那么我启动计时器及其任务。 keyStillPressed是一个数组,告诉我,是否仍按下相应的键。说它仍然被按下,这是真的:我再次检查下一个瓷砖是否可以通过(有一些问题,按下按键允许我穿过墙壁,并修复它),如果是的话,我设置了速度为1,将地图向右移动(基本上是左边的角色)。
map.movePlayerLeft()让地图知道玩家当前所在的位置,以便在踩到某物时触发事件。如果下一个tile不可通过,则该字符停止,我重置移动到空String并取消定时器。由于每个图块都是32像素,而我每10毫秒移动1个像素,因此循环时间为320毫秒。
现在,我知道通过String处理播放器的状态并不是很酷。显然使用keyListener是废话,所以我决定使用keyBindings。遗憾的是,当角色正在悲伤地移动时,我的任务就是阻止所有的键输入。
使用计时器来侵入整个拼贴距离甚至是正确的吗?如何在角色移动期间让游戏不听所有其他键输入?
修改
好的,我没有说明问题。我按照childofsoong的建议修改了代码:
private void moveLeft() {
if (!occupied){
if (map.getNextTile("Left").isPassable()){
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!occupied) {
xSpeed = 1;
map.movePlayerLeft();
occupied = true;
} else {
xSpeed = 0;
occupied = false;
timer.cancel();
timer.purge();
}
}
}, 0, 320);
}
setFacing("Left");
}
}
这应该简化事情。我现在留下的问题是,如果我在向一个方向移动时开始按下不同的按钮,并保持按住,一旦我完成移动,我将开始移动之前有0.2到0.5秒的短暂延迟一个不同的方向。
我不想排队行动,我只是不希望延迟,我不明白它的来源。