quick-cocos2d-x 学习系列之六 CoinFlip

下面我们来看一个很完整的例子,CoinFlip,这个DEMO已经非常完整可以直接用来玩耍了。

代码路径:.. \quick\samples\coinflip

这个游戏还是很益智的。

1.代码逻辑

开始部分基本和其他的都一致,从main.lua文件进入,到达MyApp.lua文件中。(MyApp继承于cc.mvc.AppBase)

主要函数是run,enterMenuScene,enterMoreGamesScene,enterChooseLevelScene,playLevel

(程序逻辑结构比之前略微复杂一点:有多个文件夹data,scenes,ui,views.

其中data用来存放关卡信息,ui是UI相关文件,scenes是4个场景文件,views是显示相关的函数和类)

1.1.1Run

该函数会增加程序搜索路径 res文件,加载游戏的相关PNG文件,加载声音文件,然后调用程序self:enterMenuScene().

2.1.1enterMenuScene

该函数调用如下:

self:enterScene("MenuScene",nil,"fade",0.6,display.COLOR_WHITE)

这个enterScene函数是继承自父类的。

直接进入到MenuScene场景中,该场景定义在文件 app/scenes/MenuScene.lua文件中。

3.1.1nterMoreGamesScene

该函数调用如下:

self:enterScene("MoreGamesScene",display.COLOR_WHITE)

其他同上

4.1.1enterChooseLevelScene

该函数调用如下:

self:enterScene("ChooseLevelScene",display.COLOR_WHITE)

其他同上

5.1.1playLevel

该函数调用如下:

self:enterScene("PlayLevelScene",{levelIndex},display.COLOR_WHITE)

其他同上

2.MenuScene

导入其他函数如下:

local AdBar = import("..views.AdBar")

local BubbleButton = import("..views.BubbleButton")

游戏开始后的第一个场景,即菜单场景。

代码都在ctor函数中(构造函数)

增加背景图片,设置两个BUTTON。

一个开始,一个关于更多游戏。

点击开始后,进入选择LEVEL的场景

点击更多游戏后,进入MoreGamesScene场景

注:此处有个BUG,如果点击完开始后,立马点击更多游戏的按钮,程序会死掉,这个就交个小伙伴们自己去修正吧。

4.1BubbleButton

定义了一个函数用于创建BUTTON,该BUTTON 带果冻样的特效,看上去很专业的,最后返回BUTTON,该文件核心也是实现这果冻效果(主要是简单动作把握时间进行合成)。

3.MoreGamesScene

这个场景只有一个ctor构造函数,实现了背景图片添加,

一个测试BAR的添加,最后是一个返回按钮增加。

注:BAR在views/AdBar.lua文件夹中。

4.ChooseLevelScene

这个LEVEL选择的场景当前在很多流行的游戏中管用的伎俩,应该说是手段,不过基本都是大同小异的。

该场景的主要函数还是其构造函数,ctor,此外还有两个函数分别是onTapLevelIcon,onEnter

还导入了两个其他功能块(这样实现功能解耦)

local AdBar = import("..views.AdBar")

local LevelsList = import("..views.LevelsList")

4.2Ctor

首先是添加一个背景图片,增加一个TITLE,一个测试的BAR。

创建一个矩形,通过矩形创建LevelsList,为其添加监听onTapLevelIcon。

最后创建一个BACK按钮。

注:主要是LevelsList,在views/LevelsList.lua文件中。

4.2.1LevelsList

先导入了3个其他文件如下:

local LevelsListCell = import(".LevelsListCell")

local Levels = import("..data.Levels")

local PageControl = import("..ui.PageControl")

定义一个LevelsList类,继承于PageControl,PageControl继承与ScrollView.

该类是所有关卡的集合,按页分开。

定义了一个常量

LevelsList.INDICATOR_MARGIN = 46(指示关卡页的黑点间距)

每个关卡页存放4X4=16个关卡。如果高度大于1000,则存放5行。

此外主要是3个函数,ctor,scrollToCell,onTapLevelIcon.

Ctor是构造函数

调用父类的构造函数LevelsList.super.ctor(self,rect,PageControl.DIRECTION_HORIZONTAL)

通过总关卡数量除以每页行数和列数计算得到总共页数。

设置每页的最后一个关卡,如果超过总关卡数则设置为实际最后关卡。

然后通过LevelsListCell 类将页填满,以此往复。

然后设置页下方的小点点,起到提示用户当前在哪个关卡页面上。

在表示第一页的小点上增加实心图片,然后循环增加空心图片如下:

local x = (self:getClippingRect().width - LevelsList.INDICATOR_MARGIN * (numPages - 1)) / 2

local y = self:getClippingRect().y + 20

self.indicator_ = display.newSprite("#LevelListsCellSelected.png")

self.indicator_:setPosition(x,y)

self.indicator_.firstX_ = x

for pageIndex = 1, numPages do

local icon = display.newSprite("#LevelListsCellIndicator.png")

icon:setPosition(x,y)

self:addChild(icon)

x = x + LevelsList.INDICATOR_MARGIN

end

scrollToCell

调用父节点的scrollToCell函数。

然后移动实心图片到实际的显示的页面上。

onTapLevelIcon函数就一条语句如下

self:dispatchEvent({name ="onTapLevelIcon",levelIndex = event.levelIndex})

分发onTapLevelIcon时间,参数为levelIndex = event.levelIndex。

4.2.2PageControl

导入了文件local ScrollView = import(".ScrollView")

类继承于ScrollView(该类定义与ScrollView.lua文件中)

主要实现函数onTouchEndedWithoutTap

局部变量offsetX,offset,index,count

根据direction变量,进行处理滑动关卡页面操作。

4.2.3ScrollView

定义了ScrollView类,初始化需要一个RECT矩阵参数,如果没有则矩阵参数为(0,0)

通过该矩阵创建一个剪切区域。

通过如下命令增加组件:

cc(node):addComponent("components.behavior.EventProtocol"):exportMethods()

初始化函数中,定义了一些变量,

self.dragThreshold = 40 --拖动上限

self.bouncThreshold = 140 --滑动关卡页面的最大值,参看setContentOffset

self.defaultAnimateTime = 0.4 –默认动画时间

self.defaultAnimateEasing = "backOut" –默认动画效果

self.direction = direction

self.touchRect = rect

self.offsetX = 0

self.offsetY = 0

self.cells = {}

self.currentIndex = 0

添加NODE的事件监听,

self:addNodeEventListener(cc.NODE_EVENT,function(event)

if event.name == "enter" then

self:onEnter()

elseif event.name == "exit" then

self:onExit()

end

end)

此外创建一个触摸层,对其增加触摸监听,调用onTouch函数。

self.view = display.newLayer()

self:addChild(self.view)

self.view:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)

return self:onTouch(event.name,event.x,event.y)

end)

onTouch函数中,进行多种情况 处理,按下,移动,弹起。

按下后调用:onTouchBegan

移动后调用:onTouchMoved

弹起后调用:onTouchEnded

其他则调用:onTouchEnded

函数getCurrentCell 获取当前所在的关卡。

Addcell函数增加一个包含关卡的页面到可视的view层中,该函数调用reorderAllCells函数。

LevelsList直接调用了Addcell函数。

reorderAllCells函数,处理CELLS的页面在view中的排序,会设置变量currentIndex变量的值,该变量指定当前触摸页面的数量,都按规则排放在views这个层上。

该类中比较复杂的应该是触摸函数的处理:

l 有触摸函数:

a)onTouch

该函数在触摸开始就调用,如果没有关卡就退出,也就没有后文了。如果是刚按下那么判断是否在可触摸范围当中,不在则返回FALSE退出触摸,如何在其中则调用onTouchBegan函数,其参数为按下的坐标。如果不是刚按下,则调用onTouchMoved即可处理鼠标移动。

如果触摸结束则调用函数onTouchEnded,如果是其他则调用函数onTouchCancelled

b)onTouchBegan

设置拖动的起点,设置isTap为True(每次开始触摸都会设置为True,滑动后就变为FALSE了,防止滑动后还进入某个关卡)

通过函数getCurrentCell获取当前的cell.

调用CELL本身的onTouch 函数(这个函数就在LevelsListCell.lua 文件中了,实现按钮变化)。

c)onTouchMoved

获取当前的CELL,根据水平还是垂直,再判断超过临界值dragThreshold,是否isTrap,后进行调用setContentOffset 进行处理实时滑动,否则调用CELL的onTouch.

d)onTouchEnded

如果设置了isTrap则调用函数onTouchEndedWithTap

如果没有设置,则调用函数onTouchEndedWithoutTap。

e)onTouchCancelled

该函数值只将self.drag变量设置为nil。

其他相关的函数

f)onTouchEndedWithTap

该改用调用cell本身的的onTouch和onTrap函数。

Cell本身的onTrap函数实现self:dispatchEvent({name= "onTapLevelIcon",levelIndex = button.levelIndex})事件分发,由LevelsList类中的onTapLevelIcon函数处理再一次分发,最后由ChooseLevelScene:onTapLevelIcon(event)函数处理,实现进入到具体关卡的作用

这个函数就是不滑动关卡页面的处理。

g)onTouchEndedWithoutTap

在PageControl.lua文件中被重写。这个函数就是滑动关卡页面的处理。

根据判断进行滑动,调用scrollToCell函数,该函数会调用setContentOffset函数。

处理滑动页面情况。实际最后接手的函数依旧是setContentOffset。此时是带有动画效果的。

h)setContentOffset

处理实时滑动效果,根据水平、垂直,设置实时坐标值,不能超过上下限,最后设置位置,如果有动画则进行播放。

此处传入的参数是offset,该参数会被复制给self.offsetX进行保存。

该参数每次触摸开始的时候赋值给self.drag.currentOffsetX.

在传递给setContentOffset函数的时候发生变化,同时保存给self.offsetX进行保存。

4.2.4ScrollViewCell

创建一个类ScrollViewCell,通过给定的大小创建一个Node.

为该node增加组件如下:

cc(node):addComponent("components.behavior.EventProtocol"):exportMethods()

该类是一个触摸单元类。

4.2.5LevelsListCell

该类继承于ScrollViewCell,是一个滑屏单元类。通过屏幕本身大小定义

rowHeight 屏幕高度-340 除以总行数

colWidth 屏幕宽度乘以0.9, 除以总列数得到。

pageIndex是关卡的当前页数。

页开始的X和,Y 根据显示屏幕计算的得到。

beginLevelIndex,endLevelIndex在构造函数中的参数。

根据一页能够容纳的BUTTON数量,卡的BUTTON,其中给BUTTON增加一个LABEL表示关卡等级。

该类中定义了函数onTap函数,根据点击位置返回BUTTON,最重要的是该函数进行了时间“onTrapLevelIcon”分发。(BUTTON是一个表结构,有一个图片和levelIndex变量)

(该类主要的都是在本身自己类中完成的,其父类主要的工作是如下代码

local node = display.newNode()

if contentSize then node:setContentSize(contentSize) end

node:setNodeEventEnabled(true)

cc(node):addComponent("components.behavior.EventProtocol"):exportMethods()

return node

4.2.6Levels

定义了关卡信息如:

Levels表结构

levelsData 表结构

函数numLevels()

get(levelIndex)

4.3onTapLevelIcon

是levelsList 的onTapLevelIcon事件回调函数(该事件由LevelsListCell类中onTap函数分发,不过具体分发时间是由ScrollView类中的onTouchEndedWithTap函数调用),播放按钮声音,然后调用app:playLevel函数进入到选择的游戏场景中。

4.4onEnter

该函数在构造函数执行完毕后执行,在此主要是使能按钮。

5PlayLevelScene

先倒入其他的功能模块:

local Levels = import("..data.Levels")

local Board = import("..views.Board")

local AdBar = import("..views.AdBar")

Levels.lua文件中定义了各个关卡的数据,可以设置关卡几乘几,关卡初始化条件。

一个背景图片,一个TITLE,一个测试BAR,关卡级别的LABEL显示。游戏的BORAD,一个返回的BUTTON。

游戏中增加了self.board:addEventListener("LEVEL_COMPLETED",handler(self,self.onLevelCompleted))对事件监听,当胜利时会发出该事件消息,然后

PlayLevelScene:onLevelCompleted函数进行处理。

注:BOARD在 views.Board.lua文件中定义。

BOARD中有核心逻辑

5.1Board

导入如下文件

local Levels = import("..data.Levels")

local Coin = import("..views.Coin")

获取游戏关卡变量grid,rows,cols

计算得到offsetX,offset

摆放金币背景精灵。判断当前位置是否为空,不为空则创建一个金币。

将金币存放到coins数组中。使能触摸,创建触摸监听。

onTouch函数将金币进行反转。

这个度量常数是padding = NODE_PADDING /2

flipCoin函数可以同时将隔壁金币进行反转。

flipCoin函数会进行关卡检测是否完毕。

5.2Coin

定义了一个Coin类,该类根据初始化正反面创建图片,还有一个isWhite变量。

还有一个重要函数Coin:flip,该函数中定义了一个动画,根据isWhite设置动画方向,即翻转的动画。

同时设置isWhite变量反转。

6个别函数说明

self.levelsList:addEventListener("onTapLevelIcon",self.onTapLevelIcon))

将 Lua 对象及其方法包装为一个匿名函数。

格式:

函数 = handler(对象,对象.方法)

在 quick-cocos2d-x 中,许多功能需要传入一个 Lua 函数做参数,然后在特定事件发生时就会调用传入的函数。例如触摸事件、帧事件等等。

Quick-Cocos2d-x中自定义事件

官网查看地址:

http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/manual/framework/quick/V3/events/zh.md

·addEventListener

·removeEventListener

·removeAllEventListenersForEvent

·removeAllEventListeners

cc(node):addComponent("components.behavior.EventProtocol"):exportMethods()

该句为node类添加了扩展的事件处理方法,现在我们可以使用EventProxy中的函数了,通过这些函数我们可以让cc(node)接收到自定义的消息然后进行处理。

分发事件“addCell”

self:dispatchEvent({name = "addCell",count =#self.cells})

display.addSpriteFrames()

display.addSpriteFrames(plistFilename,image,handler)

将指定的 Sprite Sheets 材质文件及其数据文件载入图像帧缓存。

格式:

display.addSpriteFrames(数据文件名,材质文件名)

cc.rect

实际参数是 x,y,width,height

坐标X,Y,宽和高。实际使用如下:

local rect = cc.rect(display.left,display.bottom+ 180,display.width,display.height - 280)

display.newBatchNode()

display.newBatchNode(image,capacity)

从指定的图像文件创建并返回一个批量渲染对象。

local imageName = "Sprites.png"

display.addSpriteFrames("Sprites.plist",imageName) -- 载入图像到帧缓存

-- 下面的代码绘制 100 个图像只用了 1 OpenGL draw call

local batch =display.newBatch(imageName)

for i = 1,100 do

local sprite = display.newSprite("#Sprite0001.png")

batch:addChild(sprite)

end

-- 下面的代码绘制 100 个图像则要使用 100 OpenGL draw call

local group = display.newNode()

for i = 1,100 do

local sprite = display.newSprite("#Sprite0001.png")

group:addChild(sprite)

end

Parameters

stringimage图像文件名

integercapacity

reorderChild

reorderChild有两个参数如下图

Child 是准备添加的节点,zOrder 是cocos2d 里面的 z 值

这个函数意思就是根据新的 zOrder 重新排序 child 优先级

例如在一个 layer(场景)里面添加了一个图片,已经设置好了这个图片的绘制优先级,由于某种情况,这个优先级存在一定的问题,想修改一下这个图片的优先级。这个时候我就不用先使用layer(场景)

调用removeFromParentAndCleanup(boolcleanup);然后再addChild(Node * child,int zOrder);这么麻烦了

transition.playAnimationOnce()

transition.playAnimationOnce(target,animation,removeWhenFinished,onComplete,delay)

在显示对象上播放一次动画,并返回 Action 动作对象。

7逻辑拓扑图



quick-cocos2d-x 学习系列之六 CoinFlip的更多相关文章

  1. HTML5 input新增type属性color颜色拾取器的实例代码

    type 属性规定 input 元素的类型。本文较详细的给大家介绍了HTML5 input新增type属性color颜色拾取器的实例代码,感兴趣的朋友跟随脚本之家小编一起看看吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amazeui模态框弹出后立马消失并刷新页面

    这篇文章主要介绍了amazeui模态框弹出后立马消失并刷新页面,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. 移动HTML5前端框架—MUI的使用

    这篇文章主要介绍了移动HTML5前端框架—MUI的使用的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. AmazeUI 模态窗口的实现代码

    这篇文章主要介绍了AmazeUI 模态窗口的实现代码,代码简单易懂,非常不错,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. ios – 仅在异步函数完成执行后运行代码

    所以,例如:如果问题是你不知道要调用什么函数,你可以配置你周围的函数/对象,这样有人可以给你一个函数,然后你在我上面说“调用函数”的地方调用你的函数.例如:

  7. ios – 如何使用Objective C类中的多个参数调用Swift函数?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  8. ios – UIPopoverController出现在错误的位置

    所以我花了一些时间寻找答案,但到目前为止还没有找到任何答案.我正在尝试从UIInputAccessoryView上的按钮呈现弹出窗口.UIBarButtonItem我想显示popover来自定制视图,所以我可以使用图像.我创建这样的按钮:当需要显示popover时,我这样做:但我得到的是:弹出窗口看起来很好,但它应该出现在第一个按钮上时出现在第二个按钮上.然后我发现了这个问题:UIBarButto

  9. ios – 关闭UIBarButtonItem上的突出显示

    我正在尝试使用UIBarButtonItem在我的UIToolbar上添加标题.我使用简单的风格,看起来很好,但我似乎无法让它停止突出显示触摸.“突出显示时触摸”选项不适用于条形按钮项目.有没有快速简便的方法来做到这一点?

  10. ios – 使用带有NodeJs HTTPS的certificates.cer

    我为IOS推送通知生成了一个.cer文件,我希望将它与NodeJSHTTPS模块一起使用.我发现HTTPS模块的唯一例子是使用.pem和.sfx文件,而不是.cer:有解决方案吗解决方法.cer文件可以使用两种不同的格式进行编码:PEM和DER.如果您的文件使用PEM格式编码,您可以像使用任何其他.pem文件一样使用它(有关详细信息,请参见Node.jsdocumentation):如果您的文件使

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部