Skip to content

cfadmin-cn/lua-aoi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

lua-aoi

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

API Introduce

local aoi = require "lua-aoi"

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

0. Aoi new

function Aoi:new({ x = x or 65535, y = y or 65535, radius = radius or 100, }) end

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

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

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

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

1. Aoi Enter

---comment @Player Enter ---@param uid any @UID ---@param x integer @Y Position ---@param y integer @X Position ---@param fast boolean @don't care response. function Aoi:enter(uid, x, y, fast) return { uid1, uid2, uid3 } end

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

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

2. Aoi Move

---comment @Player Move ---@param uid any @UID ---@param x integer @Y Position ---@param y integer @X Position function Aoi:move(uid, x, y) return { uid1, uid2, uid3 } end

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

3. Aoi Leave

---comment @Player Leave ---@param uid any @UID function Aoi:leave(uid) return { uid1, uid2, uid3 } end

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

4. Aoi Around

---comment @Player Get all units around `uid` ---@param uid any @UID function Aoi:around(uid) return { uid1, uid2, uid3 } end

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

5. Aoi Aroundx

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

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

6. Aoi get_uid

---comment Get uid position. ---@param uid any @UID ---@return table @Position{ x = xxx, y = yyy } function Aoi:get_uid(uid) return { x = y, y = x } end

返回值为指定uidXY值.

7. Aoi Count

---comment Get all units amount. ---@return integer function Aoi:count() return the_number_of_units end

返回值内部单位总数

Test

local aoi = require "lua-aoi" local sys = require "sys" local now = sys.now -- 地图大小 local max_x, max_y = 5000, 5000 -- 地图内的人数 local max_humen = 1000 -- 指定半径范围 local radius = 100 local Amap = aoi:new { x = max_x, y = max_y, radius = radius, } for i = 1, max_humen do -- 指定人数进入到随机的位置 Amap:enter("user-" .. i, math.random(0, max_x), math.random(0, max_y), true) end -- 启动每隔0.5秒触发一次的周期定时器 require "cf".at(0.5, function () local ret = {} local uid = "user-" .. math.random(1, max_humen) local s = 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) local e = now() local position = 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

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages