Cocos2d-x 3.x Lua的启动流程

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 的启动流程差不多就是这样了。

你可能感兴趣的:(Cocos2dx,Lua,cocos2d-x,lua)