# 区域与地图系统 ## 区域标签规范 所有地图上的功能性区域通过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 ```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 ``` --- ## 视野阻挡区域 某些地图区域(如建筑内部、墙壁后方)可通过编辑器设置视野阻挡: ```lua -- 在编辑器中可配置,也可通过代码动态控制 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` 标记,怀疑值系统中检测玩家是否在暗区时给予减怀疑值加成。 ```lua -- 在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 |