对多个物体进行碰撞检测

2022-09-02 23:55:21

我主要专注于图形方面,以创建一些2DGame。我看过/看过几个教程,但没有一个是那么令人愉悦。我已经有一个玩家(一个正方形)在屏幕上移动并与其他方块碰撞。重力等也完成了。

如果屏幕上只有那么多物体(30 * 20),则一切正常。但是,如果我将其增加到300 * 300,程序开始运行非常慢,因为它必须检查这么多对象。

我真的不明白像Minecraft这样的游戏如何与所有这些块一起工作,我的程序已经放弃了300 * 300块。

我已经尝试过仅在对象可见时才检查碰撞,但这会导致程序检查每个对象的可见性,从而导致相同的问题。我做错了什么?帮助赞赏。

我将发布一些有关如何处理冲突的代码。

player.collision(player, wall);

public void collision(Tile object1, Tile[] object2){
    collisionCheckUp(object1, object2);
    collisionCheckDown(object1, object2);
    collisionCheckLeft(object1, object2);
    collisionCheckRight(object1, object2);  
}

public void collisionCheckDown(Tile object1, Tile[] object2){

    for (int i = 0; i < Map.tileAmount; i++){
        if(object2[i] != null && object2[i].visible)
        {
            if(object1.isCollidingDown(object2[i])){
                object1.collisionDown = true;
                return;
            }

        }
    }       
    object1.collisionDown = false;
}

public void compileHullDown(){

     collisionHull = new Rectangle((int)x+3, (int)y+3, width-6, height);
}

int wallCount = 0;
    for (int x=0;x<Map.WIDTH;x++) {
        for (int y=0;y<Map.HEIGHT;y++) {

            if (Map.data[x][y] == Map.BLOCKED) {
                wall[wallCount] = new Tile(x * Map.TILE_SIZE, y *  Map.TILE_SIZE);
                wallCount++;
            }
        }
    }

答案 1

优化碰撞检测的常用方法是使用空间分区对对象进行分类/管理。

该方法的一般思想是,您构建一个表示空间的树,并根据对象的位置将其放入该树中。计算碰撞时,将遍历树。这样,与使用蛮力方法相比,您执行的计算将少得多,因为您将忽略分支中除要遍历的对象之外的所有对象。Minecraft和类似的版本可能使用八叉星进行碰撞(也可能用于渲染)。

最常见的空间分区结构是BSP树kd树(一种特殊类型的BSP树)。更简单的方法是首先使用统一的空间分区 - 将空间分成轴对齐的一半。

我发现的关于碰撞的最好的资源是这本书。它应该澄清您关于该主题的所有问题。

那是如果你想把它做好的话。如果你想快速完成,你可以只对角色周围的颜色缓冲区进行采样,或者只在移动方向上采样,以确定障碍物是否靠近。


答案 2

正如Kostja所提到的,对空间进行分区对您很有用。但是,您将需要使用QuadTrees而不是Octrees,因为您只是在2D而不是3D中。这是一篇很好的文章,让你开始使用QuadTrees。


推荐