简体   繁体   English

Java更高效的数组搜索

[英]Java more efficient array searching

I am coding a game using LibGdx and I have an array with all of my wall objects that the player can collide with. 我正在使用LibGdx对游戏进行编码,我有一个数组,其中包含玩家可以碰撞的所有墙对象。 For those who don't use LibGdx, I am talking about LibGdx's Array class which provides the same functionality as an ArrayList but it's built with memory efficiency in mind. 对于那些不使用LibGdx的人,我说的是LibGdx的Array类,它提供了与ArrayList相同的功能,但它的构建考虑了内存效率。 When I check for collision, I am having to go through every wall in the array and check for collision like this: 当我检查碰撞时,我不得不穿过阵列中的每个墙并检查碰撞,如下所示:

for(Wall  w : walls) {
    if(w.bounds().contains(player.bounds()) {
    // handle collision
    }
}

I realized this was inefficient because I am going through every wall even if that wall is off the current view of the map. 我意识到这是低效的,因为即使那堵墙离开了地图的当前视图,我也会穿过每一面墙。 Obviously, if I am checking for collision with walls currently in the camera's viewport (this means they are currently visible by the player) then there is no point in going through the whole array because the player can't collide with them until they come into view. 显然,如果我正在检查相机视口中当前墙壁的碰撞(这意味着玩家当前可以看到它们),那么通过整个阵列是没有意义的,因为玩家在进入之前不能与它们发生碰撞视图。 I was thinking of making my game a bit more efficient by only checking for collision with walls close to the player. 我只想通过检查与玩家附近墙壁的碰撞来让我的游戏更有效率。 In my game, I have all of the walls snapped onto a grid with cells 32x32 px. 在我的游戏中,我将所有墙壁都卡在一个网格上,单元格为32x32像素。 I really don't know how I could create more efficient searching for collision. 我真的不知道如何创建更有效的碰撞搜索。 Could I use like a map of some sort which uses a vector2 position for its key and then look up the player's position and look through walls within a certain range from the player's position in the map? 我可以使用某种类型的地图,它使用vector2位置作为其键,然后查看玩家的位置并在玩家在地图中的位置的某个范围内查看墙壁吗? I am just really lost on how to have code that won't go through all 100+ walls in my game when there are only 10 current possible walls that the player could touch because of where it currently is. 我真的迷失了如何在我的游戏中拥有不会通过所有100多个墙壁的代码,因为当前只有10个当前可能的墙壁可以触摸玩家。 Does this make any sense? 这有道理吗? Could someone explain a good way to do something like this? 有人可以解释这样做的好方法吗? Thanks so much. 非常感谢。

There are lots of collision alghoritms out there, you will need to find one that suits your need. 那里有很多碰撞的alghoritms,你需要找到一个适合你需要的。

One solution I can think of on the top of my head is: 我能想到的一个解决方案是:
Keep your wall list sorted on their coordinates. 保持您的墙列表在其坐标上排序。 If you create a new wall, use insertion sort to resort your array. 如果您创建了一个新墙,请使用插入排序来求助您的数组。 When you want to check for collisions, take the objects coordinates (in this case probably the player that is running) and do a binary search to find the closest wall to the player. 当你想检查碰撞时,取对象坐标(在这种情况下可能是正在运行的玩家)并进行二分查找以找到最接近玩家的墙。 Then calculate if the player and this wall collides. 然后计算玩家和这堵墙是否发生碰撞。 If the closest wall isn't causing a collision, you can be pretty confident that no other wall is as well. 如果最近的墙没有造成碰撞,你可以非常自信没有其他墙也是如此。

Each wall is on one or more of these 32x32px grids. 每个墙都在这些32x32px网格中的一个或多个上。 Let the coordinates of a grid be x and y. 设栅格的坐标为x和y。 If a grid contains a wall, enter this into a 如果网格包含墙,请将其输入a

HashMap<CoordPair,Set<Wall>> xy2wall

To investigate where a location is in contact with a nearby wall, use the coordinates of the location to determine a small set of grid coordinates, fetch the set or sets of Walls mapped by these CoordPairs. 要调查位置与附近墙壁的接触位置,请使用位置坐标确定一小组网格坐标,获取由这些CoordPairs映射的一组或多组墙。 I guess the Player.bounds() can provide a suitable set of coordinates. 我猜Player.bounds()可以提供一组合适的坐标。

If the 32x32 grid results in too many entries, you can always use a coarser grid. 如果32x32网格导致过多条目,则始终可以使用较粗糙的网格。

I once came into the same realization that you have while developing a top down rpg. 在开发自上而下的RPG时,我曾经有过相同的认识。 There are more walls than you can imagine in a top down rpg. 在自上而下的RPG中,墙壁比你想象的要多。

Here is how I solved it: 这是我解决它的方式:

First: Segment the map into zones ie.) draw your map on paper or something and cut it up into parts. 第一:将地图划分为区域,即。)在纸上或其他东西上绘制地图并将其切割成部分。

Second: Record the pixel boundaries for each segmented section of the map. 第二:记录地图的每个分段部分的像素边界。

Third: Check where your players location is with respect to the boundaries. 第三:检查球员位置相对于边界的位置。

Finally: Only check the walls within those boundaries. 最后:只检查这些边界内的墙壁。

In a realm of infinite walls this is not any more efficient (speaking about Big O) but for all practical purposes this is effective in cutting down on lookup times 在无限墙的领域,这不是更有效(谈论大O)但是出于所有实际目的,这在减少查找时间方面是有效的


if (boundary1.contains(player1)) {

    for(Wall  w : Boundary1Walls) {
        if(w.bounds().contains(player.bounds()) {
            // handle collision
        }
    }
}
else if (boundary2.contains(player1)) {

    for (Wall  w : Boundary2Walls) {
        if(w.bounds().contains(player.bounds()) {
            // handle collision
        }
    }
}

.... Continue in this fashion ......继续以这种方式

Take note... I did it like this before going to college for software development, so I did not make use of data structures such as BST which could be used to store walls with respect to their coordinates. 请注意......我在上大学进行软件开发之前是这样做的,所以我没有使用BST这样的数据结构,可以用来存储与坐标相关的墙。 Making your lookup time extremely fast. 使您的查询时间非常快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM