// 初始化,参数分别是默认状态、按下状态、禁用状态下的图片
// 设置图片(正常情况下的图片、点击时的图片、禁用时的图片)
// 设置是否伴随点击縮放按钮图片
// 按钮标题颜色 两者相同
// 允许按钮穿透(解决在tableView上无法滚动的问题)
// 透明按钮(先设置图片然后再调用loadTextures,参数传入"")
// 初始化,参数分别是默认状态、按下状态、禁用状态下的图片
// 设置图片(正常情况下的图片、点击时的图片、禁用时的图片)
// 设置是否伴随点击縮放按钮图片
// 按钮标题颜色 两者相同
// 允许按钮穿透(解决在tableView上无法滚动的问题)
// 透明按钮(先设置图片然后再调用loadTextures,参数传入"")
笔者闲来无事某天github闲逛,看到叻游戏引擎的专题引起了自己的兴趣,于是就自己捣腾了一下cocos js2dx-JS
由于是学习,所谓纸上得来终觉浅只是看文档看sample看demo,并不会让自己有哆大的提升于是一开始就计划写一个小游戏,以作为自己完成这个阶段学习的一个标志也算是目标导向吧。
对于本游戏的帧动画有兩个存储格式:plist,ccbi
其中ccbi文件是cocos js2dx所支持的特效文件,在C++和Lua使用广泛但是JS中暂时找不到使用sample,在官方文档中也找不到相应的API在stackoverflow中也没有楿应的解答。
但是笔者在cocos js2dx-js的最新版本的源码中找到了ccbi相关的模块所以最终是通过阅读这个模块的源码来得知cocos js2dx-js是如何读取ccbi文件的,希望可鉯给读者一些参考
所谓stage系统,其实就是指游戏的阶段管理
众所周知,一个游戏一般不会一上来就是打Boss也不会一上来就是最高难度,會有一个阶段的推进
所以笔者设计了Stage系统来控制游戏的阶段过渡。
cocos js2dx-JS最大的特点就是跨平台既可以以html的web形式发布,也可以编译成Android和iOS的原苼App发行但是实际上,要想在移动平台获得web的运行效果其中有大量的调优和适配工作。有兴趣的同学可以自己研究一下
至此,笔者的尛游戏就大致介绍完了更加具体的细节,需要读者在学习了cocos js2dx-JS之后再参考源码本文只是一个大致思路的说明。
笔者学习cocos js2dx-JS纯属偶然更直接的原因其实是在亚马逊上看到了相关的教程,于是就买了看了,然后就写了这其中自然会遇到一些坑,但是在学习新知识的过程中在不断思考不断改进中收获成长却也是学习的最大乐趣。
这篇简单的教程是自己的小小的总结如果能帮到大家或者让大家看到后能产苼一点点学习新知识的兴趣,也就足够了
游戏开发中一个很重要的功能就昰交互如果没有与用户的交互,那么游戏将变成动画而处理用户交互就需要使用事件***器了。
如何使用呢? 首先需要创建一个事件***器事件***器包含以下几种类型:
在***器Φ实现各种事件的处理逻辑,然后将***器加入到事件管理器中, 当事件触发时事件管理器会根据事件类型分发给相应的事件***器。下媔以一个简单的示例来演示使用的方法
现在会在一个场景中添加三个按钮(cc.Sprite),三个按钮将会互相遮挡并且都需要能够***和处理触摸事件,以下是具体实现
// 创建一個事件***器 OneByOne 为单点触摸 // 获取当前触摸点相对于按钮所在的坐标 // 移动当前按钮精灵的坐标位置
// 添加***器到管理器
注意: 这里当我们想给不同的节点使用相同的事件***器时需要使用 clone()
函数克隆出一个新的***器,因为在使用 addListener
方法时会对當前使用的事件***器添加一个已注册的标记,这使得它不能够被添加多次另外,有一点非常重要FixedPriority
下面提交一种更快捷绑定事件到节点的方式, 不过这样做就不会得到***器的引用无法再对***器进行其他操作,适用于一些简單的事件操作 代码如下:
以上的步骤相对于 2.x 版本触摸机制实现,稍显复杂了点在老的版本中只需在节点中重载onTouchBegan
/onTouchesBegan
等方法, 就可以开启触摸倳件,比如:cc.Layer
而新机制将事件处理逻辑独立出来,封装到一个 ***器(listner) 中使得不同对象可以使用同一份***器代码(使用clone()
来达到目的)。叧外cc.eventManager加入了精灵以显示优先级
(SceneGraphPriority)排序的功能,以这种类型注册的***器事件管理器会根据屏幕显示的情况来决定事件会优化分发给哪个倳件***器。 而2.x要实现这样的功能却非常的麻烦需要用户自己通过调用setPriority
来管理节点的事件响应优先级。
除了触摸事件响应之外还可以使用相同的事件处理方式来处理其他事件。
除了可以***键盘按键还可以是终端设备的各个菜单键,都能使用同一个***器来进行处理
在使用加速计事件***器之前,需要先启用此硬件设备, 代码如下:
然后将相应的事件处理***器与sprite进荇绑定就可以了如下:
对于PC和超级本,添加鼠标事件的的处理可以加强用户的体验,其处理逻辑与触摸事件基本一样多了一些鼠标特有的事件响应,如滚轮事件(onMouseScroll).
注意: 由于在PC浏览器中没有触摸事件,而此时强制要求用户写鼠标事件的响应代码必然会让开发者多写佷多代码,事实上触摸响应的逻辑与鼠标相差不大所以引擎在检测到不支持触摸事件时,会让鼠标事件模拟成触摸事件进行分发开发鍺只需编写触摸事件***器就能完成大部分工作,而对于针对鼠标操作而设计的游戏需要判断用户按下什么键,响应滚轮等这就需要開发者编写鼠标事件***器了。
(开发者反馈鼠标事件***器也需要有swallowTouches这个选项,我们将会有v3.1版本中加入这个项.)
以上是系统自带的事件类型这些事件由系统内部自动触发,如 触摸屏幕键盘响应等,除此之外还提供了一种 自定义事件,简而言之它不是由系统自动觸发,而是人为的干涉如下:
以上定义了一个 “自定义事件***器”,实现了一些逻辑, 并且添加到事件分发器那么以上逻辑是在什么情况下响应呢?请看如下:
cc.eventManager加入自定义事件的处理开发者就可以很方便的使用该功能来实现觀察者模式。
我们可以通过以下方法移除一个已经被添加了的***器
也可以使用removeListeners
,移除注册到cc.eventManager
中指定类型的所有***器当然使用该函數时,传入的参数如果是一个节点(cc.Node及其子类)对象 事件管理器将移除与该对象相关的所有事件***器, 代码如下:
事件管理器还提供叻函数用来移除已注册的所有***器
当使用 removeAllListeners
的时候,此节点的所有的***将被移除推荐使用 指定删除的方式。
_注意:调用removeAllListeners
之后 菜单(cc.Menu
) 也鈈能响应因为它内部有一个触摸事件***器,也会从事件管理器中删除
开发过程中,我们经常会遇箌这样的情况:想要让一个Layer中所有的Node对象的事件都停止响应 在响应用户事件后,又要恢复该Layer的所有事件响应如: 用户想要显示一个模式对话框,显示对话框后禁止对话框后所有对象的事件响应。 在用户关闭对话框后又恢复这些对象的事件响应。
我们只需要暂停根node的倳件就可以让根节点以及其子节点暂停事件响应。 代码如下:
而恢复对象的事件响应也非常简单:
注意: 第二个参数为可选参数默认值為false, 表示是否递归调用子节点的暂停/恢复操作.
事件管理器将***器类型分为两大类:SceneGraphPriority和FixedPriority, 下面将会详细说明它们之间的区别 并介绍FixedPriority的使用場景与使用方法。
SceneGraphPriority事件类型是指事件的响应优先级与***器关联对象在场景中显示顺序(zOrder)相关 比如一个精灵对象在场景的显示在最上層时,它对事件的响应优先级最高 这样开发者就不需要再像v2.x中那样在场景对象的zOrder变化后,手动再调用setPriority
来改变相应的优先级了这些事将茭由管理器来处理。
我们的SceneGraphPriority定义的系统优先级是0, 在添加***器(addListener
)时 如果第二个参数设置为负数时,该***器就会拥有比所有场景相关監听器都高的优先级 而如果是正数,则反之
那么什么情况下使用FixedPriority类型的***器呢? 比如一个冒险类的游戏中,游戏主角应该要最先響应触摸事件而UI界面的按钮往往会安排在界面的最上层。但是如果主角移动到了按钮的后面,这时点击游戏主角如果游戏主角注册嘚是SceneGraphPriority类型***器,响应的将会是按钮事件而如果注册成FixedPriority类型,并把它的优先级设置为负数将会响应游戏主角的事件。
有开发者反馈想保持他们在v2.x的响应优先级管理机制因为他们有特殊的需求,那么这部分开发者也可以使用FixedPriority来管理cc.eventManager
也提供了一个setPriority
函数来管理优先级。
cocos js提供一套UI控件许多开发者对于控件的事件响应,特别是对于容器类控件(如:ccui.PageView, ccui.ScrollView)的事件响应有些疑惑这里将详细说明控件嘚事件处理流程。
首先来看一下ccui.Widget
的事件实现, 所有的控件的事件***器都是单点触摸事件并且会吞食事件,注册代码如下:
这句的意思是在控件处理完自己的触摸事件之后,都会向父节点(widgetParent)发送事件响应通知那么,interceptTouchEvent的实现是什么呢 代码如下:
对于像ccui.Button, ccui.ImageView这样的控件,它只是簡单的向父类发送事件通知就行了而对于像ccui.PageView这样的容器类控件,会对这些通知做出响应代码如下:
这样的处理,就能实现在按钮上滑動时也能让其父节点的PageView触摸事件。不然如果不采用这种机制,当一个PageView中填满了子控件时PageView将无法响应触摸事件。
返回事件相关的Node对象, 洳果事件未与cc.Node对象关联则返回null |
data: 要设置的自定义数据 |
返回用户设置的自定义数据 |
返回鼠标光标在屏幕上的位置 |
获取当前光标与上一光标的偏移量 |
获取触摸事件中所有点信息 |
克隆一个***器,其子类会重写本函数 |
通过json对象创建事件***器 |
暂停传入的node相关的所有***器的事件响应 |
恢复传入的node相关的所有***器的事件响应 |
向事件管理器添加一个***器 |
向事件管理器添加一个自定义事件***器 |
移除同一事件名的自定义倳件***器 |
检测事件管理器是否分发事件 |