Quick-Cocos2d-x初学者游戏教程(六) --------------------- 游戏逻辑

Quick-Cocos2d-x初学者游戏教程(六)

上一章我 们介绍了开发中会用到的辅助工具,并建立了 GameScene 场景,接下来这章咱们将继续 GameScene 的传(bai)奇(bi)。不过在开始编写 GameScene 场景的代码以前,咱们仍是先来明确一下游戏的功能和实现方法。这样能够帮咱们更好的理解并设计逻辑。下面是总结出的结论:css

  1. 在 GameScene 场景中,咱们将建立一个飞行的娃娃角色,这个角色是游戏的惟一主角。游戏初始状态下,这个角色有满满的生命值,但随着时间的推移,生命值会不断的减小。这里生命值咱们能够以进度条的形式来展现它的多少和增减。
  2. 游戏 GameScene 场景有不止一层的滚动背景,每层的背景滚动速率不一,这样能够产生立体的滚动效果。娃娃位置不动,让背景不停的滚动,能够产生娃娃在向前飞行的视觉感觉。
  3. 在滚动过程当中屏幕上会时不时的出现一些障碍物和能够增长生命值的奖励品,当娃娃碰到障碍物时,生命值减小;碰到奖励品时,生命值增长。
  4. 当触碰屏幕时,娃娃将向上升至必定的高度;当不触碰屏幕时,它将向下掉落。掉落到地板时会扣除相应的生命值。因此玩家必须在按与不按之间保持必定的平衡,一方面躲避障碍物并避免触碰地板,另外一方面争取多吃一点奖励品,这样才能让娃娃顺利地到达终点。
  5. 本场景咱们将用物理引擎来模拟整个飞行世界,这样游戏主角的飞行问题(漂浮状态),以及它与障碍物/奖励品之间的碰撞检测就很容易实现了。

GameScene 的背景

为了产生立体的滚动视觉效果,咱们决定用四层不一样的背景来实现这一效果(怕累死的,能够偷懒)。固然,这里层的概念不一样于引擎中的层(cc.Layer),它只是一个普通的副词而已。html

  • 首先,最底层是一张固定不动的布幕背景;
  • 其次,我将在布幕背景的上层添加一层远景背景,该背景将会以较慢的速度向左滚动;
  • 而后,在远景背景的上层咱们又会添加一层近景背景,该背景将会以较快的速度向左滚动;
  • 最后,在最上层,咱们将放置一层以更快速度向左滚动的背景,游戏的障碍物和奖励品都会在该层背景上。因此这层背景咱们将用 TliedMap 编辑器来制做,也就是用 TMX 文件来建立。

乱入一个知识点:游戏中元素的层级关系由 z-order 属性来决定,咱们能够经过设置元素的z-order值来控制元素之间的渲染顺序。默认状况下,全部元素的 z-order 为0,因此当游戏元素没有指定z-order值时,游戏中的元素将按添加顺序来显示。故此,咱们在添加游戏背景或其余元素时,应该要注意下它们的添加顺序 或 z-order 值,不要出现遮挡的现象。api

建立BackgroundLayer背景层

为了让代码结构更加清晰,接下来咱们将为 GameScene 场景建立一个背景层,而后把以上的四层背景图都添加到该层上。
frameapp

因此,咱们在 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 局部型的类。工具

把背景层添加到GameScene场景

BackgroundLayer.lua 文件是个单独的模块文件,若是咱们想要引用它,那咱们须要把它加载到项目中来。ui

一般,载入文件到 Quick 项目可使用如下的两种方式:lua

  1. 经过require()方法,该方法会搜索指定的目录,并加载文件。
  2. 经过import()方法,该方法用于处理require同目录下其余模块,在模块名前加.。

它们的详细用法参见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] 后面。

gs

在此以后,须要添加不断执行 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 后,帧事件才会被触发。

此时咱们再用一样的方法添加近景背景(让它每次移动的距离大一些),运行游戏时,屏幕上就会出现滚循环移动的背景了。

bg

注:以上截图不是循环的。

最上层的TMX背景

背景层中还有一个重要的滚动项,那就是容纳了障碍物和奖励品的 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 文件后一并上传。

相关文章
相关标签/搜索