范围技能要不要命中目标、拾取点够不够近、怪物攻击有没有够到——碰撞判定无处不在。圆形碰撞是游戏世界的标准模型,粗筛与精判的两段式判定让千人同屏的碰撞计算的成本可控。
---粗筛:距离平方比较,免开方
local function broadPhase(ax, ay, bx, by, range)
local dx = ax - bx
local dy = ay - by
return dx * dx + dy * dy <= range * range
end
---精判:技能扇形的角度校验
local function narrowPhase(actor, tx, ty, face, arc)
local dx = tx - actor.x
local dy = ty - actor.y
local ang = math.deg(math.atan2(dy, dx))
local diff = math.abs((ang - face + 180) % 360 - 180)
return diff <= arc / 2
end
---烈火剑法的判定:2 格扇形 90 度
function Combat.fireSwordHit(actor, target)
if not broadPhase(actor.x, actor.y, target.x, target.y, 2) then
return false
end
return narrowPhase(actor, target.x, target.y,
actor:GetFacing(), 90)
end
粗筛用距离平方比较:不开方,一次乘法两次减法完成圆的包含判定,性能是开方版本的数倍。粗筛不过的直接淘汰,粗筛过了的进精判——扇形技能在圆的包含之外再校验角度差,角度的归一化处理让 359 度与 1 度的差值算成 2 度而不是 358 度。烈火剑法的 2 格 90 度扇形在两段式下:粗筛淘汰八成的远处目标,精判只处理视野内的一小撮。
---群体技能的批量判定:先桶后筛
function Combat.aoeHit(actor, cx, cy, radius, arc)
local hits = {}
local candidates = Grid.queryCircle(cx, cy, radius)
for _, t in ipairs(candidates) do
if broadPhase(cx, cy, t.x, t.y, radius)
and narrowPhase(actor, t.x, t.y,
actor:GetFacing(), arc) then
hits[#hits + 1] = t
if #hits >= 12 then break end -- 单次上限
end
end
return hits
end
群体技能的判定在 AOI 桶上做:先取圆形区域的候选集(格子级粗筛),再逐个做圆与扇形的精判,单次命中上限 12 个封顶结算成本。判定顺序的纪律:廉价的先做(平方距离)、昂贵的后做(角度与开方)、有上限的截断在循环内。命中数的上限与飘字的密度联动,千个目标的群体技能不产生千条飘字——判定的成本与表现的成本一起管。
判定的单测覆盖边界:恰好在半径上、扇形边缘角、归一化的跨零角度;单次技能的判定耗时抽样,超 2 毫秒即回查候选集的规模。
角度差曾经没归一化,背对目标的玩家吃到了正面技能,跨零的取模修正。粗筛曾经用了开方的距离比较,千人群技的判定耗时翻三倍,平方比较回归。候选集曾经取全图玩家列表,AOI 桶的接入让候选集缩到视野级。
技能的形状参数(半径、扇角、上限)进技能表,判定逻辑不感知数值。判定的日志带粗筛与精判的漏斗计数,性能的分布一目了然。碰撞的参数与客户端的表现半径同源,视觉与判定的一致从数据层保证。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 沃玛祭坛是沃玛森林深处的隐藏玩法:玩家投放指定祭品积累召唤进度,进度满格召唤出沃玛教主之影,全服玩家都可…
实战应用:用在哪里 全服入侵事件最大的问题是玩家总是在事后才知道。魔军压境前哨把预警做成玩法的一部分:入侵前三哨塔依次亮起,…
实战应用:用在哪里 坐骑不喂会饿、喂饱了跑得快,饱食度是坐骑系统的核心状态。坐骑喂养接口管理饱食度的增减与加成联动:饱食度一…
实战应用:用在哪里 宠物合成要消耗材料与金币,分解返还多少材料,玩家在操作前就该知道。宠物合成分解页把合成消耗、分解返还、成…
实战应用:用在哪里 角色数据与订单数据曾共用一套备份,订单回滚时把角色也卷了回去,玩家充了钱角色却回到三天前。异库备份把角色…
实战应用:用在哪里 师门成员平日各忙各的,同门之间几乎零交流。师门切磋周把门内切磋变成积分赛:一周内师门成员互相发起切磋,胜…