我正在使用基于Atari游戏冒险的java游戏。我得到了基本的KeyListener部分工作正常,但后来我添加了另一个if语句,使用另一个类来测试玩家是否要撞墙,如果是这样的话就停止移动。我使用的方法也使用if语句,当我运行代码时,它有MAJOR滞后。我先尝试了一个while循环,但这使得它更加滞后。无论如何要让这不是那么多滞后?看起来运行程序看起来并不复杂,我仍然需要添加另一个if语句才能进入另一个房间,所以我必须做一些事情来大规模减少延迟。
这是班级:
class Player extends JPanel implements KeyListener{
private char c = 'e';
int x = 400;
int y = 400;
int mapX = 0;
int mapY = 0;
public Player() {
this.setPreferredSize(new Dimension(800, 500));
addKeyListener(this);
}
public void addNotify() {
super.addNotify();
requestFocus();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Environment Layout = new Environment();
Layout.drawRoom(mapX,mapY,g);
g.fillRect(x , y , 20, 20);
}
public void keyPressed(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) {
c = e.getKeyChar();
repaint();
Environment Layout = new Environment();
if(Layout.isWall(x,y,c)){}
else{
if (c == 'a'){
x = x - 3;
}
else if (c == 'w'){
y = y - 3;
}
else if (c == 's'){
y = y + 3;
}
else if (c == 'd'){
x = x + 3;
}
}
}
public static void main(String[] s) throws IOException{
JFrame f = new JFrame();
f.getContentPane().add(new Player());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
我在这里使用的抽奖室方法只是为了把房间的背景放到位。
以下是Environment类的isWall方法:
public boolean isWall(int moveX, int moveY, char let){
BufferedImage room = null;
try {
room = ImageIO.read(new File(xNum + "," + yNum + ".png"));
}
catch (IOException e) {
}
int[][] walls = convertImage(room);
boolean blocked = false;
if(let == 'w') {
if(walls[moveY-8][moveX] == -3584){blocked = true;}
}
else if(let == 's') {
if(walls[moveY+20][moveX] == -3584){blocked = true;}
}
else if(let == 'a') {
if(walls[moveY][moveX-5] == -3584){blocked = true;}
}
else if(let == 'd') {
if(walls[moveY][moveX+20] == -3584){blocked = true;}
}
return blocked;
}
convertImage方法只是将房间的图像转换为int数组,用于颜色的值。 -3584是墙壁的颜色。可能这就是它的落后之处,但这似乎是每个房间自动完成墙壁的最佳方式。
我也试过一个计时器,但要么我做错了,要么就是没有帮助。
如果需要,我可以提供更多代码,但是对此的帮助将非常感激。我对这种东西比较陌生,所以很可能我错过了一些大事。感谢。
答案 0 :(得分:4)
这里的滞后几乎肯定不是来自if
陈述。那些真的很快。我认为更大的问题出在isWall
。请注意,只要您想检查墙是否存在,就
与查看内存中的值相比,从磁盘读取文件非常慢。例如,常规磁性硬盘驱动器的工作频率约为7200 RPM,因此寻道时间以毫秒为单位。另一方面,您的处理器每秒可以执行大约10亿次操作,因此其他操作需要几纳秒。这意味着,与其他操作相比,磁盘读取的速度大约是百万分之一,这几乎可以肯定您将从中获得延迟!
要解决此问题,请考虑重写您的isWall
代码,以便只读取文件并进行一次转换,然后执行此操作,然后只需查找所需图像部分即可。这会将大量(冰冷)文件读取转换为单个(缓慢但不可避免)文件读取,然后进行大量快速内存读取。
答案 1 :(得分:0)
你似乎比移动玩家更进一步移动墙壁。
通过制作" blocked = true&#34>,你的玩家对象是否可能卡在墙上?连续?
你的角色在每个方向上都会得到+ - 3,但是你的墙壁似乎不一致,范围从8到20到5到左到右20。
答案 2 :(得分:0)
这是对@ templatetypedef的回答的扩展。
除了在调用isWall方法时加载图像文件,您可能还需要考虑在游戏开始时缓存所有墙。
所以我在想;
<String, Integer>
键控的HashMap数据结构。 String是你的坐标。例如。坐标字符串=&#34; 100,238&#34; 这应该会大大减少I / O磁盘争用。
将来,如果您希望扩展解决方案以合并诸如isTreasureChest()或isMonster()之类的API。它可以通过构建一个不可变的类调用来扩展&#34; Room
&#34;或&#34; Tile
&#34;代表对象。然后修改HashMap以接收<String, Room>
。