【问题标题】:Pacman Collisions in JavaJava 中的 Pacman 碰撞
【发布时间】:2020-11-09 08:49:58
【问题描述】:

我正在 Java 上制作 pacman 街机游戏,但我的碰撞有问题。 如果你看到我的图片 here 我的 pacman 精灵在拐角处或试图返回它来的方向(即向左但不再向右)时静止不动(没有 x 或 y 移动)。我理解这是因为如果检测到碰撞,我将 xMovement 设置为 0,将 yMovement 设置为 0(参见 collide() 下的第二个代码块)。

如果我的碰撞()不允许这样做,我将如何让吃豆子精灵向另一个方向移动(即它来自左侧,我希望它向右移动)或穿过一个角落?

下面是我在 App.java 类中的 draw 方法,它根据用户的输入来绘制玩家。键分别对应上、左、下、右。 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.java 类 *再次注意,this.x_ord + 2 == w.x_pos + 16 && this.y_ord + 4 == w.y_pos 被偏移,因为我的 pacman 精灵比我的 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);
        }
    }

非常感谢对我的问题的任何帮助。

【问题讨论】:

    标签: java object logic collision pacman


    【解决方案1】:

    我没有深入分析您的代码,但在我看来,您的主要问题是collide 方法仅考虑两种情况,垂直移动或水平移动。如果你想在 4 个不同的方向上移动,该方法需要有 4 个不同的状态。

    要实现这一点,您可以创建一个表示方向的枚举。然后在detectCollision 中将适当的Direction 传递给collide。最后,在collide 中考虑 4 个不同的方向。例如,如果右边有障碍,xMovement 需要为非正数。 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);
        }
    }
    

    【讨论】:

    • 优秀的解决方案!我在代码示例中对 Direction.UP 和 Direction.DOWN 进行了微调(因为 .UP 随 yMovement 减小而 .DOWN 随 yMovement 增大)进行了微调,并按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多