Java 中的 Pacman 碰撞
Pacman Collisions in Java
我正在 Java 上制作吃豆人街机游戏,但我的碰撞有问题。
如果你看到我的头像
here 我的吃豆子精灵在到达一个角落或试图转回它来时的方向(即向左但不再向右)时静止不动(没有 x 或 y 移动)。我知道这是因为如果检测到碰撞,我将 xMovement 设置为 0,将 yMovement 设置为 0(请参阅 collide() 下的第二个代码块)。
如果我的 collision() 不允许这样做,我如何允许吃豆子精灵以其他方式移动(即它来自左侧,我希望它向右移动)或穿过一个角?
下面是我在 App.java class 中的绘制方法,它根据用户的输入绘制播放器。按键分别对应上、左、下、右。 this.direction 仅用于让玩家在发生碰撞时不会浪费移动或穿过墙壁。 *请注意,我放 (this.player.x_ord + 2) % 16 == 0
是因为我的 pacman 图片不是 16x16 图片,不像我的墙那样。
public void draw() { // This is an infinite loop
mapDraw(); // this draws my map constantly so I do not have multiple pacman sprites drawn
this.player.tick(); // see second code below for details
if (keyPressed){ // Used wasd rather than arrow keys
if (key == 's' && this.direction != 's' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){ // We dont want Player to turn ever on a non 16 divisible area
this.player.p = this.loadImage("src/main/resources/playerDown.png");
this.player.yMovement = this.player.speed;
this.player.xMovement = 0;
this.direction = 's';
}
else if (key == 'w' && this.direction != 'w' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){
this.player.p = this.loadImage("src/main/resources/playerUp.png");
this.player.yMovement = -this.player.speed;
this.player.xMovement = 0; // I do not want my pacman to move diagonally so thats why
this.direction = 'w';
}
else if (key == 'd' && this.direction != 'd' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){
this.player.p = this.loadImage("src/main/resources/playerRight.png");
this.player.xMovement = this.player.speed;
this.player.yMovement = 0;
this.direction = 'd';
}
else if (key == 'a' && this.direction != 'a' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){
this.player.p = this.loadImage("src/main/resources/playerLeft.png");
this.player.xMovement = -this.player.speed;
this.player.yMovement = 0;
this.direction = 'a';
}
}
this.player.draw(this); //see second code below for details
}
下面是我的player.javaclass
*再次注意 this.x_ord + 2 == w.x_pos + 16 && this.y_ord + 4 == w.y_pos
偏移是因为我的吃豆子精灵比我的 16x16 墙大。
public void tick(){
// //logic
this.detectCollision();
if (this.isLiving){
this.y_ord += this.yMovement;
this.x_ord += this.xMovement;
}
}
public void draw(PApplet a){ //just draw the sprite
if (this.isLiving){
a.image(this.p, this.x_ord, this.y_ord);
}
}
public void collide(boolean isX){ // Is it an x or y collision
if (isX == true){ // If it moves left or right into a wall
this.xMovement = 0;
}
else if (isX == false){ // If it moves up or down into a wall
this.xMovement = 0;
}
}
public void detectCollision(){
for (Walls w: this.wallLocations){ // A list of wall locations from a .txt file
if (this.x_ord + 2 == w.x_pos + 16 && this.y_ord + 4 == w.y_pos){ // Detect left movement into right wall piece
collide(true);
}
if (this.x_ord + 2 + 16 == w.x_pos && this.y_ord + 4 == w.y_pos){ // Detect right movement into left wall piece
collide(true);
}
if (this.y_ord + 4 == w.y_pos + 16 && this.x_ord + 2 == w.x_pos){ // Detect up movement into bottom wall piece
collide(false);
}
if (this.y_ord + 4 + 16 == w.y_pos && this.x_ord + 2 == w.x_pos){ // Detect down movement into top wall piece
collide(false);
}
}
非常感谢对我的问题的任何帮助。
我没有深入分析你的代码,但在我看来你的主要问题是 collide
方法只考虑了两种情况,垂直移动或水平移动。如果你想在 4 个不同的方向上移动,该方法需要有 4 个不同的状态。
为此,您可以创建一个代表方向的枚举。然后在 detectCollision
中将适当的 Direction
传递给 collide
。最后,在collide
考虑4个不同的方向。例如右边有障碍物,xMovement
需要non-positive。 collide
方法可能如下所示:
public void collide(Direction direction){
if (direction == Direction.RIGHT){
this.xMovement = Math.min(0, this.xMovement);
}
if (direction == Direction.LEFT){
this.xMovement = Math.max(0, this.xMovement);
}
if (direction == Direction.UP){
this.yMovement = Math.min(0, this.yMovement);
}
if (direction == Direction.DOWN){
this.yMovement = Math.max(0, this.yMovement);
}
}
我正在 Java 上制作吃豆人街机游戏,但我的碰撞有问题。 如果你看到我的头像 here 我的吃豆子精灵在到达一个角落或试图转回它来时的方向(即向左但不再向右)时静止不动(没有 x 或 y 移动)。我知道这是因为如果检测到碰撞,我将 xMovement 设置为 0,将 yMovement 设置为 0(请参阅 collide() 下的第二个代码块)。
如果我的 collision() 不允许这样做,我如何允许吃豆子精灵以其他方式移动(即它来自左侧,我希望它向右移动)或穿过一个角?
下面是我在 App.java class 中的绘制方法,它根据用户的输入绘制播放器。按键分别对应上、左、下、右。 this.direction 仅用于让玩家在发生碰撞时不会浪费移动或穿过墙壁。 *请注意,我放 (this.player.x_ord + 2) % 16 == 0
是因为我的 pacman 图片不是 16x16 图片,不像我的墙那样。
public void draw() { // This is an infinite loop
mapDraw(); // this draws my map constantly so I do not have multiple pacman sprites drawn
this.player.tick(); // see second code below for details
if (keyPressed){ // Used wasd rather than arrow keys
if (key == 's' && this.direction != 's' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){ // We dont want Player to turn ever on a non 16 divisible area
this.player.p = this.loadImage("src/main/resources/playerDown.png");
this.player.yMovement = this.player.speed;
this.player.xMovement = 0;
this.direction = 's';
}
else if (key == 'w' && this.direction != 'w' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){
this.player.p = this.loadImage("src/main/resources/playerUp.png");
this.player.yMovement = -this.player.speed;
this.player.xMovement = 0; // I do not want my pacman to move diagonally so thats why
this.direction = 'w';
}
else if (key == 'd' && this.direction != 'd' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){
this.player.p = this.loadImage("src/main/resources/playerRight.png");
this.player.xMovement = this.player.speed;
this.player.yMovement = 0;
this.direction = 'd';
}
else if (key == 'a' && this.direction != 'a' && (this.player.x_ord + 2) % 16 == 0 &&
(this.player.y_ord + 4) % 16 == 0){
this.player.p = this.loadImage("src/main/resources/playerLeft.png");
this.player.xMovement = -this.player.speed;
this.player.yMovement = 0;
this.direction = 'a';
}
}
this.player.draw(this); //see second code below for details
}
下面是我的player.javaclass
*再次注意 this.x_ord + 2 == w.x_pos + 16 && this.y_ord + 4 == w.y_pos
偏移是因为我的吃豆子精灵比我的 16x16 墙大。
public void tick(){
// //logic
this.detectCollision();
if (this.isLiving){
this.y_ord += this.yMovement;
this.x_ord += this.xMovement;
}
}
public void draw(PApplet a){ //just draw the sprite
if (this.isLiving){
a.image(this.p, this.x_ord, this.y_ord);
}
}
public void collide(boolean isX){ // Is it an x or y collision
if (isX == true){ // If it moves left or right into a wall
this.xMovement = 0;
}
else if (isX == false){ // If it moves up or down into a wall
this.xMovement = 0;
}
}
public void detectCollision(){
for (Walls w: this.wallLocations){ // A list of wall locations from a .txt file
if (this.x_ord + 2 == w.x_pos + 16 && this.y_ord + 4 == w.y_pos){ // Detect left movement into right wall piece
collide(true);
}
if (this.x_ord + 2 + 16 == w.x_pos && this.y_ord + 4 == w.y_pos){ // Detect right movement into left wall piece
collide(true);
}
if (this.y_ord + 4 == w.y_pos + 16 && this.x_ord + 2 == w.x_pos){ // Detect up movement into bottom wall piece
collide(false);
}
if (this.y_ord + 4 + 16 == w.y_pos && this.x_ord + 2 == w.x_pos){ // Detect down movement into top wall piece
collide(false);
}
}
非常感谢对我的问题的任何帮助。
我没有深入分析你的代码,但在我看来你的主要问题是 collide
方法只考虑了两种情况,垂直移动或水平移动。如果你想在 4 个不同的方向上移动,该方法需要有 4 个不同的状态。
为此,您可以创建一个代表方向的枚举。然后在 detectCollision
中将适当的 Direction
传递给 collide
。最后,在collide
考虑4个不同的方向。例如右边有障碍物,xMovement
需要non-positive。 collide
方法可能如下所示:
public void collide(Direction direction){
if (direction == Direction.RIGHT){
this.xMovement = Math.min(0, this.xMovement);
}
if (direction == Direction.LEFT){
this.xMovement = Math.max(0, this.xMovement);
}
if (direction == Direction.UP){
this.yMovement = Math.min(0, this.yMovement);
}
if (direction == Direction.DOWN){
this.yMovement = Math.max(0, this.yMovement);
}
}