local Game = { frameCount = 1, loadedList = {}, pauseStatus = false, hasFocus = true } EDITOR_MODE = CS.BF.GameConst.EDITOR_MODE DEBUG = CS.BF.GameConst.DEBUG USE_AB = CS.BF.GameConst.USE_AB IS_PUBLISH = CS.BF.BFPlatform.IsPublishChannel() NOT_PUBLISH = not IS_PUBLISH if EDITOR_MODE and CS.BF.BFMain.Instance.LuaMgr.DevExist then -- 调试等一些特殊代码可以写到lua_debug.lua文件里面,lua_debug已添加忽略,有需要的可以在根目录创建,和main.lua同级 local devLuaPath = CS.UnityEngine.Application.dataPath .. "/Developer/lua/lua_debug.lua" if CS.System.IO.File.Exists(devLuaPath) then require("lua_debug") end end local Input = CS.UnityEngine.Input local KeyCode = CS.UnityEngine.KeyCode function Game:recordloadedList() self.loadedList = {} for name, v in pairs(package.loaded) do self.loadedList[name] = 1 end end function Game:initBase() self:recordloadedList() require "app/bf/common/functions" require "app/bf/init" require "app/global/global_unity_func" CS.BF.BFMain.Instance.LuaMgr:GetGlobalLuaFunc() BF.exports.Logger = require "app/common/logger" BF.exports.LocalData = require "app/common/local_data" BF.exports.BIReport = require "app/common/bi_report" BF.exports.SchedulerManager = require "app/common/scheduler_manager" BF.exports.ResourceManager = require "app/common/resource_manager" BF.exports.AudioManager = require "app/common/audio_manager" BF.exports.RenderManager = require "app/common/render_manager" AudioManager:init() Logger.log("initBase") end function Game:initOther() require "app/bf/unity/unity" BF.exports.json = require "rapidjson" BF.exports.GConst = require "app/global/global_const" BF.exports.GFunc = require "app/global/global_func" BF.exports.LuaComponent = require "app/bf/component/lua_component" BF.exports.BaseCell = require "app/ui/common/cell/base_cell" BF.exports.VersionCompatible = require "app/common/version_compatible" BF.exports.Platform = require "app/common/platform" BF.exports.ConfigManager = require "app/common/config_manager" BF.exports.EventManager = require "app/common/event_manager" BF.exports.CameraManager = require "app/common/camera_manager" BF.exports.SceneManager = require "app/scene/scene_manager" BF.exports.BaseScene = require "app/scene/base_scene" BF.exports.UIManager = require "app/ui/ui_manager" BF.exports.BaseUI = require "app/ui/base_ui" BF.exports.BaseSubUI = require "app/ui/base_sub_ui" BF.exports.UIPrefabManager = require "app/common/uiprefab_manager" BF.exports.TextureManager = require "app/common/texture_manager" BF.exports.ModelManager = require "app/common/model_manager" BF.exports.EffectManager = require "app/common/effect_manager" BF.exports.SpineManager = require "app/common/spine_manager" BF.exports.WebRequestManager = require "app/common/webrequest_manager" BF.exports.NetManager = require "app/net/net_manager" BF.exports.I18N = require "app/common/i18n_manager" BF.exports.CellManager = require "app/common/cell_manager" BF.exports.Time = require "app/common/time" BF.exports.BaseData = require "app/userdata/base_data" BF.exports.BaseObject = require "app/bf/unity/base_object" BF.exports.ServerPushManager = require "app/common/server_push_manager" BF.exports.SafeAreaManager = require "app/common/safe_area_manager" BF.exports.BaseModule = require "app/module/base_module" BF.exports.ModuleManager = require "app/common/module_manager" BF.exports.DataManager = require "app/common/data_manager" BF.exports.DOTweenManager = require "app/common/dotween_manager" BF.exports.FSMManager = require "app/common/state_machine_manager" BF.exports.ProtoMsgType = require "app/proto/proto_msg_type" BF.exports.SDKManager = require "app/common/sdk_manager" BF.exports.DeviceHelper = require "app/common/device_helper" BF.exports.PayManager = require "app/common/pay_manager" CameraManager:init() WebRequestManager:init() I18N:init() DataManager:init() DOTweenManager:init() ModuleManager:init() NetManager:init() -- 例如EmmyLua等IDE或者插件无法识别BF.exports.xx的全局变量赋值语法,这里专门处理一下 self:specialForIdea() end function Game:specialForIdea() if EDITOR_MODE then -- xlua专用的全局变量 CS = CS typeof = typeof json = json or require "rapidjson" Logger = Logger or require "app/common/logger" LocalData = LocalData or require "app/common/local_data" BIReport = BIReport or require "app/common/bi_report" SchedulerManager = SchedulerManager or require "app/common/scheduler_manager" ResourceManager = ResourceManager or require "app/common/resource_manager" AudioManager = AudioManager or require "app/common/audio_manager" RenderManager = RenderManager or require "app/common/render_manager" GConst = GConst or require "app/global/global_const" GFunc = GFunc or require "app/global/global_func" LuaComponent = LuaComponent or require "app/bf/component/lua_component" BaseCell = BaseCell or require "app/ui/common/cell/base_cell" VersionCompatible = VersionCompatible or require "app/common/version_compatible" Platform = Platform or require "app/common/platform" ConfigManager = ConfigManager or require "app/common/config_manager" EventManager = EventManager or require "app/common/event_manager" CameraManager = CameraManager or require "app/common/camera_manager" SceneManager = SceneManager or require "app/scene/scene_manager" BaseScene = BaseScene or require "app/scene/base_scene" UIManager = UIManager or require "app/ui/ui_manager" BaseUI = BaseUI or require "app/ui/base_ui" BaseSubUI = BaseSubUI or require "app/ui/base_sub_ui" UIPrefabManager = UIPrefabManager or require "app/common/uiprefab_manager" TextureManager = TextureManager or require "app/common/texture_manager" ModelManager = ModelManager or require "app/common/model_manager" EffectManager = EffectManager or require "app/common/effect_manager" SpineManager = SpineManager or require "app/common/spine_manager" WebRequestManager = WebRequestManager or require "app/common/webrequest_manager" NetManager = NetManager or require "app/net/net_manager" I18N = I18N or require "app/common/i18n_manager" CellManager = CellManager or require "app/common/cell_manager" Time = Time or require "app/common/time" BaseData = BaseData or require "app/userdata/base_data" BaseObject = BaseObject or require "app/bf/unity/base_object" ServerPushManager = ServerPushManager or require "app/module/login/server_push_manager" SafeAreaManager = SafeAreaManager or require "app/common/safe_area_manager" BaseModule = BaseModule or require "app/module/base_module" ModuleManager = ModuleManager or require "app/common/module_manager" DataManager = DataManager or require "app/common/data_manager" DOTweenManager = DOTweenManager or require "app/common/dotween_manager" FSMManager = FSMManager or require "app/common/state_machine_manager" ProtoMsgType = ProtoMsgType or require "app/proto/proto_msg_type" SDKManager = SDKManager or require "app/common/sdk_manager" DeviceHelper = DeviceHelper or require "app/common/device_helper" PayManager = PayManager or require "app/common/pay_manager" end end function Game:disableGlobalVariable() if self.g_meta_table then setmetatable(_G, self.g_meta_table) elseif BF and BF.disableGlobal then BF.disableGlobal() else setmetatable(_G, { __newindex = function(_, name, value) error(string.format("USE \" BF.exports.%s = value \" INSTEAD OF SET GLOBAL VARIABLE", name), 0) end }) end end function Game:enableGlobalVariable() self.g_meta_table = getmetatable(_G) setmetatable(_G, nil) end function Game:start() local time = os.clock() RenderManager:initRender(function() Logger.log("===========start game================") self:initOther() -- 先初始化UIManager UIManager:init(function() Logger.log("init game use time " .. (os.clock() - time)) SDKManager:init() -- 然后等字体加载完成后再显示界面 I18N:onFontLoaded(function() SceneManager:enterMainScene() end) end) end) end function Game:showLoginUI() UIManager:hideRollToast(true) ModuleManager.LoginManager:showLoginUI() end -- 测试地址的连接情况 function Game:httpRequestHostAndReport(ipOrHost) local startTime = CS.UnityEngine.Time.time local httpRequest = CS.BestHTTP.HTTPRequest(CS.System.Uri(ipOrHost), CS.BestHTTP.HTTPMethods.Get, function(req, httpResponse) if httpResponse and httpResponse.IsSuccess == true then BIReport:postPingServer(ipOrHost, math.floor((CS.UnityEngine.Time.time - startTime)*1000), "Success") else BIReport:postPingServer(ipOrHost, math.floor((CS.UnityEngine.Time.time - startTime)*1000), "Failed") end end) httpRequest:Send() end function Game:handleInputKey() if not self.hasFocus then return end if self.pauseStatus then return end if Input.GetKeyDown(KeyCode.Escape) then if UIManager then UIManager:onPressAndroidBackspace() end end if Input.anyKey then -- 待确认 EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.GET_ANY_KEY_DOWN) end end function Game:clear() SchedulerManager:clear() EventManager:clear() AudioManager:clear() ResourceManager:clear() end function Game:onDestroy() end function Game:update() self.frameCount = self.frameCount + 1 if SchedulerManager then SchedulerManager:update() end if FSMManager then FSMManager:tick() end self:handleInputKey() end function Game:onApplicationFocus(hasFocus) if hasFocus == self.hasFocus then return end self.hasFocus = hasFocus end function Game:onApplicationPause(pauseStatus) if pauseStatus == self.pauseStatus then return end self.pauseStatus = pauseStatus end function Game:onApplicationQuit() -- 上报游戏退出 if BIReport then BIReport:postGameExit() end end function Game:onLogMessageReceived(logString, stackTrace) -- 同一帧内的多个crash只处理第一个 if self.currCrashFrame == self.frameCount then return end self.currCrashFrame = self.frameCount if self.lastLogString == logString and self.lastStackTrace == stackTrace then return end self.lastLogString = logString self.lastStackTrace = stackTrace if BIReport then BIReport:postLuaCrash(logString, stackTrace) end end function Game:garbageCollect(callback) ResourceManager:unloadAllDelayAssets() CS.BF.BFMain.Instance.LuaMgr:LuaEnvFullGC(30000) collectgarbage("collect") local asyncOperation = CS.UnityEngine.Resources.UnloadUnusedAssets() local function onUnloadComplete(opration) asyncOperation:completed("-", onUnloadComplete) if callback then callback() end end asyncOperation:completed("+", onUnloadComplete) end function Game:destroyAll() self:destroyLua() self:destroyRes() self:destroyAB() end function Game:destroyLua() for name, v in pairs(package.loaded) do if not self.loadedList[name] then package.loaded[name] = nil end end package.loaded["app/game"] = nil package.loaded["app/first/first"] = nil package.loaded["app/first/first_text"] = nil CS.BF.BFMain.Instance.LuaMgr:ClearCache() CS.BF.BFMain.Instance.LuaMgr:Clear() end function Game:destroyRes() UIManager:destroyUIRoot() ResourceManager:unloadAllDelayAssets() ResourceManager:clear() end -- 清理没有被ResourceManager卸载的ab function Game:destroyAB() local bundles = CS.UnityEngine.AssetBundle.GetAllLoadedAssetBundles() if bundles then local len = bundles.Length for i = 0, len - 1 do local bundle = bundles[i] if bundle then Logger.log("[game]destroyAB :%s", bundle.name) if "first/first.ab" ~= bundle.name then bundle:Unload(false) end end end end end if NOT_PUBLISH then Game._releaseOnLogMessageReceived = Game.onLogMessageReceived function Game:onLogMessageReceived(logString, stackTrace) self:_releaseOnLogMessageReceived(logString, stackTrace) if UIManager then local params = { desc = logString .. stackTrace } ModuleManager.TipsManager:showHelpTips(params) end end Game._releaseHandleInputKey = Game.handleInputKey function Game:handleInputKey() self:_releaseHandleInputKey() if Input.GetKeyDown(KeyCode.T) then -- 如果当前正处于输入状态,则不显示响应gm快捷键 local comps = CS.UnityEngine.GameObject.FindObjectsOfType(GConst.TYPEOF_UNITY_CLASS.UI_INPUT_FIELD) for i = 0, comps.Length - 1 do if comps[i].isFocused then return end end if UIManager and UIManager:getTopUIObj() and UIManager:getTopUIObj():getUIIndex() ~= UIManager.UI_PATH.GM_TOO_UI then if ModuleManager.DevToolManager then ModuleManager.DevToolManager:showOrHideDevListUI() end end end if Input.GetKeyDown(KeyCode.Backspace) and Input.GetKey(KeyCode.RightControl) then Logger.logHighlight("on press backspace") if UIManager then UIManager:onPressAndroidBackspace() end end if Input.GetKeyDown(KeyCode.J) and Input.GetKey(KeyCode.RightControl) then local desktopDir = CS.System.Environment.GetFolderPath(CS.System.Environment.SpecialFolder.DesktopDirectory) local path = CS.System.IO.Path.Combine(desktopDir, "bf_screenshot.png") CS.UnityEngine.ScreenCapture.CaptureScreenshot(path, 1) Logger.logHighlight("截图保存地址:%s", path) end if Input.GetKeyDown(KeyCode.G) and Input.GetKey(KeyCode.LeftControl) then local battleController = ModuleManager.BattleManager.battleController if not battleController then return end if battleController.battleData.gridEntities then local map = {} for posId, entity in pairs(battleController.battleData.gridEntities) do map[tostring(posId)] = entity:getSnapshoptInfo() end Logger.logHighlight("——————————战斗棋盘快照如下————————") Logger.logHighlight("——————————当前战斗回合步骤————————" .. battleController.roundStep) Logger.logHighlight(json.encode(map)) end end if (Input.GetKeyDown(KeyCode.RightArrow) or Input.GetKeyDown(KeyCode.LeftArrow)) and Input.GetKey(KeyCode.LeftControl) then if not ModuleManager.DevToolManager.set_board_info then Logger.logHighlight("请先去gm面板设置浏览的棋盘信息!") return end local configName = ModuleManager.DevToolManager.set_board_info.config local idx = ModuleManager.DevToolManager.set_board_info.idx or 0 local isMystery = ModuleManager.DevToolManager.set_board_info.isMystery if not configName then return end local config = ConfigManager:getConfig(configName) if Input.GetKeyDown(KeyCode.LeftArrow) then idx = idx - 1 if isMystery then while config[idx] do if config[idx].mystery_box_board then break end idx = idx - 1 end end else idx = idx + 1 if isMystery then while config[idx] do if config[idx].mystery_box_board then break end idx = idx + 1 end end end if not config[idx] then Logger.logHighlight(configName .. " 没有id idx = " .. idx) return end Logger.logHighlight(configName .. " 当前 idx = " .. idx) ModuleManager.DevToolManager.set_board_info.idx = idx local board = config[idx].board if not board then board = config[idx].board_daily_challenge end if isMystery then board = config[idx].mystery_box_board if not board then Logger.logHighlight(configName .. " 没有mystery_box_board idx = " .. idx) return end end if ModuleManager.BattleManager:isInBattle() then local battleController = ModuleManager.BattleManager.battleController battleController.battleData:refreshBoard(board, battleController:getBlockIcon()) battleController.battleUI:initGridCell() end end end Game._releaseOnApplicationFocus = Game.onApplicationFocus function Game:onApplicationFocus(hasFocus) if hasFocus ~= self.hasFocus and hasFocus == true then -- 说明从后台返回到游戏里 end self:_releaseOnApplicationFocus(hasFocus) end end return Game