2013-11-17 3 views
0

пытается кодировать java pacman.i использовать bufferedimage для хранения лабиринта. Чтобы проверить столкновение pacman со стенами, я использовал 2d int array, значение 0 означает пустое пространство & pacman может перемещаться по нему, 1 объект wall.pacman должен перемещаться по 1 квадрату за один раз при нажатии клавиши, останавливаться на keyrelease. Но pacman не двигается правильно, он иногда перемещается по квадрату стены, иногда он перемещается, а затем полностью останавливается, даже когда он находится в пустом квадрате. не знаю, где я ошибаюсь. Я использовал классы ниже. Пожалуйста, помогите кому-нибудь.java pacman wall collision не работает правильно

public class Map extends JPanel implements Runnable{ 

private int TILE_W=15; //divide map into 15x15 tiles 
private int TILE_H=20; //there will be 20 tiles along width and 15 along height,total of 300 tiles 

private Image tile; // 15x15 png image 

private BufferedImage img; //stores maze image 

private long DELAY=50; 

private Pacman pacman; 

private int[][] mapdata={{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 
         {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, 
         {1,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1}, 
         {1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1}, 
         {1,0,0,1,0,0,1,0,1,0,1,0,1,1,1,1,1,1,0,1}, 
         {1,0,0,1,1,1,1,0,1,0,1,0,1,0,0,0,0,1,0,1}, 
         {1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1}, 
         {1,0,0,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,0,1}, 
         {1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1}, 
         {1,0,0,1,0,0,1,0,1,0,1,0,1,1,1,1,1,1,0,1}, 
         {1,0,0,1,0,0,1,0,1,0,1,0,1,0,0,0,0,1,0,1}, 
         {1,0,0,1,0,0,1,0,1,0,1,0,1,0,0,0,0,1,0,1}, 
         {1,0,0,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,0,1}, 
         {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1}, 
         {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} 
         }; 

public Map(){ 
    ImageIcon ict=new ImageIcon(this.getClass().getResource("tile.png")); 
    tile=ict.getImage(); 
    addKeyListener(new KbListener()); 
    setFocusable(true); 
    setDoubleBuffered(true); 
    pacman=new Pacman(mapdata); 
    img=new BufferedImage(350,350,BufferedImage.TYPE_INT_ARGB); 
    Graphics2D g2D=(Graphics2D) img.getGraphics(); 
    for(int x=0;x<TILE_W;x++) 
    for(int y=0;y<TILE_H;y++){ 
      if(mapdata[x][y]==1) 
       g2D.drawImage(tile,y*15,x*15,this); 
    } 
    Thread t=new Thread(this); 
    t.start(); 
} 

@Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    Graphics2D g2D=(Graphics2D) g; 
    g2D.drawImage(img,0,0,this); 
    g2D.drawImage(pacman.getImage(),pacman.getX(),pacman.getY(),this); 
    Toolkit.getDefaultToolkit().sync(); 
    g.dispose(); 
} 

public void run() { 
    // TODO Auto-generated method stub 
    while(true){ 
    repaint(); 
    pacman.move(); 
    try { 
     Thread.sleep(DELAY); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    } 
} 

private class KbListener extends KeyAdapter{ 
    public void keyReleased(KeyEvent e){ 
     pacman.keyReleased(e); 
    } 

    public void keyPressed(KeyEvent e){ 
     pacman.keyPressed(e); 
    } 
} 

} 


public class Pacman { 
private Image pacman; 
private int x,y; 
private int dx,dy; 

private int[][] mapdata; 
private int mapx,mapy; 

public Pacman(int[][] mapdata){ 
    ImageIcon icp=new ImageIcon(this.getClass().getResource("pacman.png")); 
    pacman=icp.getImage(); 
    x=30; 
    y=15; 
    dx=0; 
    dy=0; 
    mapx=2; 
    mapy=1; 
    this.mapdata=mapdata; 
} 

public void move(){ 
    x+=dx; 
    y+=dy; 
} 

public Image getImage(){ 
    return pacman; 
} 

public int getX(){ 
    return x; 
} 

public int getY(){ 
    return y; 
} 

public void keyPressed(KeyEvent e){ 
    int k=e.getKeyCode(); 
    if(k==KeyEvent.VK_LEFT){ 
     mapx=(x-15)/15; 
     if(mapdata[mapx][mapy]==1) 
      dx=0; 
     else dx=-15; 
    } 
    if(k==KeyEvent.VK_RIGHT){ 
     mapx=(x+15)/15; 
     if(mapdata[mapx][mapy]==1) 
      dx=0; 
     else dx=15; 
    } 
    if(k==KeyEvent.VK_UP){ 
     mapy=(y-15)/15; 
     if(mapdata[mapx][mapy]==1) 
      dy=0; 
     else dy=-15; 
    } 
    if(k==KeyEvent.VK_DOWN){ 
     mapy=(y+15)/15; 
     if(mapdata[mapx][mapy]==1) 
      dy=0; 
     else dy=15; 
    } 
} 

public void keyReleased(KeyEvent e){ 
    int k=e.getKeyCode(); 
    if(k==KeyEvent.VK_LEFT) 
     dx=0; 
    if(k==KeyEvent.VK_RIGHT) 
     dx=0; 
    if(k==KeyEvent.VK_UP) 
     dy=0; 
    if(k==KeyEvent.VK_DOWN) 
     dy=0; 
} 
} 
+2

1) Для лучшей помощи раньше, отправьте сообщение [SSCCE] (http://sscce.org/). 2) В вашем «вопросе» нет «?». У вас есть вопрос, если да, что это? 3) Для Swing обычно используют привязки клавиш на основе AWT на нижнем уровне, 'KeyListener'. Подробнее о том, как их использовать, см. [Как использовать привязки клавиш] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html). 4) См. [Этот ответ] (http://stackoverflow.com/a/14575043/418556) для одной формы обнаружения столкновений, которая работает. –

ответ

0

Посмотрите на ваших переменных здесь:

if(k==KeyEvent.VK_LEFT){ 
    mapx=(x-15)/15; 
    if(mapdata[mapx][mapy]==1) 
     dx=0; 
    else dx=-15; 
} 

Где вы сбрасываете mapx и mapy между событиями? Я не вижу, чтобы ты это делал. Итак, что происходит с mapx и mapy между последующими событиями? Например, если вы переместитесь налево и нажмите на стену, затем двигайтесь вверх, ваш mapx теперь все еще застрял в стене.

Не используйте поля, потому что вы не используете их нигде. Просто сделайте переменные в методе. У вас есть аналогичная потенциальная проблема с dx и dy, где они только сбрасываются до 0 , если вы попадаете в стену перед сменой направлений.

int mapx = x/15; 
int mapy = y/15; 

if (k == KeyEvent.VK_LEFT) { 
    mapx--; 

    if (mapx < 0 || 
      mapdata[mapx][mapy] == 1) 
     dx = 0; 
    else dx =- 15; 

    dy = 0; 

} else if (k == KeyEvent.VK_RIGHT) { 
    mapx++; 

    if (mapx > mapdata.length - 1 || 
      mapdata[mapx][mapy] == 1) 
     dx = 0; 
    else dx = 15; 

    dy = 0; 

} else if (k == KeyEvent.VK_UP) { 
    mapy--; 

    if (mapy < 0 || 
      mapdata[mapx][mapy] == 1) 
     dy = 0; 
    else dy =- 15; 

    dx = 0; 

} else if (k == KeyEvent.VK_DOWN) { 
    mapy++; 

    if (mapy > mapdata[mapx].length - 1 || 
      mapdata[mapx][mapy] == 1) 
     dy = 0; 
    else dy = 15; 

    dx = 0; 
} 
+0

thanks.it работает лучше, но pacman все же иногда перемещается по стенам, когда я держу ключ непрерывно. Есть ли способ предотвратить это? Это что-то связано с тем, что paint() вызывается до того, как скорость pacman установлена ​​в 0? – thiru

+0

Это может быть одновременная проблема. Попробуйте объявить поля в Pacman нестабильными. – Radiodef