Java:Pacman与墙的碰撞检测

Java:Pacman与墙的碰撞检测,java,swing,collision-detection,game-physics,custom-painting,Java,Swing,Collision Detection,Game Physics,Custom Painting,我一直在努力解决Pacman和墙壁之间的碰撞检测问题,但是我的实现似乎没有正常工作 碰撞检测是否有效?对 它的行为正确吗?没有 目前情况如何?当你撞到墙上时,它会阻止吃豆人 从移动这是好的,但任何新的按键移动只会改变 图像轴(上、右、下或左,取决于按键), 撞击墙壁后,它不会将Pacman移动到其当前位置之外 如蒙协助,将不胜感激。提前谢谢 GamePanel.java package pacman; import java.awt.Color; import java.awt.Graph

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

  • 碰撞检测是否有效?对
  • 它的行为正确吗?没有
  • 目前情况如何?当你撞到墙上时,它会阻止吃豆人 从移动这是好的,但任何新的按键移动只会改变 图像轴(上、右、下或左,取决于按键), 撞击墙壁后,它不会将Pacman移动到其当前位置之外
如蒙协助,将不胜感激。提前谢谢

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);
        }
    }
}
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
packman;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.Rectangle;
导入java.awt.Toolkit;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入javax.swing.JPanel;
公共类GamePanel扩展JPanel实现可运行{
私有线程动画师;
私有布尔运算;
私有映射=新映射();
公共游戏小组(){
这个.背景(颜色.黑色);
此.setDoubleBuffered(true);
addKeyListener(新的TAdapter());
设置聚焦(真);
}
@凌驾
公开募捐{
isRunning=true;
System.out.println(“正在运行?”+isRunning);
长启动时间、时间差、睡眠时间;
startTime=System.currentTimeMillis();
同时(正在运行){
重新油漆();
gameUpdate();
timeDiff=System.currentTimeMillis()-startTime;
睡眠时间=5-时间差;
试一试{
睡眠(睡眠时间);
}
捕获(中断异常例外){
系统出口(0);
}
startTime=System.currentTimeMillis();
}   
//gameOver();尚未实现,当我有一些基本的动画和游戏循环工作到令人满意的程度时,我将重点关注这一点。
}
@凌驾
public void addNotify(){
super.addNotify();
startGame();
}
public void startName(){
如果(animator==null | |!正在运行){
animator=新线程(此);
animator.start();
}
}//startName方法的结尾
public void gameUpdate(){
map.getPlayer().move();
检查碰撞();
}//实施ingame更新,例如pacman被杀。
public void checkCollision(){//这是我正式设置碰撞的地方
对于(int i=0;i
Player.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);
        }
    }
}
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
packman;
导入java.awt.Image;
导入java.awt.Rectangle;
导入java.awt.event.KeyEvent;
导入javax.swing.ImageIcon;
公共类播放器扩展了Commons{
私有整数dx,dy;
私人整数速度=1;
private static int playerWidth=52;//这些数字似乎不正确,但这是因为图像设计不正确,或者pacman图像不符合不超过帧大小的逻辑。
专用静态int playerHeight=82;
专用矩形播放框;
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=新图像图标(Player.class.getResource(“PacmanLeft.png”)).getImage();
private Image playerImgDown=新图像图标(Player.class.getResource(“PacmanDown.png”)).getImage();
私有布尔值isColliding=false;
公共玩家(){
这是setX(320);
这是塞蒂(280);
playerBox=新矩形(this.getX(),this.getY(),40,40);
}
公共无效设置速度(int sp){
速度=sp;
}
公共映像getImage(){
如果(dy==1){
返回playerImgDown;
} 
else if(dy==-1){
返回playerImgUp;
}
else if(dx==-1){
返回playerImgLeft;
}
其他的
返回playerImg;
}//负责根据pacman的运动方向显示pacman图像。
无效移动(){
int x=this.getX();
int y=this.getY();
/*
*这是我试图实现某种程度的逻辑来阻止它移动的部分
*/
如果(isColliding==false){
这个.setX(x+=dx);
玩