Java:2D 世界碰撞检测代码错误

标签 java grid collision-detection tiles

这是我在同一区域遇到问题的第二款游戏... 第一个我什至不知道我是如何修复它的。坐标系也是 double 的。

这是物理类的“更新”代码,将由世界上的所有对象(玩家、敌人、元素)继承。 所有这些对象都必须能够遵守与世界的碰撞,因此......当它们具有 xSpeed 或 ySpeed 时,这部分代码将运行以应用并将对象“捕捉”到正确的空间(如果它碰到固体) (称为状态2)世界瓷砖。每个世界图 block 都是 20x20 像素。

问题: 它工作得很好,除了......

如果您捕捉到右侧的图 block ,则您无法向上或向下移动。 (尽管您可以向左移动,然后向上或向下移动)

如果您吸附到底部图 block ,则无法向左或向右移动。 (尽管您可以向上移动,然后向左或向右移动)

    if(xSpeed<0){
        try{
            int dest = hitbox.x + (int)(xSpeed/20*tick);
            if(Ids.tiles[world[dest/20][hitbox.y/20]].getState() == 2 || Ids.tiles[world[dest/20][(hitbox.y+hitbox.width)/20]].getState() == 2){
                hitbox.x = (int)Math.ceil(dest/20.)*20;
                xSpeed = 0;
            }else{
                hitbox.x += (int)(xSpeed/20*tick);
            }
        }catch(Exception e){
            hitbox.x += (int)(xSpeed/20*tick);
        }
    }else if(xSpeed>0){
        try{
            int dest = hitbox.x+hitbox.width+(int)(xSpeed/20*tick);
            if(Ids.tiles[world[dest/20][hitbox.y/20]].getState() == 2 || Ids.tiles[world[dest/20][(hitbox.y + hitbox.width)/20]].getState() == 2){
                hitbox.x = dest/20*20 - hitbox.width;
                xSpeed = 0;
            }else{
                hitbox.x += (int)(xSpeed/20*tick);
            }
        }catch(Exception e){
            hitbox.x += (int)(xSpeed/20*tick);
        }
    }

    if(ySpeed<0){
        try{
            int dest =  hitbox.y + (int)(ySpeed/20*tick);
            if(Ids.tiles[world[hitbox.x/20][dest/20]].getState() == 2 || Ids.tiles[world[(hitbox.x + hitbox.width)/20][dest/20]].getState() == 2){
                hitbox.y = (int)Math.ceil(dest/20.)*20;
                ySpeed = 0;
            }else{
                hitbox.y +=  (int)(ySpeed/20*tick);;
            }
        }catch(Exception e){
            hitbox.y +=  (int)(ySpeed/20*tick);;
        }
    }else if(ySpeed>0){
        try{
            int dest = hitbox.y + hitbox.height +  (int)(ySpeed/20*tick);
            if(Ids.tiles[world[hitbox.x/20][dest/20]].getState() == 2 || Ids.tiles[world[(hitbox.x + hitbox.width)/20][dest/20]].getState() == 2){
                hitbox.y = dest/20*20 - hitbox.height;
                ySpeed = 0;
            }else{
                hitbox.y +=  (int)(ySpeed/20*tick);;
            }
        }catch(Exception e){
            hitbox.y +=  (int)(ySpeed/20*tick);;
        }
    }

最佳答案

考虑右边缘(向右移动)碰撞时会发生什么。此条件通过:

Ids.tiles[world[dest/20][hitbox.y/20]].getState() == 2

假设 hitbox.width 为 5。那么一旦 hitbox.x 为 15,该函数就会返回 true。但是您随后重置了 hitbox.xdest/20*20 - hitbox.width,结果正好是它已经在的位置。然后,在垂直方向上,如果对象移动,那么它的最右边缘已经与图 block 碰撞,因此它无法移动。

要解决此问题,请在使用 Hitbox 查找网格位置时从其大小中减去 1 个像素 - 当然是在除法之前。

如果您使用浮点坐标,则可以使用 Math.ceil((hitbox.x + hitbox.width)/20.0) - 1 来产生类似的效果,而无需使用任意 e​​psilon。

关于Java:2D 世界碰撞检测代码错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9830263/

相关文章:

javascript - 在我的项目中使用 admin-on-rest

javascript - 我该如何改进这个 JavaScript 碰撞检测?

c++ - 处理质量 Spring 系统之间碰撞的好方法

java - Android 无法解析的日期异常

java - 如何将流式传输到 MediaPlayer 的音频缓存到磁盘中?

java - 使用mockito、ioC和 Autowiring 测试服务

java - Spring Boot 集成测试 - 不需要的模拟

css - 用于手机、平板电脑和桌面的 Bootstrap 网格布局

Extjs 3.4 checkchange 监听器不适用于 Checkcolumn

swift - 将 SKShapeNode 与 UIBezierpath 结合使用时不会进行碰撞检测