本章我们继续解析新建项目的代码文件,衔接不上的童鞋可以先回顾下上章的内容。那么下面我们就言简意赅直接进入正题吧!
2、main.lua
在src目录下,除了 config.lua 文件外,还有一个 main.lua 文件,这个 main.lua 是 Quick 项目的通用入口文件,它类似于 Cocos2d-x 中的 AppDelegate.h/cpp 文件,同时也类似于一般 Windows 工程中的 main 文件。
1
2
3
4
5
6
7
8
9
10
|
function __G__TRACKBACK__(errorMessage)
print(
"----------------------------------------"
)
print(
"LUA ERROR: "
.. tostring(errorMessage) ..
"\n"
)
print(debug.traceback(
""
,2))
print(
"----------------------------------------"
)
end
package.path = package.path ..
";src/"
cc.FileUtils:getInstance():setPopupNotify(
false
)
require(
"app.MyApp"
).
new
():run()
|
每个新项目的 main.lua 文件内容都是一样的,一般情况下,我们不需要改动它。
我们只需要知道,main 文件的最后一行代码中通过载入的 app.MyApp 模块创建了一个 MyApp 实例,并且还调用执行了该 MyApp 实例的 run 方法。这行代码将启动并执行 MyApp 脚本。从此处我们也可以看出,main.lua 文件是应用程序 lua 脚本的启动文件。
require 方法表示引入一个文件,使用 require 方法加载文件的过程会检查文件的 lua 语法,同时会完成被加载文件内部变量的初始化。
3、MyApp.lua
main.lua 文件启动执行 MyApp 脚本后,接下来我们就来看看“src/app”目录下的 MyApp.lua 文件,该文件将启动游戏场景,其代码段如下所示:
-- 1
require(
"config"
)
require(
"cocos.init"
)
require(
"framework.init"
)
-- 2
local MyApp =
class
(
"MyApp"
,cc.mvc.AppBase)
-- 3
function MyApp:ctor()
MyApp.super.ctor(self)
end
-- 4
function MyApp:run()
cc.FileUtils:getInstance():addSearchPath(
"res/"
)
cc.Director:getInstance():setContentScaleFactor( 640/CONFIG_SCREEN_HEIGHT )
self:enterScene(
"MainScene"
)
end
return
MyApp
|
我们依次来看以上各代码行的含义:
- 使用 require 方法载入配置、cocos 以及 Quick 框架。这些是每个 Quick 程序都必须要加载的。
- 使用 class 函数定义一个 MyApp 类。
class 方法本身是 Quick 框架中定义的一个用于创建自定义 lua 类的函数,该函数可在 Quick 引擎的 “quick/framework/functions.lua” 文件中找到。当然,如果你听了我的话,在 Sublime 下安装了 QuickDev 插件,那么你也可以在 class 字符上单击右键,跳转到它的定义(Goto Definition),这样也能找到它。
在 “functions.lua” 中,function class(classname,super)
函数有两个参数,其中classname
表示的是类名,super
表示的是父类或者创建对象实例的函数。当super
传入的参数是前者时,将会以传入的对象为父类派生新类,如本处;当传入的参数为后者时,会以传入的函数作为构造函数创建新类,如稍后要讲解的 MainScene 类。
从本段代码中我们可以看到,MyApp 这个类是从 cc.mvc.AppBase 中继承而来的,而 AppBase 是 Quick 中自带的一个 MVC(面向对象的一种设计模式)的应用程序基础类,这个类为我们的应用程序提供了一些逻辑控制上的功能,比如进入场景,切换场景等等。 - MyApp 的ctor()函数相当于 C++ 中的构造(constructor)函数,以及init()函数。所以我们一般会在ctor()函数中初始化我们的游戏数据和信息,每当调用 XXClass.new() 创建对象实例时,也会自动执行ctor()函数。
另外,在子类的ctor函数中必须手动调用父类的构造函数,这样才等保证子类能“继承”父类的属性和方法,正如上段代码所示。其中 XXClass.super 可以访问指定 XXClass 类的父类。 - 在 MyApp 的 run 方法中,这里做了三件事:
- 首先,通过 addSearchPath 方法设置资源搜索路径。这也是为什么资源一定要放在“res”目录下的原因。
- 然后,通过 setContentScaleFactor 方法设置资源缩放因子,这行代码是我们在上章进行分辨率适配时自己添加的。
- 最后,因为 MyApp 类继承于 AppBase 类,因此自然地,MyApp 也同父类一样,具备了些许逻辑控制的功能。所以在 run 方法的最后,程序调用 enterScene 函数进入到名为 “MainScene” 的游戏场景。
当然我们也可以在 enterScene 函数中设置场景切换的动画,不过为了加深大家对场景切换的印象,我们还是留到后面使用的时候再做详细的讲解。注意:游戏场景默认必须放在 “src/app/scenes” 目录下,放到其他目录下是不能找到的。
4、MainScene.lua
讲的这里,大家应该很清楚 main 文件执行require("app.MyApp").new():run()
代码的过程了吧。所以,接下来请大家打开“src/app/scenes”目录下的 MainScene.lua 文件,我们接着来看它的结构。其代码如下图所示:
local MainScene =
class
(
"MainScene"
,function()
return
display.newScene(
"MainScene"
)
end)
function MainScene:ctor()
cc.ui.UILabel.
new
({
UILabelType = 2,text =
"Hello,World"
,size = 64})
:align(display.CENTER,display.cx,display.cy)
:addTo(self)
end
function MainScene:onEnter()
end
function MainScene:onExit()
end
return
MainScene
|
在 MainScene.lua 这个文件中,第一行代码使用 class 函数创建了一个 MainScene 场景类,同前边创建 MyApp 类不同的是,这里我们的类不是从基础类继承而来,而是通过一个函数创建出来的。
这是因为 Scene 场景对象必须是一个 C++ 的对象,而 C++ 的对象是无法直接派生出 Lua 的类的,所以我们只有用一个函数把它创建出来,然后再为它添加相应的方法。
在创建场景的函数段里,display.newScene()
方法将创建了一个新场景,并返回该 Scene 场景对象。
这里的 display 是一个重要的概念,在 Quick 中,display 模块封装了绝大部分与显示有关的功能,并负责根据 config.lua 中定义的分辨率设定计算屏幕的设计分辨率。display 模块提供了众多的方法和属性,比如创建层(display.newLayer),创建精灵(display.newSprite),以及恢复暂停切换场景等等。
总而言之,display 是个很值得我们细细探索的模块。关于它更多详情内容可参见Quick-Cocos2d-x的API文档。
下面我们例举一些 display 常用的属性:
- display.widthInPixels,display.heightInPixels: 屏幕分辨率的宽、高
- display.width,display.height: 设计分辨率的宽、高
- display.cx,display.cy: 设计分辨率中央的 x、y 坐标
- display.left,display.top,display.right,display.bottom: 设计分辨率四边的坐标
- display.c_left,display.c_top,display.c_right,display.c_bottom: 当父对象在屏幕中央时,屏幕四边的坐标
- display.contentScaleFactor: 设计分辨率到屏幕分辨率的缩放因子,不同于内容缩放因子。
结合 display 模块提供的常量,我们可以很方便的获取屏幕的某些与现实相关的属性,如位置和颜色等等。display 模块中关于位置的常量是初始化的时候程序就已经计算好的(不信你可以查看控制台窗口中的打印信息),它们根据分辨率的不同而不同。
MainScene 的 ctor 函数中默认添加了一个 UI 标签,这个标签的作用是在屏幕正中间添加一个“Hello World”的文本,并显示到屏幕上。
其中 cc.ui 模块中封装了大量符合脚本风格的 Cocos2d-x 控件,包含 UILabel、UIImage、UiSlider 等等。所以正如上述代码一样,我们可以通过调用cc.ui.UILabel.new()
来实例化一个新的 UILabel 控件。其先有参数分别表示:
- UILabelType:创建文本对象所使用的方式。
1 表示使用位图字体创建文本显示对象,返回对象是 LabelBMFont。
2 表示使用 TTF 字体创建文字显示对象,返回对象是 Label。 - text:要显示的文本。
- size:文字尺寸。
创建好 UILabel 后,通过调用 align 方法设置文本的锚点和显示位置。最后用 addTo 方法把文本添加到场景中。
至于 MainScene 的 onEnter 和 onExit 两个方法,清楚 Cocos2d-x 原理的的童鞋应该很容易理解。其中onEnter 方法是在进入场景的时候调用的,我们可以在这里做一些初始化的工作;而 onExit 方法是在退出场景的时候调用的,在这里我们可以释放资源,重置变量。
小结
到现在为止,我们就已经解析完 src 目录下所有的 lua 文件了,总的来说,这两章所解析的 lua 文件的关系和用途如下图所示:
好了,上图把这两章讲解的废话都概括完了,我想应该够清楚明了的吧!! O(∩_∩)O~,从下章开始,我们将正式开始类el游戏的开发。