Quick-Cocos2d-x初学者游戏教程12

上章我们讲解了物体之间的碰撞检测,而本章开始,我们将讲解触摸事件的实现,同时,我们还将给 Player 加上血量条。

需求说明

在开始之前,我们先来看看本节游戏的一些需求。

对于本教程游戏来说,我们的需求是在点击屏幕的时候,给 Player 一个向上的速度,让它能飞起来,否则它会受到重力的影响向下掉落。当掉落到地面上时,Player 会掉血,所以我们必须不停的点击屏幕以避免 Player 掉落到地上。在避免 Player 掉落的同时,我们还可以通过控制 Player 的飞起和降落来躲开障碍物和拾取心心。

游戏开始后 Player 精力充沛,有满满的血量,但当 Player 撞到障碍物和地面时,会根据碰撞到的类型来扣除不同点数的血量,当 Player 碰到心心时,可以增加一定的血量,并且会消除心心,消除的同时给它一个消除特效,这个特效用粒子系统来完成。Player 血量为0或地图跑外时,游戏结束。

需求分析清楚以后,下面我们就开始实现也上所描述的功能。

添加触摸事件

首先,我们来添加触摸事件。

触摸响应是游戏开发中一个很重要的模块,它是手游中玩家与游戏交互的主要途径。在 Quick 中,触摸事件机制是非常简单的,它允许任何一个 Node 接受触摸事件,而不局限于 Layer。

在我们的游戏中,我们需要在 Player 开始下落的时候启动触摸事件的响应,所以,我们将在 playerFlyToScene 函数的 startDrop 方法中启动触摸事件的响应,相关代码如下所示:

local function startDrop()
self.player:getPhysicsBody():setGravityEnable(true)
self.player:drop()
self.backgroundLayer:startGame()

self.backgroundLayer:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event)
return self:onTouch(event.name, event.x, event.y)
end)
self.backgroundLayer:setTouchEnabled(true)

end

这里,我们给 self.backgroundLayer 背景层添加了触摸事件的监听,其中 addNodeEventListener 方法用于注册系统事件的监听,如上所诉的触摸事件,以及帧事件、按键事件等等。

可能你会问:为什么是给 self.backgroundLayer 添加触摸事件的监听呢,为什么不是 self 场景自身,或者 Player?这里我们需要解释一下的是:触摸响应不能直接给 scene 添加事件监听,而如果只给 Player 添加触摸监听,那么我们只能在 Player 这个很小的范围内响应到触摸事件,所以我们需要用一个层来完成。在游戏中又只创建了一个背景层,所以我们就将就着把触摸事件的监听添加到它身上。当然,你也可以新建一个层来添加触摸监听,这里我们就不那么讲究了!

setTouchEnabled 方法用于开启触摸功能,如果 setTouchEnabled(false),那么背景层将不能接受到触摸响应。

另外,onTouch 方法是触摸事件回调,其定义如下:

function GameScene:onTouch(event, x, y)
if event == "began" then

self.player:flying()
self.player:getPhysicsBody():setVelocity(cc.p(0, 98))

return true
-- elseif event == "moved" then

elseif event == "ended" then
self.player:drop()
-- else event == "cancelled" then
end
end

因为我们要实现点击屏幕就给 Player 一个向上的速度,不点的时候 Player 向下掉落。所以,这里我们只需在触摸开始时,让 Player 处于飞行状态且给它一个方向向上的速度(0, 98);在触摸结束时,让 Player 下落就可以了。而不必去考虑在触摸移动 "moved" 和触摸取消 "cancelled" 时的状态。

还有一点要注意的是:在触摸开始时,必须返回 true,不然之后的 "ended" 等消息将不会被响应。

添加血条

接下来我们来给 Player 添加血量条,这可以用引擎中已经封装好的进度条(ProgressTimer)来实现。

以下是在 Player 中添加的相关代码,我们先来看看。

function Player:createProgress()
self.blood = 100 -- 1
local progressbg = display.newSprite("#progress1.png") -- 2
self.fill = display.newProgressTimer("#progress2.png", display.PROGRESS_TIMER_BAR) -- 3

self.fill:setMidpoint(cc.p(0, 0.5)) -- 4
self.fill:setBarChangeRate(cc.p(1.0, 0)) -- 5
-- 6
self.fill:setPosition(progressbg:getContentSize().width/2, progressbg:getContentSize().height/2)
progressbg:addChild(self.fill)
self.fill:setPercentage(self.blood) -- 7

-- 8
progressbg:setAnchorPoint(cc.p(0, 1))
self:getParent():addChild(progressbg)
progressbg:setPosition(cc.p(display.left, display.top))
end

function Player:setProPercentage(Percentage)
self.fill:setPercentage(Percentage) -- 9
end

其中 createProgress 方法的作用是添加一个进度条,setProPercentage 方法的作用是设置进度条的百分比。下面我们一一讲解下代码:

  1. 添加血量属性 self.blood,这里初始值我设为了 100,这样我们后面就可以根据血量来设置进度条的百分比了(懒人做法)。
  2. 给进度条创建一个底,也就是在进度条的下面放一个背景,这样当进度条逐渐变短时,用户可以更直观的看到它减少了多少。
    进度条背景和进度条图片分别如下所示:
    progress1 progress2
  3. 创建进度条 self.fill,display.newProgressTimer 方法的两个参数分别表示创建进度条所用的图片,以及进度条的类型。引擎中进度条的类型有两种:

    • display.PROGRESS_TIMER_BAR:条形,这种类型的进度条通常用于创建类似生命条,等级条的一类进度条。
    • display.PROGRESS_TIMER_RADIAL:环形,它通常用于创建类似加载功能的进度条,比如游戏加载资源时页面上旋转的菊花(PS:词穷,就是菊花吧,不要想歪)。
  4. 设置进度条的起始点,(0,y)表示最左边,(1,y)表示最右边,(x,1)表示最上面,(x,0)表示最下面。
  5. 设置进度条变化方向,如果不用变化的方向,则设置该方向为0,否则设置为1。所以(1,0)表示横方向,(0,1)表示纵方向。
  6. 把进度条的位置设置在 progressbg 上,并将进度条添加到 progressbg 上。
  7. 调用 ProgressTimer 的 setPercentage 方法设置进度条的百分比为 100%(因为 self.blood 的值为100)。
    ProgressTimer 类有一个很最要的percentage属性。它代表当前进度条的进度值。其中 setPercentage 方法能设置 ProgressTimer 的 percentage 值。
  8. 把 progressbg 加入屏幕的左上角。这里做了三件事:
    • 首先要把 progressbg 的锚点设置到它的左上角,锚点这个概念我忘了前面讲没讲过了,这里还是简单说明一下。
      锚点的两个参数在0~1之间。一般节点的锚点默认值都是(0.5, 0.5),也就是在节点的最中间。(0, 1)就表示左上角,将一个节点添加到父节点里面时,需要设置节点在父节点上的位置,其本质上就是设置节点的锚点在父节点坐标系上的位置。
    • 接着,我们把 progressbg 加到了 Player 的父节点上,这里也就是 GameScene 场景中。这样,进度条才不会随着 Player 的移动而移动了。
    • 最后,这里我们把 progressbg 放到屏幕的左上角。 anchor
  9. setProPercentage 是我们来设置进度条百分比的。

好了,以上创建血条的代码段应该讲解的够清楚了吧,接下来我们需要做的就是在合适的地方调用它。这里我们在 GameScene 中调用:

self.player = Player.new()
self.player:setPosition(-20, display.height * 2 / 3)
self:addChild(self.player)
self:playerFlyToScene()

self.player:createProgress() -- here

此刻,运行游戏,我们就可以看到如下的效果了。

smallw

好了,本章就到处为止,下章将是我们教程的最后一章,大家期待的完整代码将放出,敬请期待吧。

转载请注明出自:http://shannn.com/archives/437

标签: none

?>