Skip to content

Latest commit

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

lua-aoi

基于cfadmin实现的纯Lua版九宫格Aoi算法.

API Introduce

localaoi=require"lua-aoi"

导入后必须先使用Aoi类来创建一个实例.

0. Aoi new

functionAoi:new({
x=xor65535,
y=yor65535,
radius=radiusor100,
})
end

x - X轴的最大值, 起始值为0, 默认值为65535.

y - Y轴的最大值, 起始值为0, 默认值为65535.

radius - 指定半径大小, 默认值为100.

使用Aoi类创建实例, 创建后的实例可用于下面的操作.

1. Aoi Enter

---comment @Player Enter---@paramuidany @UID---@paramxinteger @Y Position---@paramyinteger @X Position---@paramfastboolean @don't care response.functionAoi:enter(uid, x, y, fast) return { uid1, uid2, uid3 } end

返回值为进入后, 需要通知的单位数组.

如果指定fasttrue, 那么将不会有返回值.

2. Aoi Move

---comment @Player Move---@paramuidany @UID---@paramxinteger @Y Position---@paramyinteger @X PositionfunctionAoi:move(uid, x, y) return { uid1, uid2, uid3 } end

返回值为移动后, 需要通知的单位数组.

3. Aoi Leave

---comment @Player Leave---@paramuidany @UIDfunctionAoi:leave(uid) return { uid1, uid2, uid3 } end

返回值为离开后, 需要通知的单位数组.

4. Aoi Around

---comment @Player Get all units around `uid`---@paramuidany @UIDfunctionAoi:around(uid) return { uid1, uid2, uid3 } end

返回值为指定uid周围需要通知的单位数组.

5. Aoi Aroundx

---comment @Player Get all units around `X` and `Y` position---@paramxinteger @Y Position---@paramyinteger @X PositionfunctionAoi:aroundx(x, y) return { uid1, uid2, uid3 } end

返回值为指定XY位置周围需要通知的单位数组.

6. Aoi get_uid

---comment Get uid position.---@paramuidany @UID---@returntable @Position{ x = xxx, y = yyy }functionAoi:get_uid(uid) return { x=y, y=x } end

返回值为指定uidXY值.

7. Aoi Count

---comment Get all units amount.---@returnintegerfunctionAoi:count() returnthe_number_of_unitsend

返回值内部单位总数

Test

localaoi=require"lua-aoi"localsys=require"sys"localnow=sys.now-- 地图大小localmax_x, max_y=5000, 5000-- 地图内的人数localmax_humen=1000-- 指定半径范围localradius=100localAmap=aoi:new {
x=max_x,
y=max_y,
radius=radius,
}
fori=1, max_humendo-- 指定人数进入到随机的位置Amap:enter("user-" ..i, math.random(0, max_x), math.random(0, max_y), true)
end-- 启动每隔0.5秒触发一次的周期定时器require"cf".at(0.5, function ()
localret= {}
localuid="user-" ..math.random(1, max_humen)
locals=now()
-- -- 玩家移动后需要通知的人-- ret = Amap:move(uid, x, y)-- -- 玩家离开后需要通知的人-- ret = Amap:leave(uid)-- -- 根据指定UID, 获取其周边有多少人-- ret = Amap:around(uid)-- -- 根据指定位置, 获取周边有多少人-- local x, y = math.random(0, max_x), math.random(0, max_y)-- ret = Amap:aroundx(x, y)locale=now()
localposition=Amap:get_uid(uid)
print(string.format("uid为: %s(%d, %d), 数量为: %d, 耗时为: %.4f秒", uid, position.x, position.y, #ret, e-s))
end)

Advice

  • uidunique ID的缩写, 是用来代指Aoi结构内部唯一ID而不是User ID.
  • 支持integer/string类型的uid值, 但建议自行构造成: player::pidnpc::nidcreep::cid等.
  • 数组下标查表是非常高效的, 所以一般是不会有性能问题的. 但请尽可能将聚集度设计的更松散, 避免大量单位聚集在格子内.
  • 可自行根据示例代码测试不同大小、范围、人数等等情况下的效率.

About

Lua grid AOI algorithm.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages