Pacman java 移动问题

Posted

技术标签:

【中文标题】Pacman java 移动问题【英文标题】:Pacman java movement issues 【发布时间】:2015-03-31 05:46:14 【问题描述】:

我现在正在做的 pacman 运动遇到了一个小问题。

我似乎无法找到一种方法使该运动类似于起源的 pacman 运动。为了解释我希望它如何移动,我上传了这张图片。

就目前而言,我已经在黄色矩形和蓝色墙壁之间进行了碰撞。问题是当我如图所示向左移动并单击向上箭头时,它不应停止,而是继续移动,然后在有空闲空间时向上移动。

现在,如果您像这样单击向上箭头,黄色矩形将停止:

已上传包含我的动作的 pacman 类,以及检测到碰撞时我的板类中的代码。

pacman 类

public class Pacman 

private String pacmanup = "pacmanup.png";
private String pacmandown = "pacmandown.png";
private String pacmanleft = "pacmanleft.png";
private String pacmanright = "pacmanright.png";

private int dx;
private int dy;
private int x;
private int y;
private int width;
private int height;
private boolean visible;

private Image imageup;
private Image imagedown;
private Image imageleft;
private Image imageright;

public Pacman() 

    Thread thread = new Thread();

    thread.start();

    ImageIcon i1 = new ImageIcon(this.getClass().getResource(pacmanup));
    imageup = i1.getImage();

    ImageIcon i2 = new ImageIcon(this.getClass().getResource(pacmandown));
    imagedown = i2.getImage();

    ImageIcon i3 = new ImageIcon(this.getClass().getResource(pacmanleft));
    imageleft = i3.getImage();

    ImageIcon i4 = new ImageIcon(this.getClass().getResource(pacmanright));
    imageright = i4.getImage();

    width = imageup.getWidth(null);
    height = imageup.getHeight(null);
    visible = true;
    x = 27;
    y = 27;



public int getDx() 
    return dx;


public void setDx(int dx) 
    this.dx = dx;


public int getDy() 
    return dy;


public void setDy(int dy) 
    this.dy = dy;


public int getX() 
    return x;


public int getY() 
    return y;


public void setX(int x) 
    this.x = x;


public void setY(int y) 
    this.y = y;


public Image getImageup() 
    return imageup;


public Image getImagedown() 
    return imagedown;


public Image getImageleft() 
    return imageleft;


public Image getImageright() 
    return imageright;


public void setVisible(boolean visible) 
    this.visible = visible;


public boolean isVisible() 
    return visible;


public Rectangle getBounds() 
    return new Rectangle(x, y, width, height);


public Rectangle getOffsetBounds() 
    return new Rectangle(x + dx, y + dy, width, height);


public void move() 

    x += dx;
    y += dy;


public void keyPressed(KeyEvent e) 

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) 
        dx = -1;
        dy = 0;
    

    if (key == KeyEvent.VK_RIGHT) 
        dx = 1;
        dy = 0;
    

    if (key == KeyEvent.VK_UP) 
        dx = 0;
        dy = -1;
    

    if (key == KeyEvent.VK_DOWN) 
        dx = 0;
        dy = 1; 
    


public void keyReleased(KeyEvent e) 

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) 

    

    if (key == KeyEvent.VK_RIGHT) 

    

    if (key == KeyEvent.VK_UP) 

    

    if (key == KeyEvent.VK_DOWN) 

    



Board 类的代码

Rectangle r5 = pacman.getOffsetBounds();

    for (int j = 0; j<barriers.size(); j++) 
        Barrier b = (Barrier) barriers.get(j);
        Rectangle r4 = b.getBounds();

        if (r5.intersects(r4)) 

            pacman.setDx(0);
            pacman.setDy(0);
            break;

        

    

    pacman.move();


在我的棋盘类中创建了一个名为 direction 的字符串,用于检测黄色矩形的移动方向。

“左”“上”“右”或“下”

已经尝试过编写一些代码,但无法正常工作。这是我尝试过的:

      // moving to the left and tried go up
            else if (pacman.getDx() == 0 && pacman.getDy() == -1 && direction.equals("left")) 
                pacman.setDy(0);
                pacman.setDx(-1);
                break;

好吧,当它向左移动并且你点击向上时,它会继续向左移动,但它不会像它应该做的那样上升到可用空间:)

是keydapter / 按键的问题吗?也许当你点击时按下的键没有激活或什么?

【问题讨论】:

我会避免 KeyListener 支持键绑定。 How to Use Key Bindings。但是,我们检测到按键,您需要确定玩家可以朝那个方向移动,并且只在可以的情况下更新移动增量,如果不能,则保持增量不变 如果您添加一些逻辑来检查向上移动是否真的发生(碰撞 == false)而不是立即递减 dY,该怎么办? 【参考方案1】:

在我看来你有两个问题。

(问题 1)

如果您希望 pacman 继续移动,请不断更改 dx or dy 的值,直到按下另一个键。无论如何,经典的吃豆人就是这样工作的。它总是一直在移动/试图继续朝着最后一个keypressed 的方向移动。 (亲自在这里查看游戏机制 - https://www.google.com/doodles/30th-anniversary-of-pac-man)

(问题 2)

如果您不尝试实现经典 pacman(从您尝试执行的操作来看,您看起来不像是在实现经典 pacman),并且如果您想稍微改变控件的工作方式,就像根据按键历史智能切换方向,考虑存储按键。问题是您要跟踪多少个按键方向?

假设您只想跟踪两个按键,您需要有一个大小为 2 的 array,它在任何时候都只能存储两个 key:value 对。 key 将是 directionvalue 将是 如果你可以在那个方向上移动而不是(即 @987654326 @truefalse)。

您可以通过以下方式使用array 来解决您的问题:

按下方向键时,将其设置为array[0].key,并检查您是否可以朝该方向移动。如果可以,将array[0].value 的值设置为true 并使用该值查看是否需要通过检查array[0].keyarray[0].value 在另一个函数中更改dxdy 变量的值状态来决定你是否可以朝那个方向移动。实际move函数的细节将在后面解释。您已经实现了基本的move 方法,这很好,您只需要添加一些条件并稍作修改即可。

现在,当按下第二个键(如up key)时,请执行以下操作:

    设置temp = array[0] 设置array[0].key = 'up' 设置array[1].value = 检查是否可以朝array[0].key 的方向移动,如果可以设置为true,如果不能设置为false。 设置array[1] = temp并检查array[1].valuetrue还是false

请注意,您已将最早的按键操作移至 array[1],并将最新按键操作移至 array[0]

此时,设置一个约定,您将始终首先尝试向array[0] 的方向移动,因为它存储了最新按下的键的方向值,然后您才会尝试向array[1] 移动.

通过将array[0]array[1] 的布尔值设置为array[0].valuearray[1].value 来检查您是否可以向它们的方向移动后,您现在知道可以移动的位置并准备实际移动:

所以在你的移动方法中,执行以下操作,if(array[0].value==true) 然后:

    array[0] 的方向移动并忽略array[1](即在使用循环实现移动逻辑的情况下中断)

else if(array[1].value == true):

    array[1]的方向移动

    一旦您的 move() 函数返回,并且您处于新的 (x,y) 处,请返回第一步并重新开始。

希望您需要执行的步骤很明确。

【讨论】:

以上是关于Pacman java 移动问题的主要内容,如果未能解决你的问题,请参考以下文章

将 jLabel 移动到 jPanel 中的不同位置(类似 Pacman 的游戏)

yaourt: a pacman frontend(pacman前端,翻译)

不免费的PacMan

初学:什么是pacman以及pacman的使用方法

ArchLinux使用pacman安装软件时遇到的签名问题

修复 pacman 中的“未找到目标”(可能是 pacman.conf 的镜像列表