xLua游戏开发框架实战指南

管理员
## 一、框架架构设计 ### 整体分层架构 ``` ┌─────────────────────────────────────────┐ 游戏业务层(Lua) - 游戏逻辑/UI/数据配置 ├─────────────────────────────────────────┤ Lua框架层(Lua) - 模块管理/事件系统/MVC框架 ├─────────────────────────────────────────┤ 桥接层(C# + Lua) - 类型转换/函数调用/数据同步 ├─────────────────────────────────────────┤ 基础服务层(C#) - 网络通信/资源管理/对象池/配置加载 ├─────────────────────────────────────────┤ Unity引擎层 └─────────────────────────────────────────┘ ``` ## 二、环境搭建与初始化 ### 1. xLua环境管理器 ```csharp // LuaManager.cs - 核心Lua环境管理 using UnityEngine; using XLua; public class LuaManager : MonoSingleton { private LuaEnv luaEnv; private LuaTable luaFramework; private bool initialized = false; private void Awake() { DontDestroyOnLoad(gameObject); } public void Initialize() { if (initialized) return; // 创建Lua环境 luaEnv = new LuaEnv(); // 设置Lua路径 SetupLuaPath(); // 加载核心框架脚本 LoadFrameworkScripts(); // 初始化Lua框架 InitializeLuaFramework(); // 启动垃圾回收 StartGCCoroutine(); initialized = true; Debug.Log("xLua环境初始化完成"); } private void SetupLuaPath() { // 设置Lua脚本搜索路径 string luaPath = Application.dataPath + "/LuaScripts/?.lua;"; luaPath += Application.dataPath + "/LuaScripts/?/init.lua;"; // 支持热更新路径 if (Application.isMobilePlatform || Application.isConsolePlatform) { luaPath += Application.persistentDataPath + "/LuaScripts/?.lua;"; luaPath += Application.persistentDataPath + "/LuaScripts/?/init.lua;"; } luaEnv.AddLoader((ref string filepath) => { string scriptPath = filepath.Replace('.', '/'); string fullPath = Application.dataPath + "/LuaScripts/" + scriptPath + ".lua"; if (System.IO.File.Exists(fullPath)) { return System.IO.File.ReadAllBytes(fullPath); } // 尝试热更新路径 fullPath = Application.persistentDataPath + "/LuaScripts/" + scriptPath + ".lua"; if (System.IO.File.Exists(fullPath)) { return System.IO.File.ReadAllBytes(fullPath); } return null; }); } private void LoadFrameworkScripts() { // 加载核心框架模块 string[] frameworkScripts = { "core/utils", "core/class", "core/event", "core/module", "core/mvc", "core/ui" }; foreach (string script in frameworkScripts) { luaEnv.DoString($"require('{script}')"); } } private void InitializeLuaFramework() { // 获取Lua框架表 luaFramework = luaEnv.Global.Get("Framework"); if (luaFramework != null) { // 初始化框架 LuaFunction initFunc = luaFramework.Get("Initialize"); initFunc?.Call(); } } private void StartGCCoroutine() { StartCoroutine(GCCoroutine()); } private System.Collections.IEnumerator GCCoroutine() { while (true) { yield return new WaitForSeconds(1f); luaEnv?.Tick(); // 定期执行完整GC if (Time.frameCount % 300 == 0) { luaEnv?.FullGc(); } } } public LuaEnv GetLuaEnv() { return luaEnv; } public void DoString(string script, string chunkName = "chunk") { luaEnv?.DoString(script, chunkName); } public void Require(string moduleName) { luaEnv?.DoString($"require('{moduleName}')"); } private void OnDestroy() { if (luaFramework != null) { LuaFunction shutdownFunc = luaFramework.Get("Shutdown"); shutdownFunc?.Call(); luaFramework.Dispose(); } luaEnv?.Dispose(); luaEnv = null; } } ``` ## 三、Lua框架核心模块 ### 1. 基础工具库 ```lua -- core/utils.lua local M = {} -- 打印函数 function M.print(...) local args = {...} for i, v in ipairs(args) do args[i] = tostring(v) end print("[Lua] " .. table.concat(args, " ")) end -- 判断表是否为空 function M.isEmpty(t) return t == nil or next(t) == nil end -- 深拷贝 function M.deepcopy(t) local copy = {} for k, v in pairs(t) do if type(v) == "table" then copy[k] = M.deepcopy(v) else copy[k] = v end end return copy end -- 表合并 function M.merge(t1, t2) local result = M.deepcopy(t1) for k, v in pairs(t2) do if type(v) == "table" and type(result[k]) == "table" then result[k] = M.merge(result[k], v) else result[k] = v end end return result end -- 防抖函数 function M.debounce(func, delay) local timer = nil return function(...) if timer then CS.UnityEngine.CoroutineUtility.StopCoroutine(timer) end local args = {...} timer = CS.UnityEngine.CoroutineUtility.StartCoroutine(function() CS.UnityEngine.Yield(CS.UnityEngine.WaitForSeconds(delay)) func(unpack(args)) timer = nil end) end end -- 节流函数 function M.throttle(func, delay) local lastCall = 0 return function(...) local now = CS.UnityEngine.Time.time if now - lastCall >= delay then lastCall = now func(...) end end end return M ``` ### 2. 类系统实现 ```lua -- core/class.lua local utils = require("core.utils") local M = {} -- 创建类 function M.class(className, super) local cls = {} cls.__className = className cls.__super = super cls.__instances = {} -- 元表 setmetatable(cls, { __index = function(t, k) if super then return super[k] end return nil end, __call = function(cls, ...) local instance = {} setmetatable(instance, { __index = cls }) if cls.ctor then cls.ctor(instance, ...) end table.insert(cls.__instances, instance) return instance end }) return cls end -- 类方法:获取实例数量 function M.GetInstanceCount(cls) return #cls.__instances end -- 类方法:获取所有实例 function M.GetAllInstances(cls) return cls.__instances end -- 类方法:销毁实例 function M.Destroy(instance) local cls = getmetatable(instance).__index for i, inst in ipairs(cls.__instances) do if inst == instance then table.remove(cls.__instances, i) end end end -- 单例模式 function M.singleton(className, ctor) local instance = nil return function(...) if not instance then instance = ctor(...) end return instance end end return M ``` ### 3. 事件系统 ```lua -- core/event.lua local utils = require("core.utils") local M = {} -- 事件管理器 local EventManager = M.class("EventManager") function EventManager:ctor() self.listeners = {} self.onceListeners = {} end -- 监听事件 function EventManager:on(eventName, callback, target) if not self.listeners[eventName] then self.listeners[eventName] = {} end table.insert(self.listeners[eventName], { callback = callback, target = target }) end -- 一次性监听 function EventManager:once(eventName, callback, target) if not self.onceListeners[eventName] then self.onceListeners[eventName] = {} end table.insert(self.onceListeners[eventName], { callback = callback, target = target }) end -- 移除监听 function EventManager:off(eventName, callback, target) local function removeListener(listeners) if not listeners[eventName] then return end for i = #listeners[eventName], 1, -1 do local listener = listeners[eventName][i] if listener.callback == callback and listener.target == target then table.remove(listeners[eventName], i) end end end removeListener(self.listeners) removeListener(self.onceListeners) end -- 派发事件 function EventManager:emit(eventName, ...) local function dispatch(listeners) if not listeners[eventName] then return end for i, listener in ipairs(listeners[eventName]) do if listener.target then listener.callback(listener.target, ...) else listener.callback(...) end end end -- 先派发一次性监听 dispatch(self.onceListeners) self.onceListeners[eventName] = nil -- 派发普通监听 dispatch(self.listeners) end -- 清空所有监听 function EventManager:clear() self.listeners = {} self.onceListeners = {} end -- 全局事件管理器实例 local globalEventManager = EventManager() -- 全局接口 function M.on(eventName, callback, target) globalEventManager:on(eventName, callback, target) end function M.once(eventName, callback, target) globalEventManager:once(eventName, callback, target) end function M.off(eventName, callback, target) globalEventManager:off(eventName, callback, target) end function M.emit(eventName, ...) globalEventManager:emit(eventName, ...) end function M.getEventManager() return globalEventManager end return M ``` ## 四、模块管理系统 ```lua -- core/module.lua local utils = require("core.utils") local class = require("core.class") local M = {} -- 模块基类 local Module = M.class("Module") function Module:ctor(name) self.name = name self.enabled = false self.initialized = false end function Module:initialize() utils.print("Module " .. self.name .. " initializing...") self.initialized = true end function Module:enable() if not self.initialized then self:initialize() end self.enabled = true utils.print("Module " .. self.name .. " enabled") end function Module:disable() self.enabled = false utils.print("Module " .. self.name .. " disabled") end function Module:update(deltaTime) -- 子类重写 end function Module:lateUpdate(deltaTime) -- 子类重写 end function Module:fixedUpdate(deltaTime) -- 子类重写 end function Module:destroy() utils.print("Module " .. self.name .. " destroyed") self.initialized = false self.enabled = false end -- 模块管理器 local ModuleManager = M.class("ModuleManager") function ModuleManager:ctor() self.modules = {} self.updateList = {} self.lateUpdateList = {} self.fixedUpdateList = {} end -- 注册模块 function ModuleManager:registerModule(module) if self.modules[module.name] then utils.print("Module " .. module.name .. " already registered") return end self.modules[module.name] = module utils.print("Module " .. module.name .. " registered") end -- 获取模块 function ModuleManager:getModule(name) return self.modules[name] end -- 启用模块 function ModuleManager:enableModule(name) local module = self:getModule(name) if module then module:enable() -- 添加到更新列表 if module.update then table.insert(self.updateList, module) end if module.lateUpdate then table.insert(self.lateUpdateList, module) end if module.fixedUpdate then table.insert(self.fixedUpdateList, module) end end end -- 禁用模块 function ModuleManager:disableModule(name) local module = self:getModule(name) if module then module:disable() -- 从更新列表中移除 for i = #self.updateList, 1, -1 do if self.updateList[i] == module then table.remove(self.updateList, i) end end for i = #self.lateUpdateList, 1, -1 do if self.lateUpdateList[i] == module then table.remove(self.lateUpdateList, i) end end for i = #self.fixedUpdateList, 1, -1 do if self.fixedUpdateList[i] == module then table.remove(self.fixedUpdateList, i) end end end end -- 更新所有启用的模块 function ModuleManager:update(deltaTime) for _, module in ipairs(self.updateList) do if module.enabled then module:update(deltaTime) end end end function ModuleManager:lateUpdate(deltaTime) for _, module in ipairs(self.lateUpdateList) do if module.enabled then module:lateUpdate(deltaTime) end end end function ModuleManager:fixedUpdate(deltaTime) for _, module in ipairs(self.fixedUpdateList) do if module.enabled then module:fixedUpdate(deltaTime) end end end -- 销毁所有模块 function ModuleManager:destroyAll() for name, module in pairs(self.modules) do module:destroy() end self.modules = {} self.updateList = {} self.lateUpdateList = {} self.fixedUpdateList = {} end -- 全局模块管理器实例 local globalModuleManager = ModuleManager() -- 全局接口 function M.registerModule(module) globalModuleManager:registerModule(module) end function M.getModule(name) return globalModuleManager:getModule(name) end function M.enableModule(name) globalModuleManager:enableModule(name) end function M.disableModule(name) globalModuleManager:disableModule(name) end function M.getModuleManager() return globalModuleManager end return M ``` ## 五、MVC框架实现 ```lua -- core/mvc.lua local utils = require("core.utils") local class = require("core.class") local event = require("core.event") local M = {} -- Model基类 local Model = M.class("Model") function Model:ctor(name) self.name = name self.data = {} self.listeners = {} end -- 设置数据 function Model:set(key, value) local oldValue = self.data[key] self.data[key] = value -- 通知数据变化 self:notifyChange(key, value, oldValue) end -- 获取数据 function Model:get(key) return self.data[key] end -- 监听数据变化 function Model:observe(key, callback) if not self.listeners[key] then self.listeners[key] = {} end table.insert(self.listeners[key], callback) end -- 移除监听 function Model:unobserve(key, callback) if not self.listeners[key] then return end for i = #self.listeners[key], 1, -1 do if self.listeners[key][i] == callback then table.remove(self.listeners[key], i) end end end -- 通知数据变化 function Model:notifyChange(key, newValue, oldValue) if self.listeners[key] then for _, callback in ipairs(self.listeners[key]) do callback(newValue, oldValue) end end end -- View基类 local View = M.class("View") function View:ctor(name) self.name = name self.gameObject = nil self.transforms = {} self.components = {} end -- 绑定GameObject function View:bind(gameObject) self.gameObject = gameObject self:onBind() end -- 绑定完成后回调 function View:onBind() -- 子类重写 end -- 获取Transform function View:getTransform(path) if not self.transforms[path] then self.transforms[path] = self.gameObject.transform:Find(path) end return self.transforms[path] end -- 获取组件 function View:getComponent(path, componentType) local key = path .. "_" .. componentType if not self.components[key] then local transform = self:getTransform(path) if transform then self.components[key] = transform:GetComponent(componentType) end end return self.components[key] end -- 显示 function View:show() if self.gameObject then self.gameObject:SetActive(true) end end -- 隐藏 function View:hide() if self.gameObject then self.gameObject:SetActive(false) end end -- Controller基类 local Controller = M.class("Controller") function Controller:ctor(name) self.name = name self.model = nil self.view = nil self.commands = {} end -- 绑定Model和View function Controller:bind(model, view) self.model = model self.view = view self:onBind() end -- 绑定完成后回调 function Controller:onBind() -- 子类重写 end -- 注册命令 function Controller:registerCommand(commandName, commandFunc) self.commands[commandName] = commandFunc end -- 执行命令 function Controller:executeCommand(commandName, ...) local command = self.commands[commandName] if command then command(self, ...) else utils.print("Command not found: " .. commandName) end end -- MVC工厂 local MVCFactory = M.class("MVCFactory") function MVCFactory:ctor() this.models = {} this.views = {} this.controllers = {} end -- 创建Model function MVCFactory:createModel(name, modelClass) local model = modelClass(name) self.models[name] = model return model end -- 创建View function MVCFactory:createView(name, viewClass, gameObject) local view = viewClass(name) view:bind(gameObject) self.views[name] = view return view end -- 创建Controller function MVCFactory:createController(name, controllerClass, modelName, viewName) local model = self.models[modelName] local view = self.views[viewName] local controller = controllerClass(name) controller:bind(model, view) self.controllers[name] = controller return controller end -- 获取Model function MVCFactory:getModel(name) return self.models[name] end -- 获取View function MVCFactory:getView(name) return self.views[name] end -- 获取Controller function MVCFactory:getController(name) return self.controllers[name] end -- 全局MVC工厂实例 local globalMVCFactory = MVCFactory() -- 全局接口 function M.createModel(name, modelClass) return globalMVCFactory:createModel(name, modelClass) end function M.createView(name, viewClass, gameObject) return globalMVCFactory:createView(name, viewClass, gameObject) end function M.createController(name, controllerClass, modelName, viewName) return globalMVCFactory:createController(name, controllerClass, modelName, viewName) end function M.getModel(name) return globalMVCFactory:getModel(name) end function M.getView(name) return globalMVCFactory:getView(name) end function M.getController(name) return globalMVCFactory:getController(name) end return M ``` ## 六、C#侧框架入口 ```csharp // GameFramework.cs - 框架入口 using UnityEngine; using XLua; public class GameFramework : MonoSingleton { private LuaTable luaFramework; private bool frameworkInitialized = false; private void Start() { // 初始化Lua环境 LuaManager.Instance.Initialize(); // 获取Lua框架 luaFramework = LuaManager.Instance.GetLuaEnv().Global.Get("Framework"); if (luaFramework != null) { // 启动框架 StartFramework(); } } private void StartFramework() { if (frameworkInitialized) return; // 调用Lua框架的启动方法 LuaFunction startFunc = luaFramework.Get("Start"); startFunc?.Call(); frameworkInitialized = true; Debug.Log("游戏框架启动完成"); } private void Update() { if (!frameworkInitialized) return; // 调用Lua框架的更新方法 LuaFunction updateFunc = luaFramework.Get("Update"); updateFunc?.Call(Time.deltaTime); } private void LateUpdate() { if (!frameworkInitialized) return; // 调用Lua框架的延迟更新方法 LuaFunction lateUpdateFunc = luaFramework.Get("LateUpdate"); lateUpdateFunc?.Call(Time.deltaTime); } private void FixedUpdate() { if (!frameworkInitialized) return; // 调用Lua框架的固定更新方法 LuaFunction fixedUpdateFunc = luaFramework.Get("FixedUpdate"); fixedUpdateFunc?.Call(Time.fixedDeltaTime); } private void OnApplicationPause(bool pauseStatus) { if (!frameworkInitialized) return; // 调用Lua框架的暂停回调 LuaFunction pauseFunc = luaFramework.Get("OnApplicationPause"); pauseFunc?.Call(pauseStatus); } private void OnDestroy() { if (!frameworkInitialized) return; // 调用Lua框架的销毁方法 LuaFunction destroyFunc = luaFramework.Get("OnDestroy"); destroyFunc?.Call(); } } ``` ## 七、完整框架启动脚本 ```lua -- Framework/init.lua - 框架主入口 local utils = require("core.utils") local event = require("core.event") local module = require("core.module") local mvc = require("core.mvc") local Framework = {} -- 框架初始化 function Framework.Initialize() utils.print("========================================") utils.print(" xLua游戏框架初始化中...") utils.print("========================================") -- 注册核心模块 Framework:RegisterCoreModules() -- 注册游戏模块 Framework:RegisterGameModules() -- 初始化事件系统 Framework:InitializeEventSystem() utils.print("========================================") utils.print(" xLua游戏框架初始化完成") utils.print("========================================") end -- 注册核心模块 function Framework:RegisterCoreModules() utils.print("注册核心模块...") -- 资源管理模块 local ResourceManager = require("modules.resource_manager") module.registerModule(ResourceManager("ResourceManager")) -- 配置管理模块 local ConfigManager = require("modules.config_manager") module.registerModule(ConfigManager("ConfigManager")) -- 网络管理模块 local NetworkManager = require("modules.network_manager") module.registerModule(NetworkManager("NetworkManager")) -- UI管理模块 local UIManager = require("modules.ui_manager") module.registerModule(UIManager("UIManager")) -- 音频管理模块 local AudioManager = require("modules.audio_manager") module.registerModule(AudioManager("AudioManager")) end -- 注册游戏模块 function Framework:RegisterGameModules() utils.print("注册游戏模块...") -- 玩家模块 local PlayerModule = require("modules.player_module") module.registerModule(PlayerModule("PlayerModule")) -- 战斗模块 local BattleModule = require("modules.battle_module") module.registerModule(BattleModule("BattleModule")) -- 关卡模块 local LevelModule = require("modules.level_module") module.registerModule(LevelModule("LevelModule")) end -- 初始化事件系统 function Framework:InitializeEventSystem() utils.print("初始化事件系统...") -- 注册全局事件 event.on("APP_PAUSE", function(paused) if paused then utils.print("应用暂停") else utils.print("应用恢复") end end) event.on("LEVEL_LOADED", function(levelName) utils.print("关卡加载完成: " .. levelName) end) end -- 框架启动 function Framework.Start() utils.print("========================================") utils.print(" 启动xLua游戏框架...") utils.print("========================================") -- 启用核心模块 module.enableModule("ResourceManager") module.enableModule("ConfigManager") module.enableModule("NetworkManager") module.enableModule("UIManager") module.enableModule("AudioManager") -- 加载配置 Framework:LoadConfigurations() -- 启动游戏模块 Framework:StartGameModules() -- 加载主场景 Framework:LoadMainScene() utils.print("========================================") utils.print(" xLua游戏框架启动完成") utils.print("========================================") end -- 加载配置 function Framework:LoadConfigurations() utils.print("加载游戏配置...") local configManager = module.getModule("ConfigManager") if configManager then configManager:LoadAllConfigs() end end -- 启动游戏模块 function Framework:StartGameModules() utils.print("启动游戏模块...") module.enableModule("PlayerModule") module.enableModule("BattleModule") module.enableModule("LevelModule") end -- 加载主场景 function Framework:LoadMainScene() utils.print("加载主场景...") local levelModule = module.getModule("LevelModule") if levelModule then levelModule:LoadLevel("MainScene") end end -- 框架更新 function Framework.Update(deltaTime) local moduleManager = module.getModuleManager() moduleManager:update(deltaTime) end -- 框架延迟更新 function Framework.LateUpdate(deltaTime) local moduleManager = module.getModuleManager() moduleManager:lateUpdate(deltaTime) end -- 框架固定更新 function Framework.FixedUpdate(deltaTime) local moduleManager = module.getModuleManager() moduleManager:fixedUpdate(deltaTime) end -- 应用暂停回调 function Framework.OnApplicationPause(paused) event.emit("APP_PAUSE", paused) end -- 框架销毁 function Framework.OnDestroy() utils.print("销毁xLua游戏框架...") local moduleManager = module.getModuleManager() moduleManager:destroyAll() event.getEventManager():clear() end -- 导出框架接口 _G.Framework = Framework return Framework ``` ## 八、核心模块示例实现 ### 资源管理模块 ```lua -- modules/resource_manager.lua local utils = require("core.utils") local class = require("core.class") local event = require("core.event") local moduleBase = require("core.module") local ResourceManager = moduleBase.Module:extend("ResourceManager") function ResourceManager:ctor(name) ResourceManager.super.ctor(self, name) self.loadedAssets = {} self.loadingRequests = {} end function ResourceManager:initialize() utils.print("初始化资源管理器...") -- 预加载核心资源 self:PreloadCoreAssets() ResourceManager.super.initialize(self) end -- 预加载核心资源 function ResourceManager:PreloadCoreAssets() local coreAssets = { "UI/Prefabs/MainPanel", "UI/Prefabs/HUDPanel", "Audio/BGM/MainTheme" } utils.print("预加载核心资源...") for i, assetPath in ipairs(coreAssets) do self:LoadAssetAsync(assetPath, function(asset) utils.print("预加载完成: " .. assetPath) end) end end -- 异步加载资源 function ResourceManager:LoadAssetAsync(assetPath, callback) -- 检查是否已加载 if self.loadedAssets[assetPath] then if callback then callback(self.loadedAssets[assetPath]) end return end -- 检查是否正在加载 if self.loadingRequests[assetPath] then table.insert(self.loadingRequests[assetPath], callback) return end -- 开始加载 self.loadingRequests[assetPath] = {callback} CS.ResourceLoader.Instance:LoadAssetAsync(assetPath, function(asset) self.loadedAssets[assetPath] = asset -- 通知所有等待的回调 for _, cb in ipairs(self.loadingRequests[assetPath]) do if cb then cb(asset) end end self.loadingRequests[assetPath] = nil utils.print("资源加载完成: " .. assetPath) -- 派发资源加载完成事件 event.emit("RESOURCE_LOADED", assetPath, asset) end) end -- 同步加载资源 function ResourceManager:LoadAsset(assetPath) -- 检查是否已加载 if self.loadedAssets[assetPath] then return self.loadedAssets[assetPath] end -- 同步加载 local asset = CS.ResourceLoader.Instance:LoadAsset(assetPath) if asset then self.loadedAssets[assetPath] = asset utils.print("资源加载完成: " .. assetPath) event.emit("RESOURCE_LOADED", assetPath, asset) end return asset end -- 卸载资源 function ResourceManager:UnloadAsset(assetPath) if self.loadedAssets[assetPath] then CS.Resources.UnloadAsset(self.loadedAssets[assetPath]) self.loadedAssets[assetPath] = nil utils.print("资源卸载完成: " .. assetPath) end end -- 获取已加载资源 function ResourceManager:GetLoadedAsset(assetPath) return self.loadedAssets[assetPath] end -- 清理未使用资源 function ResourceManager:CleanupUnusedAssets() CS.Resources.UnloadUnusedAssets() utils.print("清理未使用资源完成") end return ResourceManager ``` ## 九、框架使用示例 ### 游戏逻辑实现 ```lua -- game/player.lua local utils = require("core.utils") local class = require("core.class") local mvc = require("core.mvc") local event = require("core.event") local PlayerModel = mvc.Model:extend("PlayerModel") function PlayerModel:ctor(name) PlayerModel.super.ctor(self, name) -- 初始化玩家数据 self:set("level", 1) self:set("exp", 0) self:set("hp", 100) self:set("maxHp", 100) self:set("attack", 10) self:set("defense", 5) self:set("gold", 1000) end function PlayerModel:addExp(amount) local currentExp = self:get("exp") local level = self:get("level") self:set("exp", currentExp + amount) -- 检查升级 local expNeeded = level * 100 if currentExp + amount >= expNeeded then self:levelUp() end end function PlayerModel:levelUp() local level = self:get("level") self:set("level", level + 1) self:set("maxHp", self:get("maxHp") + 10) self:set("attack", self:get("attack") + 2) self:set("defense", self:get("defense") + 1) utils.print("玩家升级到 " .. self:get("level") .. " 级!") event.emit("PLAYER_LEVEL_UP", self:get("level")) end function PlayerModel:takeDamage(damage) local currentHp = self:get("hp") local defense = self:get("defense") local actualDamage = math.max(0, damage - defense) self:set("hp", math.max(0, currentHp - actualDamage)) utils.print("玩家受到 " .. actualDamage .. " 点伤害, 剩余生命: " .. self:get("hp")) if self:get("hp") <= 0 then event.emit("PLAYER_DEAD") end end function PlayerModel:heal(amount) local currentHp = self:get("hp") local maxHp = self:get("maxHp") self:set("hp", math.min(maxHp, currentHp + amount)) utils.print("玩家恢复 " .. amount .. " 点生命, 当前生命: " .. self:get("hp")) end local PlayerView = mvc.View:extend("PlayerView") function PlayerView:onBind() -- 绑定UI元素 self.hpText = self:getComponent("HPText", "Text") self.levelText = self:getComponent("LevelText", "Text") self.expText = self:getComponent("ExpText", "Text") self.hpSlider = self:getComponent("HPSlider", "Slider") self.expSlider = self:getComponent("ExpSlider", "Slider") -- 更新UI self:updateUI() end function PlayerView:updateUI() if self.hpText then self.hpText.text = "HP: " .. self.model:get("hp") .. "/" .. self.model:get("maxHp") end if self.levelText then self.levelText.text = "Lv. " .. self.model:get("level") end if self.expText then self.expText.text = "EXP: " .. self.model:get("exp") end if self.hpSlider then self.hpSlider.value = self.model:get("hp") / self.model:get("maxHp") end if self.expSlider then local expNeeded = self.model:get("level") * 100 self.expSlider.value = self.model:get("exp") / expNeeded end end local PlayerController = mvc.Controller:extend("PlayerController") function PlayerController:onBind() -- 监听数据变化 self.model:observe("hp", function(newValue, oldValue) self.view:updateUI() end) self.model:observe("level", function(newValue, oldValue) self.view:updateUI() end) self.model:observe("exp", function(newValue, oldValue) self.view:updateUI() end) -- 注册命令 self:registerCommand("ATTACK", function(controller, target) local damage = controller.model:get("attack") target:takeDamage(damage) end) self:registerCommand("HEAL", function(controller, amount) controller.model:heal(amount) end) end return { Model = PlayerModel, View = PlayerView, Controller = PlayerController } ``` ## 十、项目目录结构 ``` Assets/ ├── Scripts/ │ ├── Core/ │ │ ├── LuaManager.cs │ │ ├── GameFramework.cs │ │ └── MonoSingleton.cs │ ├── Services/ │ │ ├── ResourceLoader.cs │ │ ├── NetworkManager.cs │ │ └── AudioManager.cs │ └── Game/ │ └── GameController.cs ├── LuaScripts/ │ ├── core/ │ │ ├── utils.lua │ │ ├── class.lua │ │ ├── event.lua │ │ ├── module.lua │ │ └── mvc.lua │ ├── modules/ │ │ ├── resource_manager.lua │ │ ├── config_manager.lua │ │ ├── network_manager.lua │ │ ├── ui_manager.lua │ │ ├── audio_manager.lua │ │ ├── player_module.lua │ │ ├── battle_module.lua │ │ └── level_module.lua │ ├── game/ │ │ ├── player.lua │ │ ├── enemy.lua │ │ ├── battle.lua │ │ └── ui/ │ │ ├── main_panel.lua │ │ └── hud_panel.lua │ └── Framework/ │ └── init.lua └── Resources/ ├── UI/ │ └── Prefabs/ ├── Audio/ │ └── BGM/ └── Config/ ``` ## 十一、使用流程 ### 1. 初始化流程 ```csharp // 在Unity中创建空的GameObject,挂载GameFramework脚本 // 游戏启动时会自动初始化整个框架 ``` ### 2. 编写Lua游戏逻辑 ```lua -- 在LuaScripts/game/目录下编写游戏逻辑 -- 例如:player.lua ``` ### 3. 运行游戏 ``` 1. 在Unity中点击运行 2. 框架会自动初始化 3. Lua脚本会被加载执行 4. 游戏逻辑开始运行 ``` ## 十二、总结 这套xLua游戏框架的核心优势: 1. **模块化设计**:清晰的功能划分,易于扩展和维护 2. **完整的MVC架构**:数据、视图、控制器分离,代码结构清晰 3. **强大的事件系统**:模块间松耦合通信 4. **热更新支持**:Lua代码可以实时更新,无需重启游戏 5. **丰富的工具库**:提供常用的开发工具函数 6. **性能优化**:对象池、资源管理等优化机制 通过这套框架,你可以快速搭建一个功能完善、结构清晰的游戏项目,充分发挥xLua的优势,实现高效的游戏开发和热更新功能。 这个框架已经为你准备好了基础架构,你可以在此基础上根据项目需求进行扩展和定制,逐步构建出属于自己的游戏开发框架。
评论 0

发表评论 取消回复

Shift+Enter 换行  ·  Enter 发送
还没有评论,来发表第一条吧