问题
I have faced a little problem with my pacman movement that i'm working on right now.
I can't seem to find a way to make the movement similar to the originated pacman movement. In order to explain how i want it to move, i have uploaded this picture.
As it stand now, i have made the collision working between the yellow rectangle and the blue walls. The problem is when i move to the left as in the picture and i click the up arrow, it should not stop, but continue to move and then go up when there is a free space.
Right now, the yellow rectangle will stop if you click on the up arrow like this:
Have uploaded my pacman class which contains my movement, and code from my board class when collision is detected.
pacman class
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) {
}
}
code from Board class
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();
}
Have made an String called direction inside my board class which detects what direction the yellow rectangle are moving.
"left" "up" "right" or "down"
Have already tried to write some code, but not working. Here is what i tried:
// 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;
Well, when it moves to the left and you click up, it will continue to move left, but it wont go up on the free space as it should do :)
Is it something with the keydapter / pressed key? maybe the pressed up key is not activated or something when u click up?
回答1:
The way I see it you have two issues here.
(Issue 1)
If you want pacman to keep moving, keep changing the dx or dy
values until another key is pressed. That's how the classic pacman worked anyway. It always kept moving/tried to keep moving in the direction of the last keypressed
. (See the game mechanic in action here yourself - https://www.google.com/doodles/30th-anniversary-of-pac-man)
(Issue 2)
If you're not trying to implement classic pacman (from what you're trying to do, it don't look like you're implementing classic pacman), and if you want to change the way the controls worked slightly, like intelligently switch direction based on history of key presses, consider storing the keypresses. The question is how many keypress directions do you want to track ?
Assuming you only want to track two keypresses, you'd need to have an array
of size two that will only store two key:value
pairs at any time. The key will be direction and value will be if you can move in that direction of not (i.e boolean
true
or false
).
Here is how you could use this array
to solve your problem:
When a direction key is pressed set it into the array[0].key
and check if you can move in that direction. if you can, set the value of array[0].value
to true
and use this value to see if you need to change the value of dx
or dy
variable in another function by checking the array[0].key
and array[0].value
state to decide if you can move in that direction or not. Details of the actual move
function will be explained later. You already have basic the move
method implemented, so that's good, you'll just need to add some conditions and modify it a bit.
Now, when second key (like up key
) is pressed do the following:
- set
temp = array[0]
- set
array[0].key = 'up'
- set
array[1].value
= check if you can move in the direction ofarray[0].key
and set true if you can set false if you cannot. - set
array[1] = temp
and check ifarray[1].value
istrue
orfalse
Notice that, you have moved the oldest keypressed action to array[1]
and latest keypressed to array[0]
.
At this point, set a convention that you'll always try to move in the direction of array[0]
first because it stores direction value of the latest key pressed, and only then you'll try to move in array[1]
.
After checking if you can move in direction of array[0]
and array[1]
by setting their boolean values to array[0].value
and array[1].value
, you now know where you can move and are ready to move actually:
So in your move method, do the following, if(array[0].value==true)
then:
- Move in the direction of
array[0]
and ignorearray[1]
(i.e break in case you implement the move logic using a loop)
else if(array[1].value == true)
:
Move in the direction of
array[1]
Once your
move()
function returns, and you're at the new (x,y) go back to step one and do it all over again.
Hope the steps you'll need to implement are clear.
来源:https://stackoverflow.com/questions/28258111/pacman-java-movement-issues