Java 如何确保玩家不会穿过墙

Java 如何确保玩家不会穿过墙,java,swing,collision-detection,collision,windowbuilder,Java,Swing,Collision Detection,Collision,Windowbuilder,我正在编写我的第一个2D游戏(吃豆人)。我认为比赛看起来不错,但我有一个大问题——碰撞。对象仍然在穿墙。我被它困住了,所以我决定向有丰富经验的真正程序员寻求帮助。(当然我做了一些研究,但我不想做复制和粘贴之类的事情,因为我不明白)。正如我所说的,游戏就要结束了,我所需要做的就是阻止吃豆人通过。例如,我画了一个大的白色矩形作为平台。我希望有人能帮助我。在整个项目中,我学到了很多,我理解碰撞,但不知道如何正确编程。我想我很快就能找到答案了,但有些东西不见了 注:我在WindowBuilder中创建了

我正在编写我的第一个2D游戏(吃豆人)。我认为比赛看起来不错,但我有一个大问题——碰撞。对象仍然在穿墙。我被它困住了,所以我决定向有丰富经验的真正程序员寻求帮助。(当然我做了一些研究,但我不想做复制和粘贴之类的事情,因为我不明白)。正如我所说的,游戏就要结束了,我所需要做的就是阻止吃豆人通过。例如,我画了一个大的白色矩形作为平台。我希望有人能帮助我。在整个项目中,我学到了很多,我理解碰撞,但不知道如何正确编程。我想我很快就能找到答案了,但有些东西不见了

注:我在WindowBuilder中创建了window,因此编译可能会有问题:(


在代码中更新x和y,但在始终位于其初始位置的“packman”对象中没有这样做;因此,当您检查与墙的交点时,packman始终位于(170,50);我更改了动画方法以反映packman和paint方法中的更改,以便使用更新的packman坐标

动画:

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub
    if (count == 1) {
        packman.x = packman.x - xVel;
        repaint();
        zkontrolujKolizi();
        
    
    }
    
    if (count ==2) {
        packman.y = packman.y - yVel;
        repaint();
        zkontrolujKolizi();
    }
    if (count ==3) {
        packman.x = packman.x + xVel;
        repaint();
        zkontrolujKolizi();
    }
    if (count ==4) {
        packman.y  = packman.y+yVel; 
        repaint();
        zkontrolujKolizi();
    }
    
    
}
油漆:

@Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        g.drawRect(packman.x,packman.y,packman.width,packman.height);
        g.setColor(Color.blue);
        g.fillRect(packman.x,packman.y,packman.width,packman.height);
        
        g.drawRect(platform.x,platform.y,platform.width,platform.height);
        g.setColor(Color.blue);
        
        g.drawRect(secondPlat.x,secondPlat.y,secondPlat.width,secondPlat.height);
        g.setColor(Color.blue);
        
    }
当然,代码中还有很多东西需要重构,但这就是为什么没有检测到冲突的原因

要避免穿过墙移动,请计算新位置,检查碰撞,如果为真,请回滚位置更改:

@Override
public void actionPerformed(ActionEvent arg0) {
    int rollbackX=packman.x;
    int rollbackY=packman.y;

    switch (count) {
    case 1:
        packman.x = packman.x - xVel;
        break;
    case 2:
        packman.y = packman.y - yVel;
        break;
    case 3:
        packman.x = packman.x + xVel;
        break;
    case 4:
        packman.y  = packman.y+yVel;
        break;
    }

    //Collision found, rollback
    if (zkontrolujKolizi()) {
        packman.x=rollbackX;
        packman.y=rollbackY;
    } else {        
        repaint();
    }
}

public boolean zkontrolujKolizi() {
    return packman.intersects(platform) || packman.intersects(secondPlat);
}
我使用了完全相同的方法,但仅限于移动对象

 @Override
        public void actionPerformed(ActionEvent e) {
            //This is my actually code I've implemented from your answer
            int rollbackX = packRect.x;
            int rollbackY = packRect.y;
    
        switch (count) {
        case 1:
            packman.setCoordinatesX(packman.getCoordinatesX() - xVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.x = packRect.x - xVel;
            collectPoint();
    //      repaint();
            break;
    
        case 2:
            packman.setCoordinatesY(packman.getCoordinatesY() - yVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.y = packRect.y - yVel;
            sbirejBody();
    //      repaint();
            break;
        case 3:
            packman.setCoordinatesX(packman.getCoordinatesX() + xVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.x = packRect.x + xVel;
            collectPoint();
    //      repaint();
            break;
        case 4:
            packman.setCoordinatesY(packman.getCoordinatesY() + yVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.y  = packRect.y+yVel; 
            collectPoint();
        //  repaint();
            break;
        }
        
      

  int originX = packRect.x;
int originY = packRect.y;
packRect.setLocation(originX, originY); 
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
if (checkCollision) {
    rollbackX= originX;
    rollbackY = originY;
    
}else {
    repaint();
}
 packRect.setLocation(originX, originY); 
    packman.setCoordinatesX(originX);
    packman.setCoordinatesY(originY);
    gifLabel.setLocation(originX, originY);
}

public boolean checkCollision() {
    return packman.intersects(platform) || packman.intersects(secondPlat);
}

代码没有编译,因为缺少一些类,但我很奇怪,在实际移动对象之前检查碰撞。通常应该在“动画”代码中进行检查(缺少这些类,因此我无法检查)@Rocco我得到建议,我应该发布理解我的问题的最低代码,所以我没有添加像ghost或packman这样的简单类。我添加了moving animation,我理解,但请更好地检查MRE是什么:,它必须是最小的,但是完整的;这意味着你必须从头开始,创建一个复制问题的新项目。如果你只需删除部分以减小大小,它就不会编译,而且仅通过目视检查很难发现问题(更不用说许多人甚至不会在这种情况下尝试)。@Rocco好的,我用更少的代码创建了新项目。我的问题是,矩形,,,Pacman“即使我使用了intersect方法,我也能通过吗?我希望我能通过。好吧,但我不是在画组件,或者是吗?我有点困惑?我从来没有用过PAINTCOMPONENT来画画。看起来很好,碰撞被检测到了,但如何不让对象通过呢?我应该使用getHeight()和Width()吗?”方法,比如当我不想离开屏幕时。如果你知道我的意思:D@PeteJerk为了避免穿墙移动,计算新位置,检查碰撞,如果为真,回滚位置更改,最后查看新代码。好的,它可以工作,谢谢。我为pacman在我的项目中实现了它,有碰撞的一切都可以工作,但是在碰撞后我还有一个问题吗?我不知道你是否读过我的answer@PeteJerk如果是关于绘画,最好打开一个新的问题,而不是修改这个问题等等,现在你的打包工不再是rect,所以你必须恢复在列之前更改的所有对象上以前的坐标lision check.@Rocco类似的东西?我编辑了我的问题
 @Override
        public void actionPerformed(ActionEvent e) {
            //This is my actually code I've implemented from your answer
            int rollbackX = packRect.x;
            int rollbackY = packRect.y;
    
        switch (count) {
        case 1:
            packman.setCoordinatesX(packman.getCoordinatesX() - xVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.x = packRect.x - xVel;
            collectPoint();
    //      repaint();
            break;
    
        case 2:
            packman.setCoordinatesY(packman.getCoordinatesY() - yVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.y = packRect.y - yVel;
            sbirejBody();
    //      repaint();
            break;
        case 3:
            packman.setCoordinatesX(packman.getCoordinatesX() + xVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.x = packRect.x + xVel;
            collectPoint();
    //      repaint();
            break;
        case 4:
            packman.setCoordinatesY(packman.getCoordinatesY() + yVel);
            gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
            packRect.y  = packRect.y+yVel; 
            collectPoint();
        //  repaint();
            break;
        }
        
      

  int originX = packRect.x;
int originY = packRect.y;
packRect.setLocation(originX, originY); 
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
if (checkCollision) {
    rollbackX= originX;
    rollbackY = originY;
    
}else {
    repaint();
}
 packRect.setLocation(originX, originY); 
    packman.setCoordinatesX(originX);
    packman.setCoordinatesY(originY);
    gifLabel.setLocation(originX, originY);
}

public boolean checkCollision() {
    return packman.intersects(platform) || packman.intersects(secondPlat);
}