1

我现在正在研究的 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;

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

是键适配器/按下的键吗?当您单击向上时,也许按下的键未激活或其他什么?

4

1 回答 1

0

在我看来,您在这里有两个问题。

(问题一)

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

(问题 2)

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

假设您只想跟踪两个按键,您需要一个大小为 2 的按键,它在任何时候array都只能存储两对按键。关键方向key:value价值你是否可以朝那个方向移动(即或)。boolean truefalse

以下是如何使用它array来解决您的问题:

当按下方向键时,将其设置为array[0].key并检查您是否可以朝该方向移动。如果可以,设置 to 的值array[0].valuetrue使用该值来查看是否需要通过检查and状态来更改另一个函数中的值dxor变量,以确定您是否可以朝那个方向移动。稍后将解释实际功能的细节。您已经实现了基本的方法,这很好,您只需要添加一些条件并对其进行一些修改。dyarray[0].keyarray[0].valuemovemove

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

  1. temp = array[0]
  2. array[0].key = 'up'
  3. set array[1].value= 检查您是否可以朝 方向移动,如果可以,则array[0].key设置为 true,如果不能,则设置为 false。
  4. 设置array[1] = temp并检查array[1].valuetruefalse

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

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

在检查你是否可以通过将它们的布尔值设置为array[0]and的方向移动之后,你现在知道你可以移动到哪里并且准备好实际移动了:array[1]array[0].valuearray[1].value

因此,在您的 move 方法中,请执行以下操作if(array[0].value==true)

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

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

  1. 向着的方向移动array[1]

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

希望您需要实施的步骤是明确的。

于 2015-02-01T02:24:31.477 回答