前面我们已经大概的讲解完了Quick的框架和代码结构,接下来,本章开始我们将正式进入到游戏的开发。当然在开发的过程中,如果遇到值得一提的知识点和概念,我们还是会为大家详细讲解的。
哈哈,这章的内容我加它为——开发初探,因为我们将先来实现一些基础的内容。本章将实现的效果如下图所示:
菜单场景
从前面章节讲解的的知识点中,我们知道每个新建的 Quick 项目里都已经默认创建好了一个 mainScene 场景,所以下面我们将利用这个现成的场景,把它改造成我们需要的游戏场景。
我们的游戏将是一个简单的游戏,所以不需要太复杂。理所当然的,第一个运行的游戏场景一般都是菜单场景,所以本小节我们的目的就是构建菜单场景,在这个场景中,我们会添加必要的节点和控件。
下面乱入一点基础知识,已经了解 Cocos2d-x 基础概念的童鞋可绕行,不用听我的废话。但如果你对 Cocos2d-x 一窍不通,并且想更加深入地了解这些概念的童鞋可参考《Cocos2d-x 中的基础概念》一文。这里我们也只简单说说:
Cocos2d-x ( Quick 同样)是一款基于节点树渲染的游戏引擎,它把游戏的各个部分抽象成了导演、节点、场景、层、精灵等等一系列的概念,所以你可以把 Cocos2d-x 游戏想象成一部电影。同电影一样,Cocos2d-x 游戏中每个时刻都有一个场景在独立运行,我们通过切换不同的场景可以完成整个游戏流程,场景切换的管理由导演来执行。
一个游戏可有多个不同的游戏场景,每个场景又可包含多个不同的层(或其他节点),每层可拥有任意的游戏节点(常见的是精灵,但也可以是层、菜单、文本等等)。其基本构架如下图所示:
现在还不是很理解也没有关系,因为新手都是在实际运用的过程中慢慢理解,慢慢积累出经验的。
菜单场景对于我们来说就只是一个简单的游戏场景而已,下面开始我们就来在菜单场景中挨个添加游戏对象吧!
添加背景精灵
首先,我们来给游戏添加一张背景图,背景资源大小如第二章分辨率适配时决定的一样,为 1136 x 640 的大小。
添加游戏资源时,我们必须把包括背景在内的所有图片资源都拷贝到 res 目录下(放到别处将无法被引用)。当然,为了和可能有的字体文件、音效文件等等游戏资源区分开来,你也可以像我一样,先在 res 目录下新建一个叫做 image 的文件夹,然后再把资源拷贝到这个 res/image 目录下。
拷贝资源过后,我们就可以修改代码来添加背景图片了。所以,接下来请打开 MainScene.lua 文件,在它的ctor方法中删除创建 “Hello World” 文本的那段多余代码,并添加如下的一段新代码来添加背景图片:
1 2 3 | display.newSprite( "image/main.jpg" ) :pos(display.cx, display.cy) :addTo(self) |
在以上的代码中,我们使用 display.newSprite() 方法创建了一个精灵对象,并把该对象添加到了 MainScene 场景中相应的位置上。
在此之后,保存好修改过的 lua 文件,然后切换到我们项目的 player 模拟器下,按住热键 command + R ( Windows 下按 F5 )就可以刷新 player 模拟器了,此时你就可以立即看到添加了背景图片的游戏场景了。如下图所示:
验证分辨率适配结果
需要注意的是,在 player 模拟器的 View 菜单下,为我们提供了数十种常见的设备分辨率,我们可以任意的切换到各种不同的分辨率上,以便我们测试游戏在不同分辨率上的显示效果。
大家可以试着选择一些,不过你会发现,不管我们再怎么选择,我们的屏幕始终是被背景图片铺满的,不会留有任何的黑边。这也就验证了我们之前的分辨率适配是成功的。
添加标题并让它上下运动
接下来我们来添加游戏的标题,这个标题会如开篇效果图中显示的一样——会一直不停的上下晃动。
要添加这样的一个效果,我们同样需要在 ctor 方法中添加如下的一段代码:
1 2 3 4 5 6 7 8 | local title = display.newSprite( "img/title.png" ) :pos(display.cx / 2 * 3, display.cy) :addTo(self) local move1 = cc.MoveBy:create(0.5, cc.p(0, 10)) local move2 = cc.MoveBy:create(0.5, cc.p(0, -10)) local SequenceAction = cc.Sequence:create( move1, move2 ) transition.execute(title, cc.RepeatForever:create( SequenceAction )) |
在这里,我们先添加了一个精灵图片到场景上,位置在(display.cx / 2 * 3, display.cy)的坐标处。紧接着,我们让标题精灵执行了一系列的动作效果。
其中 transition.execute(target, action, args) 方法用于执行一个动作效果,它可以为原本单一的动作添加各种附加特性。其参数分别代表:
- target: 显示对象(cc.Node)
- action: 动作对象
- args: table 参数表格对象
在我们的代码中,action 参数是我们自己构建的一个复合动作,它是一个永远都保持上下移动的动作。其中我们使用了3种类型的action来创建它:
- cc.MoveBy:该动作将使节点从当前坐标点匀速直线运动到相对偏移了一定向量的位置上。其create函数的两个参数分别表示运动到指定位 置所需的时间和移动的距离(偏移量),所以 move1 表示在0.5秒内向Y轴的正轴上移动10个像素,move2 表示在0.5秒内向Y轴的负方向上移动10个像素。
- cc.Sequence: 该动作允许我们把一系列动作组合起来,并按顺序执行它们。在上面的例子中,我们创建了一个顺序执行 move1、move2的动作,这个 SequenceAction 动作会首先执行 move1,等 move1 完成后,再马上执行 move2。 这样一来一回,执行该动作的节点最终会回到原来的位置上。
- cc.RepeatForever: 该动作是一个无限重复执行的动作。
cc.RepeatForever:create( SequenceAction )
表示创建了一个无限循环执行 SequenceAction 的动作。
保存文件后刷新 player,你将看到一个一直不停运动的标题栏:
添加按钮
下面我们继续添加按钮,其代码如下所示:
1 2 3 4 5 6 | cc.ui.UIPushButton. new ({ normal = "img/start1.png" , pressed = "img/start2.png" }) :onButtonClicked(function() print( "start" ) end) :pos( display.cx / 2, display.cy ) :addTo(self) |
在Quick中有三种不同的Button控件,分别是:UIPushButton (按钮控件)、UICheckBoxButton ( CheckButton 控件)和 UICheckBoxButtonGroup ( CheckButton 组控件)。
其中 UIPushButton 是最常用的按钮控件,它继承自UIButton,我们可以通过 cc.ui.UIPushButton.new(images, options) 方法来创建 UIPushButton。参数 images 是 table 类型,它代表各个按钮状态(正常、按下、禁用)下的图片;options 为可选参数,也是 tabl e类型,包含了是否scale9缩放,偏移flipX、flipY值等设置。
onButtonClicked 方法用于监听按钮的点击事件,当点击按钮时,将调用该方法中的代码。如上例中,当我们点击按钮时,会在控制台窗口中打印“start”的字段。同 onButtonClicked 方法类似的还有:
- onButtonPressed(callback):用于监听按钮的按下事件
- onButtonRelease(callback):用于监听按钮的释放事件
- onButtonStateChanged(callback):用于监听按钮的状态改变事件
刷新 player,其效果就会出来。
好了,到现在为止,本章我们的目标就算实现了,下章我们将新建其他游戏场景,敬请期待!!