我现在正在做的步行者运动遇到了一个小问题。
我似乎找不到一种方法来使运动类似于起源的帕克曼运动。为了解释我希望它如何移动,我上传了这张照片。
就目前而言,我已经在黄色矩形和蓝色墙壁之间进行了碰撞。问题是,当我像图中一样向左移动并单击向上箭头时,它不应该停止,而是继续移动,然后在有空闲空间时向上移动。
现在,如果您单击向上箭头,黄色矩形将停止,如下所示:
上传了我的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();
}
在我的板类中创建了一个名为方向的字符串,它检测黄色矩形的移动方向。
"左"上"右"还是"下"
已经尝试编写一些代码,但不起作用。这是我尝试的:
// 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;
好吧,当它向左移动,你点击向上,它会继续向左移动,但它不会像它应该做的那样在空闲空间上向上移动:)
这是什么与按键/按下键?可能是按下键未激活或当你点击了什么?
在我看来,你有两个问题。
(问题1)
如果你想让帕克曼继续移动,请不断更改dx或dy
值,直到按下另一个键。无论如何,这就是经典帕克曼的工作方式。它总是继续移动/试图继续朝着最后一个按键
的方向移动。(请参阅此处的游戏机制-https://www.google.com/doodles/30th-anniversary-of-pac-man)
(问题2)
如果您没有尝试实现经典的Pacman(从您尝试做的事情来看,它看起来不像是在实现经典的Pacman),并且如果您想稍微改变控件的工作方式,例如根据按键历史智能切换方向,请考虑存储按键。问题是您想跟踪多少个按键方向?
假设你只想跟踪两个按键,你需要一个大小为2的数组
,它在任何时候都只能存储两个键:value
对。如果你可以朝着not的方向移动,键将是方向,值将是方向(即boolean
true
或false
)。
以下是如何使用这个数组
来解决您的问题:
当按下方向键时,将其设置为数组[0]. key
并检查您是否可以朝该方向移动。如果可以,将数组[0].value
的值设置为true
并使用该值查看是否需要通过检查数组[0].key
和数组[0].value
状态来更改另一个函数中dx
或dy
变量的值,以决定是否可以朝该方向移动。实际的移动
函数的详细信息将在后面解释。您已经实现了基本的mobile
方法,所以这很好,您只需要添加一些条件并对其进行一些修改。
现在,当按下第二个键(如up键
)时,执行以下操作:
temp=数组[0]
数组[0]. key='up'
组[1]. value
=检查您是否可以向数组[0].key
的方向移动,如果不能设置false,则设置true。数组[1]=temp
并检查数组[1]. value
是true
还是false
请注意,您已将最旧的按键操作移动到数组[1]
,并将最新的按键移动到数组[0]
。
此时,设置一个约定,您将始终尝试首先向数组[0]
的方向移动,因为它存储最新按下的键的方向值,然后您将尝试在数组[1]
中移动。
通过将它们的布尔值设置为数组[0]. value
和数组[1].value
,检查是否可以向数组[0]
和数组[1].value
的方向移动后,您现在知道可以移动的位置并准备好实际移动:
所以在你的移动方法中,执行以下操作,if(组[0]. value==true)
然后:
数组[0]
的方向移动并忽略数组[1]
(即在使用循环实现移动逻辑时中断)else if(数组[1]. value==true)
:
>
向数组[1]
的方向移动
一旦您的mobile()
函数返回,并且您处于新的(x, y),请返回第一步并重新执行。
希望您需要实施的步骤是明确的。