Java:Pacman 与墙壁的碰撞检测

标签 java swing collision-detection game-physics custom-painting

我一直在尽力解决 Pacman 和墙壁之间的碰撞检测问题,但是我的实现似乎无法正常工作

  • 碰撞检测是否有效?是的
  • 它的行为正确吗?否
  • 目前表现如何?当你撞到墙时,吃 bean 人就会停下来 移动这没关系,但是按下任何新键来移动只会发生变化 图像轴(上、右、下或左,取决于按键), 撞墙后,它不会将吃 bean 人移动到当前位置之外。

任何帮助将不胜感激。提前致谢

GamePanel.java

package pacman;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable{
    private Thread animator;
    private boolean isRunning;  
    private Map map = new Map();


    public GamePanel(){
        this.setBackground(Color.BLACK);
        this.setDoubleBuffered(true);
        addKeyListener(new TAdapter());
        setFocusable(true);
    }

    @Override
    public void run() {
        isRunning = true;
        System.out.println("Is running? "+isRunning);
        long startTime, timeDiff, sleepTime; 
        startTime = System.currentTimeMillis();

        while(isRunning){
            repaint();
            gameUpdate();


             timeDiff = System.currentTimeMillis() -  startTime;
             sleepTime = 5 - timeDiff;

            try{
                Thread.sleep(sleepTime);
            }
            catch(InterruptedException ex){
                System.exit(0);
            }
            startTime = System.currentTimeMillis();

        }   
//      gameOver(); not implemented yet, will focus on this when I have some basic animation and the game loop working to satisfaction.
    }


    @Override
    public void addNotify(){
        super.addNotify();
        startGame();
    }

    public void startGame(){        
        if(animator == null || !isRunning){
            animator = new Thread(this);
            animator.start();           
        }
    } //end of StartGame method

    public void gameUpdate(){   
        map.getPlayer().move();     
        checkCollision();
    } //implementation of ingame updates such as pacman getting killed.


    public void checkCollision(){ //this is where I officially set collision up
        for(int i = 0; i < map.tiles.length; i++){
            for(int j = 0; j < map.tiles.length; j++){
                if(map.tiles[i][j] != null){
                    if(map.getPlayer().getPlayerBox().intersects(map.tiles[i][j].getR())){
                        map.getPlayer().setColliding(true);
                        System.out.println("OWW"+map.tiles[i][j].getR().getLocation());

                    }               
                }                           
            }               
        }
    }
    public void paintComponent(Graphics g){ 
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g);
        if(isRunning){
            drawDot(g2d);
            drawPlayer(g2d);
            map.drawMap(g2d);
        }

        Toolkit.getDefaultToolkit().sync();
        g.dispose();

    }   

    public void drawDot(Graphics2D g){
        g.setColor(Color.GREEN);
        for(int x= 0; x < 400; x++){
            for(int y = 0; y < 400; y++){
                g.drawRect(x * 20, y * 20, 1, 1);
            }
        }

    }




    public void drawPlayer(Graphics2D g){       
        g.drawImage(map.getPlayer().getImage(), map.getPlayer().getX(),map.getPlayer().getY(), this); 
    }

private class TAdapter extends KeyAdapter{      

        @Override
        public void keyPressed(KeyEvent e) {            
            map.getPlayer().keyPressed(e);  
        }
        @Override

        public void keyReleased(KeyEvent e) {
            map.getPlayer().keyReleased(e);
        }
    }
}

Player.java

package pacman;


import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;

public class Player extends Commons{
    private int dx, dy;
    private int speed = 1;
    private static int playerWidth = 52; //these figures seem off, but that is because the image is not designed correctly or the pacman image is not obeying the logic of not going passed the frame size.
    private static int playerHeight = 82;
    private Rectangle playerBox;
    private Image playerImg  = new ImageIcon(Player.class.getResource("Pacman.png")).getImage();
    private Image playerImgUp  = new ImageIcon(Player.class.getResource("PacmanUp.png")).getImage();
    private Image playerImgLeft  = new ImageIcon(Player.class.getResource("PacmanLeft.png")).getImage();
    private Image playerImgDown  = new ImageIcon(Player.class.getResource("PacmanDown.png")).getImage();

    private boolean isColliding = false;



    public Player(){
        this.setX(320);
        this.setY(280);
        playerBox = new Rectangle(this.getX(), this.getY(),40,40);
    }

    public void setSpeed(int sp){
        speed = sp;
    }

    public Image getImage(){
        if(dy == 1){            
            return playerImgDown;
        } 
        else if(dy == -1){
            return playerImgUp;
        }
        else if(dx == -1){
            return playerImgLeft;
        }
        else 
            return playerImg;       
    }//Responsible for displaying pacman image based on direction of pacman's movement.



    void move(){
        int x = this.getX();
        int y = this.getY();
        /*
         * This is the part where I am trying to implement some degree of logic to stop it from moving
         */
        if(isColliding == false){
            this.setX(x += dx);
            playerBox.setLocation(x, y);
            this.setY(y += dy);
        }else if(isColliding == true){
            this.setColliding(false);
            this.setX(this.getX());
            this.setY(this.getY());

        }

        if (this.getX() <= 1) {
            this.setX(1);
        }
        if (this.getX() >= 400 - playerWidth) {
            this.setX(400 - playerWidth);
        }
        if (this.getY() <= 2) {
            this.setY(2);
        }
        if (this.getY() >= 400 - playerHeight ) {
            this.setY(400 - playerHeight);
        }
    }//Most simplist form of collision detection, stops pacman from leaving the JFrame

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();


        if(key == KeyEvent.VK_LEFT ){
            dx = -speed;
            dy = 0;
        }
        if(key == KeyEvent.VK_RIGHT){
            dx = speed;
            dy = 0;
        }

        if(key == KeyEvent.VK_UP){
            dx = 0;
            dy = -speed;
        }
        if(key == KeyEvent.VK_DOWN){
            dx = 0;
            dy = speed;         
        }

        if(key == KeyEvent.VK_ESCAPE){
            System.exit(0);
        }   
    }



    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        if(key == KeyEvent.VK_LEFT){
            dy = 0;     
        }
        if(key == KeyEvent.VK_RIGHT){
            dy = 0;         
        }
        if(key == KeyEvent.VK_UP){
            dx = 0;         
        }
        if(key == KeyEvent.VK_DOWN){
            dx = 0;         
        }       
    }//end of key release



    public Rectangle getPlayerBox() {
        return playerBox;
    }




    public void setPlayerBox(Rectangle playerBox) {
        this.playerBox = playerBox;
    }


    public boolean isColliding() {
        return isColliding;
    }


    public void setColliding(boolean isColliding) {
        this.isColliding = isColliding;
    }


}// end of class

最佳答案

看起来发生的情况是玩家进入一个导致碰撞的图 block ,并且 isColliding 设置为 true。 游戏更新的下一次迭代将调用检查玩家的 isColliding boolean 值的运动代码。该条件成立,并且没有发生任何运动。接下来,检查碰撞,我们还没有移出导致碰撞的图 block ,因此我们被困在这个图 block 中。

我建议当碰撞发生时将玩家移出碰撞 block 。

我们知道玩家移动的方向,因此我们可以使用相反方向(将 dxdy 乘以 -1)来移动玩家脱离碰撞的方 block 。

关于Java:Pacman 与墙壁的碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59058721/

相关文章:

java - APDU读文件java卡程序

java - 是否可以有一个只允许基于键的值类型的映射?

java - 使用 SQL 数据库中的数据填充 JTable

java - 如何区分importData中的复制/移动

java - 如何创建一个可滚动的 Java Box?

java - 如何在 Windows 环境中写入安装在 'C:\Program Files' 中的 java 桌面应用程序的嵌入式 derby 数据库?

java - 将图像图标设置为特定单元格 jTable

python | Pygame | Sprite 碰撞

c# - 点-多边形滑动碰撞检测中如何防止浮点误差

ios - 旋转图像的碰撞检测