PS:本人用的是 3.8.1 的版本
新建了一个Cocos Lua的项目,一开始看它的启动流程看得有点晕,于是整理了一下,以下是我整理的结果,如有不妥之处,请多多指教。
1、第一步不用说,AppDelegate,可以看到有下面一句代码
if (engine->executeScriptFile("src/main.lua"))
{
return false;
}
意思就是执行了main.lua这个文件。
2、找到 main.lua 这个文件,里面除了添加搜索路径外,还定义了 main 函数,
local function main()
require("app.MyApp"):create():run()
end
3、到 app 目录下找 MyApp.lua,
local MyApp = class("MyApp", cc.load("mvc").AppBase)
等同于是 MyApp 继承了 AppBase 这个类(当然 lua 没有类这个说法),并把这个 MyApp 返回,然后看回第二步,显然,接下来就是用返回的 MyApp 去调用 create() 函数。
那我们进去这个 create 函数里面看下。
4、可是等你找到在 src/packages/mvc 目录下的 AppBase.lua 文件,会发现找不到 create 函数,只有一个function AppBase:ctor(configs)
, 其实在调用 create 函数的时候就会调用这个 ctor 函数,这是怎么回事?
在 src/cocos/cocos2d 目录下找到 function.lua,里面有下面这段代码
function class(classname, ...)
local cls = {__cname = classname}
………………
………………
if not cls.ctor then
-- add default constructor
cls.ctor = function() end
end
cls.new = function(...)
local instance
if cls.__create then
instance = cls.__create(...)
else
instance = {}
end
setmetatableindex(instance, cls)
instance.class = cls
instance:ctor(...)
return instance
end
cls.create = function(_, ...)
return cls.new(...)
end
return cls
end
显然,create –> new –> ctor。
5、调用完 create 之后,就相当于已经生成了这个类,然后继续调用 run 方法,就相继执行了下面的三个函数
function AppBase:run(initSceneName)
initSceneName = initSceneName or self.configs_.defaultSceneName
self:enterScene(initSceneName)
end
function AppBase:enterScene(sceneName, transition, time, more)
local view = self:createView(sceneName)
view:showWithScene(transition, time, more)
return view
end
function AppBase:createView(name)
for _, root in ipairs(self.configs_.viewsRoot) do
local packageName = string.format("%s.%s", root, name)
local status, view = xpcall(function()
return require(packageName)
end, function(msg)
if not string.find(msg, string.format("'%s' not found:", packageName)) then
print("load view error: ", msg)
end
end)
local t = type(view)
if status and (t == "table" or t == "userdata") then
return view:create(self, name)
end
end
error(string.format("AppBase:createView() - not found view \"%s\" in search paths \"%s\"",
name, table.concat(self.configs_.viewsRoot, ",")), 0)
end
createView 函数里面有一句 return require(packageName)
,这是的 packageName 是 app.views.MainScene,因为在 AppBase:ctor 函数里面有写,当然可以自己改动。
self.configs_ = {
viewsRoot = "app.views",
modelsRoot = "app.models",
defaultSceneName = "MainScene",
}
然后 require 返回的 view 调用了 create 函数,return view:create(self, name)
,我们到 MainScene.lua 里面能看到它是继承 ViewBase 的
local MainScene = class("MainScene", cc.load("mvc").ViewBase)
6、ViewBase 和 AppBase 一样都是没有定义 create 函数,只是定义了 ctor 函数,在 ctor 函数的最后可以看到
if self.onCreate then
self:onCreate()
end
这个就相当于是C++里面的虚函数,在 ViewBase 里面有,不过里面是空的,在 MainScene 里面也有,函数里面是有实现的。
其实 ctor 就相当于 C++ 里面的 CREATE_FUNC(MainScene),onCreate 就相当于 bool init() 。主要就是在 onCreate 函数里面实现你想要的东西。
7、在执行完 createView 函数之后,就用生成的 View 执行了 showWithScene 函数,其实就是切换场景。
至此,整个Cocos2d-Lua 的启动流程差不多就是这样了。