# 玩家系统实现 ## player_manager.lua ```lua local CONST = require 'config.const' local Balance = require 'config.balance' local M = {} -- { player_id -> { player, unit, profession, score, respawn_count, alive } } local player_data = {} ----------------------------------------------------------- -- 初始化所有玩家 ----------------------------------------------------------- function M.init_all_players() local players = y3.player_group.get_all_players() for _, player in ipairs(players) do M.create_player_unit(player) end end ----------------------------------------------------------- -- 为单个玩家创建单位 ----------------------------------------------------------- function M.create_player_unit(player) local spawn = M.get_random_spawn_point() local unit = y3.unit.create_unit(player, CONST.PLAYER_UNIT_KEY, spawn, math.random(0, 360)) -- 基础属性 local prof = player:storage_get('selected_profession') or 'shadow_blade' local hp = Balance.PROFESSION_HP[prof] or 100 unit:set_attr('最大生命', hp, '基础') unit:set_hp(hp) unit:set_bar_cnt(2) -- 物品栏2个格子 unit:set_pkg_cnt(0) -- 不使用背包栏 -- 初始伪装 local model = M.get_random_npc_model() unit:replace_model(model) -- 标签与存储 unit:add_tag('player_controlled') unit:storage_set('current_model', model) unit:storage_set('previous_model', model) unit:storage_set('suspicion', 0) unit:storage_set('profession', prof) unit:storage_set('idle_time', 0) unit:storage_set('kill_cd', 0) -- 赋予职业技能 local abi_key = CONST.PROFESSION_ABILITY[prof] unit:add_ability('英雄', abi_key, 0, 1) -- 记录 player_data[player:get_id()] = { player = player, unit = unit, profession = prof, score = 0, respawn_left = Balance.RESPAWN_COUNT, alive = true, } return unit end ----------------------------------------------------------- -- 玩家死亡处理 ----------------------------------------------------------- function M.on_player_killed(killer_unit, victim_unit) local victim_pd = M.get_data_by_unit(victim_unit) local killer_pd = M.get_data_by_unit(killer_unit) if not victim_pd then return end victim_pd.alive = false -- 积分 if killer_pd then killer_pd.score = killer_pd.score + Balance.SCORE_KILL_PLAYER end victim_pd.score = victim_pd.score + Balance.SCORE_DEATH -- 尸体标记 victim_unit:add_tag('corpse') victim_unit:set_recycle_on_remove(false) -- 复活判断 local mode = require('core.mode_manager') if mode.can_respawn(victim_pd) then victim_pd.respawn_left = victim_pd.respawn_left - 1 y3.timer.wait(Balance.RESPAWN_TIME, function() M.respawn(victim_pd) end) end -- 胜负检查 mode.check_victory() end ----------------------------------------------------------- -- 复活 ----------------------------------------------------------- function M.respawn(pd) local spawn = M.get_random_spawn_point() pd.unit:reborn(spawn) pd.unit:set_hp(pd.unit:get_attr('最大生命')) -- 新外观 local model = M.get_random_npc_model() pd.unit:replace_model(model) pd.unit:storage_set('current_model', model) pd.unit:storage_set('suspicion', 0) pd.alive = true end ----------------------------------------------------------- -- 积分操作 ----------------------------------------------------------- function M.add_score(player, delta) local pd = player_data[player:get_id()] if pd then pd.score = pd.score + delta end end ----------------------------------------------------------- -- 查询 ----------------------------------------------------------- function M.get_data_by_unit(unit) for _, pd in pairs(player_data) do if pd.unit == unit then return pd end end return nil end function M.get_all_player_units() local list = {} for _, pd in pairs(player_data) do table.insert(list, pd) end return list end function M.get_alive_count(camp) local n = 0 for _, pd in pairs(player_data) do if pd.alive then if not camp or pd.unit:get_camp_id() == camp then n = n + 1 end end end return n end function M.get_rankings() local list = M.get_all_player_units() table.sort(list, function(a, b) return a.score > b.score end) for i, pd in ipairs(list) do pd.rank = i end return list end ----------------------------------------------------------- -- 工具 ----------------------------------------------------------- function M.get_random_spawn_point() local spawns = y3.area.get_circle_areas_by_tag('player_spawn') local area = spawns[math.random(#spawns)] return area:get_center_point() end function M.get_random_npc_model() local pool = CONST.NPC_MODEL_POOL return pool[math.random(#pool)] end return M ``` --- ## 事件绑定(在 main.lua 中) ```lua -- 监听单位死亡 y3.game:event('游戏-初始化', function() y3.game:subscribe_event('单位-死亡', function(trg, data) local dead = data.dead_unit local killer = data.killer_unit if dead and dead:has_tag('player_controlled') then PlayerMgr.on_player_killed(killer, dead) end end) end) ``` --- ## 出生点配置 在Y3编辑器中: 1. 在地图上放置8个圆形区域 2. 每个区域添加标签 `player_spawn` 3. 代码通过 `Area.get_circle_areas_by_tag('player_spawn')` 获取