首页 > 解决方案 > 快速查找数组中的对象

问题描述

对于碰撞检测游戏,我正在考虑将环境中的对象拆分为不同的块,以将需要检查的对象数量减少到仅位于相同(和相邻)块中的对象。然而,我的一些对象(子弹)将快速穿过不同的块,因此我需要快速将这些对象从一个数组移动到另一个数组。

我正在考虑使用字典而不是数组,这样我就可以使用唯一键作为索引来快速找到子弹并移动它,但我决定看看这里是否有人可能知道更好的方法?

我计划在我的游戏中拥有几千个对象(包括子弹),对象本身将只是圆形和矩形,子弹被表示为线段。

标签: lua

解决方案


我假设“块”是指游戏世界中的不同区域,它们或多或少地彼此独立运行以减少开销。如果我对此有误,请纠正我。

至于“块”之间的子弹轨迹问题,我建议记录子弹的原点——即它被发射的点——以及它与物体碰撞的点。这可以通过某种依赖于游戏世界坐标系的碰撞检测来实现,无论发生什么。我建议创建一个Bullet类。这是我提出的一个快速概念验证,可以作为模块加载require

local Bullet = {__type = "Bullet"}

-- This function could take bullet information as parameters, such as its point of origin
-- and calibre.
function Bullet.new(start_pos_in, calibre_in)
    -- Record start and ending positions in this table, probably represented by some 
    -- (x, y) coordinate pairs, assuming your game is 2D. I just used a generic 
    -- placeholder here called 'Point'.
    local self = {
        calibre = calbibre_in,
        start_pos = start_pos_in
        end_pos = Point.new(0, 0)
    }
    local mt = {
        __metatable = "metatable",
        __newindex = function(t, k, v)
            local e = string.format("type Bullet has no member '%s'", k)
            return error(e, 2)
        end,
        __index = self
    }
    return setmetatable(self, mt)
end

return Bullet

使用我上面的示例,Bullet可以像这样实例化一个对象:

-- Using .50 calibre as an example.
-- 'x' and 'y' represent the bullet's point of origin in the game world.
local bullet = Bullet.new(Point.new(x, y), ".50")

一旦Bullet物体与游戏世界中的某物发生碰撞,您可以使用内部变量记录其撞击点end_pos,计算其行进距离等。根据您的“块”系统的工作方式,您也可以记录子弹的“块”来源。

顺便说一句,我建议尝试为子弹粒子实现对象池以节省开销。(有兴趣的可以参考这篇文章。)


推荐阅读