edit | blame | history | raw

区域与地图系统

区域标签规范

所有地图上的功能性区域通过Y3编辑器中的Area+标签实现。代码使用 Area.get_*_areas_by_tag() 获取。

标签 形状 说明 参数(KV)
player_spawn 圆形 玩家出生点
npc_spawn 圆形 NPC出生区域
hide_spot 圆形(R=2) 藏尸点 capacity:int
item_spawn 圆形(R=1) 物品刷新点
interact_bench 圆形(R=1.5) 长椅互动点
interact_board 圆形(R=1.5) 告示栏互动点
interact_well 圆形(R=1.5) 水井互动点
interact_vendor 圆形(R=2) 摊位互动点
smoke_zone 圆形 烟雾弹动态创建
checkpoint 圆形(R=3) VIP模式检查点 order:int
exit_point 圆形(R=3) VIP撤离点
fake_vip_spawn 圆形 假VIP出生点
play_zone 圆形 当前可游玩区域(缩圈)

缩圈系统 — circle.lua

local CONST   = require 'config.const'
local Balance = require 'config.balance'

local M = {}

local current_area   = nil
local current_radius = nil
local shrink_timer   = nil
local damage_timer   = nil

-----------------------------------------------------------
-- 启动
-----------------------------------------------------------
function M.start()
    -- 初始为全地图
    current_area   = y3.area.get_map_area()
    current_radius = Balance.CIRCLE_INIT_RADIUS

    -- 创建圈区域
    local center = current_area:get_center_point()
    current_area = y3.area.create_circle_area(center, current_radius)
    current_area:add_tag('play_zone')

    -- 第一次缩圈在3分钟后
    y3.timer.wait(Balance.CIRCLE_FIRST_SHRINK, function()
        M.shrink()
    end)
end

-----------------------------------------------------------
-- 缩圈
-----------------------------------------------------------
function M.shrink()
    if not current_area then return end

    local new_radius = current_radius * Balance.CIRCLE_SHRINK_RATIO
    if new_radius < Balance.CIRCLE_MIN_RADIUS then
        new_radius = Balance.CIRCLE_MIN_RADIUS
    end

    -- 动画式缩小(每秒减一点)
    local delta = current_radius - new_radius
    local steps = math.ceil(delta / 0.5)

    shrink_timer = y3.timer.count_loop(1.0, steps, function(timer, count)
        current_radius = current_radius - 0.5
        if current_radius < new_radius then
            current_radius = new_radius
        end
        current_area:set_radius(current_radius)
    end)

    -- 启动区域外伤害
    M.start_damage()

    -- 下次缩圈
    y3.timer.wait(Balance.CIRCLE_INTERVAL, function()
        M.shrink()
    end)
end

-----------------------------------------------------------
-- 区域外持续伤害
-----------------------------------------------------------
function M.start_damage()
    if damage_timer then return end

    damage_timer = y3.timer.loop(2.0, function()
        local PlayerMgr = require 'core.player_manager'
        for _, pd in ipairs(PlayerMgr.get_all_player_units()) do
            if pd.alive then
                local pos = pd.unit:get_point()
                if not current_area:is_point_in_area(pos) then
                    pd.unit:add_hp(-Balance.CIRCLE_DAMAGE_PER_TICK)
                end
            end
        end
    end, '圈外伤害')
end

-----------------------------------------------------------
-- 停止
-----------------------------------------------------------
function M.stop()
    if shrink_timer then shrink_timer:remove() end
    if damage_timer then damage_timer:remove() end
    if current_area then current_area:remove() end
end

return M

视野阻挡区域

某些地图区域(如建筑内部、墙壁后方)可通过编辑器设置视野阻挡:

-- 在编辑器中可配置,也可通过代码动态控制
local wall_area = y3.area.get_rectangle_by_res_id(WALL_AREA_ID)
wall_area:edit_area_fov_block(1, true)  -- 添加视野阻挡

光照区域

不同区域可以有不同光照,影响"看清"其他玩家的距离:

区域类型 光照 识别距离
亮区(灯下、广场) 明亮 正常
暗区(小巷、角落) 昏暗 减半
室内 中等 -20%

实现方式:通过区域标签 light_dark / light_indoor 标记,怀疑值系统中检测玩家是否在暗区时给予减怀疑值加成。

-- 在suspicion.lua的update中增加
local dark_areas = y3.area.get_circle_areas_by_tag('light_dark')
local in_dark = false
for _, da in ipairs(dark_areas) do
    if da:is_point_in_area(unit:get_point()) then
        in_dark = true
        break
    end
end
if in_dark then
    delta = delta - 1  -- 在暗区额外减少怀疑值
end

路径(Road)系统

NPC行走路径在编辑器中通过Road工具绘制。

路径类型 标签约定 分配给
主街道环线 road_main_loop civilian, patrol
支线小巷 road_alley_* civilian
巡逻路线 road_patrol_* patrol
广场路线 road_square civilian, wanderer
VIP撤离路线 road_vip_escape_* fake_vip