上一章我 们介绍了开发中会用到的辅助工具,并建立了 GameScene 场景,接下来这章咱们将继续 GameScene 的传(bai)奇(bi)。不过在开始编写 GameScene 场景的代码以前,咱们仍是先来明确一下游戏的功能和实现方法。这样能够帮咱们更好的理解并设计逻辑。下面是总结出的结论:css
为了产生立体的滚动视觉效果,咱们决定用四层不一样的背景来实现这一效果(怕累死的,能够偷懒)。固然,这里层的概念不一样于引擎中的层(cc.Layer),它只是一个普通的副词而已。html
乱入一个知识点:游戏中元素的层级关系由 z-order 属性来决定,咱们能够经过设置元素的z-order值来控制元素之间的渲染顺序。默认状况下,全部元素的 z-order 为0,因此当游戏元素没有指定z-order值时,游戏中的元素将按添加顺序来显示。故此,咱们在添加游戏背景或其余元素时,应该要注意下它们的添加顺序 或 z-order 值,不要出现遮挡的现象。api
为了让代码结构更加清晰,接下来咱们将为 GameScene 场景建立一个背景层,而后把以上的四层背景图都添加到该层上。
app
因此,咱们在 src/app 目录下新建了一个layers 文件夹,而后再新建了一个 BackgroundLayer.lua 文件,并把它保存到 src/app/layers 目录下。框架
如下是建立空白 BackgroundLayer 层的代码:编辑器
1
2
3
4
5
6
7
8
|
BackgroundLayer =
class
(
"BackgroundLayer"
,function()
return
display.newLayer()
end)
function BackgroundLayer:ctor()
end
return
BackgroundLayer
|
display.newLayer()方法能建立并返回一个 cc.Layer 层对象。函数
注意:由于咱们将在其余(GameScene.lua)文件中调用 BackgroundLayer 类,因此在建立 BackgroundLayer 类时,咱们并无像建立 GameScene 同样把它定义为 local 局部型的类。工具
BackgroundLayer.lua 文件是个单独的模块文件,若是咱们想要引用它,那咱们须要把它加载到项目中来。ui
一般,载入文件到 Quick 项目可使用如下的两种方式:lua
它们的详细用法参见API。
这里,咱们载入 BackgroundLayer 模块用 require 方法。在 MyApp.lua 中加入以下的函数:
1
|
require(
"app.layers.BackgroundLayer"
)
|
这样就把咱们定义的 BackgroundLayer 类引入到了quick项目中,以后,咱们就能够在任何地方引用这个 BackgroundLayer 模块了。
接下来咱们来把 BackgroundLayer 层加入到 GameScene 场景中。
1
2
3
4
5
|
function GameScene:ctor()
self.backgroundLayer = BackgroundLayer.
new
()
:addTo(self)
end
|
这里调用BackgroundLayer.new()
方法实例化了一个 BackgroundLayer 对象,并把它加入到场景。这样 GameScene 场景中就有一层空白的 BackgroundLayer 层了。
框架整好之后,下面咱们来向层容器里面塞东西。
回到 BackgroundLayer 文件,下面咱们添加以下的一段函数来为 BackgroundLayer 层添加最底层的布幕背景,这里添加固定不动的布幕背景就如添加普通精灵。
1
2
3
4
5
6
|
function BackgroundLayer:createBackgrounds()
-- 建立布幕背景
local bg = display.newSprite(
"image/bj1.jpg"
)
:pos(display.cx, display.cy)
:addTo(self, -4)
end
|
addTo方法中能够指定游戏元素的 z-order 值,本教程中,咱们把布幕背景的z-order设置为-4,确保它位于场景的最下层(固然,这要确保该层中不能有比布幕背景的 z-order 值还小的元素)。
远景背景和近景背景有着共同的特征,它们都会以必定的速度向左循环移动。因此这里咱们以远景背景为例,说明下它们的实现过程。
首先,咱们添加两张首尾能够拼接的图片来表示滚动的远景背景图。
在BackgroundLayer:createBackgrounds()
方法中加入以下的代码来添加远景背景图:
1
2
3
4
5
6
7
8
9
10
|
-- 建立远景背景
local bg1 = display.newSprite(
"image/b2.png"
)
:align(display.BOTTOM_LEFT, display.left , display.bottom + 10)
:addTo(self, -3)
local bg2 = display.newSprite(
"image/b2.png"
)
:align(display.BOTTOM_LEFT, display.left + bg1:getContentSize().width, display.bottom + 10)
:addTo(self, -3)
table.insert(self.distanceBg, bg1) -- 把建立的bg1插入到了 self.distanceBg 中
table.insert(self.distanceBg, bg2) -- 把建立的bg2插入到了 self.distanceBg 中
|
其中 self.distanceBg 是一个 table 类型的值,它的定义咱们放在 ctor 函数中。
1
|
self.distanceBg = {}
|
实现滚动背景,须要作的就是不断的改变背景图片贴图横坐标,而且不断的刷新位置。因此咱们定义了一个滚动背景的函数scrollBackgrounds()。
1
2
3
4
5
6
7
8
9
10
11
12
|
function BackgroundLayer:scrollBackgrounds(dt)
if
self.distanceBg[2]:getPositionX() <= 0 then
self.distanceBg[1]:setPositionX(0)
end
local x1 = self.distanceBg[1]:getPositionX() - 50*dt -- 50*dt 至关于速度
local x2 = x1 + self.distanceBg[1]:getContentSize().width
self.distanceBg[1]:setPositionX(x1)
self.distanceBg[2]:setPositionX(x2)
end
|
以上的这段函数的做用就是让 self.distanceBg[1]
和 self.distanceBg[2]
的 X 坐标都向左移动 50 * dt (dt是时间间隔,两帧之间的时间间隔)个单位,self.distanceBg[2]
紧接在 self.distanceBg[1]
后面。
在此以后,须要添加不断执行 scrollBackgrounds() 函数的方法,以确保远景背景不断的向左移动。使用过 Cocos2d-x 的童鞋应该知道,Cocos2d-x 中能够经过重载 update 函数在每帧刷新的时候执行本身须要的一些操做。在 Quick 框架中,咱们把这种事件叫作帧事件,意思是每帧刷新时都会执行的事件。
帧事件在游戏中常常用来更新游戏中的数据。下面咱们将在 ctor() 函数中加入这种帧事件,用以更新背景图的坐标。代码以下:
1
2
3
4
5
6
7
8
9
10
11
|
function BackgroundLayer:ctor()
self.distanceBg = {}
self.nearbyBg = {}
self.tiledMapBg = {}
self:createBackgrounds()
self:addNodeEventListener(cc.NODE_ENTER_FRAME_EVENT, handler(self, self.scrollBackgrounds))
self:scheduleUpdate()
end
|
其中,addNodeEventListener 方法用于注册帧事件,scheduleUpdate 方法则启用了帧事件,只有调用了 scheduleUpdate 后,帧事件才会被触发。
此时咱们再用一样的方法添加近景背景(让它每次移动的距离大一些),运行游戏时,屏幕上就会出现滚循环移动的背景了。
注:以上截图不是循环的。
背景层中还有一个重要的滚动项,那就是容纳了障碍物和奖励品的 TMX 类型的背景。
前面章节中咱们已经提到过,TiledMap 编辑器能把单个的图块拼接成一幅完整的地图,而它的最终产物就是 TMX 文件。这里咱们也不要把它想的有多复杂,其实说白了,渲染出来就是一张破图而已。和 png,jpg的图片精灵外形无明显差别。
因此它滚动的原理和远/近景背景滚动的原理差很少,只不过,它不循环。咱们能够用一个以上的 TMX 文件来实现滚动,当最后一个 TMX 文件恰好显示完的时候游戏就结束。这里考虑到后续的碰撞检测,因此咱们只用一个 TMX 文件实现滚动。
载入 TMX 文件的代码以下,添加的位置依旧在 createBackgrounds 方法中。
1
2
3
|
self.map = cc.TMXTiledMap:create(
"image/map.tmx"
)
:align(display.BOTTOM_LEFT, display.left, display.bottom)
:addTo(self, -1)
|
让地图文件滚动的代码以下:
1
2
3
4
5
6
|
if
self.map:getPositionX() <= display.width - self.map:getContentSize().width then
self:unscheduleUpdate() -- 禁用帧事件,中止整个背景层滚动
end
local x5 = self.map:getPositionX() - 130*dt
self.map:setPositionX(x5)
|
好了,本周的教程就算完成了,这里咱们的 tmx 文件是在下暂时随便建立的一个,下一章咱们会详细地讲解如何制做 tmx 文件。
另外,关于本游戏的资源咱们将会在下章好好制做 tmx 文件后一并上传。