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

时间:2012-03-22 20:47:50

标签: java grid collision-detection tiles

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

这是物理类的“更新”代码,将由世界上所有对象(玩家,敌人,物品)继承。 所有这些对象必须能够服从与世界的碰撞,所以......当它们有xSpeed或ySpeed时,这部分代码将运行以应用并将对象“捕捉”到正确的空间中,如果它碰到一个实体(被称为国家2)世界瓷砖。每个世界区块为20x20像素。

问题: 它的工作原理非常好,除了......

如果您对齐右侧瓷砖,则无法向上或向下移动。 (尽管你可以向左移动,然后向上或向下移动)

如果您对齐底部图块,则无法向左或向右移动。 (虽然你可以向上移动然后向左或向右移动)

    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);;
        }
    }

1 个答案:

答案 0 :(得分:1)

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

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

假设hitbox.width为5.然后,只要hitbox.x为15,这将返回true。但是,然后您将hitbox.x重置为dest/20*20 - hitbox.width,这恰好是已经存在的地方。然后,在垂直方向上,如果物体移动,那么它的最右边缘已经与瓷砖碰撞,因此它不能移动。

要解决这个问题,当使用它来查找网格位置时,在点击框大小中减去1个像素 - 当然,在分割之前。

如果您使用的是浮点坐标,那么您可以使用Math.ceil((hitbox.x + hitbox.width)/20.0) - 1来产生类似的效果而不需要任意的epsilon。