《Cocos Creator游戏实战》旋转循环页视图实现
旋转循环页视图实现
设置节点
编写代码
在这一节中我们实现一个类似旋转门的页视图(PageView)。
运行效果如下:
Cocos Creator版本:2.2.0
后台回复"旋转页视图",获取该项目完整文件:
设置节点
首先创建以下节点:
1. cardsNode为一个空节点,大小跟Canvas一样(我们之后会在该节点上设置触摸监听)。
2. card1-card6为cardNode的子节点,类型为Sprite,图片都在textures文件夹中:
现在我们把card1-card6节点的x坐标设置一下,将他们摆放在不同位置:
card1和card4是重叠的,其他card节点朝两边摆开。
注:因为节点顺序zIndex的关系,所以我们发现这里的遮挡关系其实不正确,之后需要在代码中调整。
编写代码
创建一个Revolve.js脚本文件,挂到cardsNode节点上,在onLoad方法中设置在各个位置上的card节点应有的属性:
// Revolve.js
onLoad () {this.attrArray = [JSON.stringify({zIndex: 3,scale: 1,opacity: 255,pos: this.node.children[0].position}),JSON.stringify({zIndex: 2,scale: 0.8,opacity: 180,pos: this.node.children[1].position}),JSON.stringify({zIndex: 1,scale: 0.5,opacity: 100,pos: this.node.children[2].position}),JSON.stringify({zIndex: 0,scale: 0.2,opacity: 30,pos: this.node.children[3].position}),JSON.stringify({zIndex: 1,scale: 0.5,opacity: 100,pos: this.node.children[4].position}),JSON.stringify({zIndex: 2,scale: 0.8,opacity: 180,pos: this.node.children[5].position}),];
},
attrArray变量是一个数组,其中的元素都为JSON类型。
我们拿第一个元素来讲解:第一个元素指的是在正当中(C位),玩家当前正在观看的那张card节点(注意不一定是card1,因为玩家会滑动屏幕,card节点会更换)。
zIndex:此时该节点的zIndex值应该是最大的,不能被其他节点所遮挡。
scale和opacity:节点大小和透明度为原始状态,所以scale值和opacity值为1。
pos:因为我们最开始摆放时,card1节点在正当中,所以card1最开始的位置就是C位卡片应有的位置。由于card1节点位置会在玩家滑动后发生改变,所以我们这里需要调用JSON.stringfy方法对元素进行字符串化。
其余的元素代表其他位置上card节点应有的属性状态。
现在在onLoad方法中添加如下代码对各个节点进行初始化:
// Revolve.js
onLoad () {...// 将cardsNode子节点的各个属性初始化this.cardsArray = this.node.children;for (let i=0; i<this.cardsArray.length; i++) {this.cardsArray[i].num = i;let initAttr = JSON.parse(this.attrArray[i]);this.cardsArray[i].zIndex = initAttr['zIndex'];this.cardsArray[i].scale = initAttr['scale'];this.cardsArray[i].opacity = initAttr['opacity'];// this.cardsArray[i].pos = initAttr['pos'];}
},
笔者这里给各个card节点加了一个num属性值,该值用来判断它们各自所处的位置,也就知道它们当前所应该呈现的属性状态。比如某节点num等于2的话,那么该节点的属性状态就对应为attrArray数组中的第3个元素。当然num值在玩家滑动后会发生改变。
运行后,效果如下:
接着我们要做的就是处理玩家滑动事件。在onLoad方法中添加触摸监听代码(只用监听touchmove就可以了):
// Revolve.js
onLoad () {...// 触摸监听this.node.on('touchmove', this.onTouchMove, this);
},
onTouchMove方法编写如下:
// Revolve.js
onTouchMove (event) {let deltaX = event.getDelta().x;if (deltaX > this.node.parent.width / 40) {// 说明是往右滑动this.revolve2Right();}else if (deltaX < -this.node.parent.width / 40) {// 说明是向左滑动this.revolve2Left();}
},
通过判断玩家横向滑动的距离来执行相应代码(this.node.parent就是Canvas)。
revolve2Right方法编写如下:
// Revolve.js
revolve2Right () {// 往右旋转for (let i=0; i<this.cardsArray.length; i++) {// 所有节点编号+1if (this.cardsArray[i].num < this.cardsArray.length-1)this.cardsArray[i].num += 1;elsethis.cardsArray[i].num = 0;// 获取目标属性let nextAttr = JSON.parse(this.attrArray[this.cardsArray[i].num]);// 改变z值this.cardsArray[i].zIndex = nextAttr['zIndex'];// 改变大小、透明度、位置let scaleAction = cc.scaleTo(this.revolveTime, nextAttr['scale']);let fadeAction = cc.fadeTo(this.revolveTime, nextAttr['opacity']);let moveAction = cc.moveTo(this.revolveTime, nextAttr['pos']);let spawnAction = cc.spawn(scaleAction, fadeAction, moveAction);spawnAction.setTag(1); // 设置动作标签this.cardsArray[i].runAction(spawnAction);}
}
如果向右滑动的话,那么所有card节点的num值加1,但注意num值最大如果超过cardsArray数组长度减1的话,就要归0(不然就超过数组下标临界值,获取不到元素了)。设置好num值后,我们就可以设置各个card节点的zIndex,scale,opacity和pos值了。revolveTime在properties中创建:
properties: {revolveTime: 0.8 // 旋转所需时间
},
大家可以发现笔者给spawnAction设置了一个tag,这个稍后会讲到。
rovolve2Left方法同理:
// Revolve.js
revolve2Left () {// 往左旋转for (let i=0; i<this.cardsArray.length; i++) {// 所有节点编号-1if (this.cardsArray[i].num > 0)this.cardsArray[i].num -= 1;elsethis.cardsArray[i].num = this.cardsArray.length-1;// 获取目标属性let nextAttr = JSON.parse(this.attrArray[this.cardsArray[i].num]);// 改变z值this.cardsArray[i].zIndex = nextAttr['zIndex'];// 改变大小、透明度、位置let scaleAction = cc.scaleTo(this.revolveTime, nextAttr['scale']);let fadeAction = cc.fadeTo(this.revolveTime, nextAttr['opacity']);let moveAction = cc.moveTo(this.revolveTime, nextAttr['pos']);let spawnAction = cc.spawn(scaleAction, fadeAction, moveAction);spawnAction.setTag(1); // 设置动作标签this.cardsArray[i].runAction(spawnAction);}
},
现在大家运行项目,滑动后发现界面变成了下面这个混乱的样子:
那是因为我们每次滑动,onTouchMove方法都被调用了好几次,而每次调用时各个card节点都会执行相应动作。问题是之前的动作都还没执行完毕,新的执行就又来了,所以才会导致以上情况出现。
解决办法就是在onTouchMove中先判断动作是否执行完毕。如果不是的话,直接return。
// Revolve.js
onTouchMove (event) {// 首先判断动作是否执行完for (let i=0; i<this.cardsArray.length; i++) {if (this.cardsArray[i].getActionByTag(1))return;}let deltaX = event.getDelta().x;if (deltaX > this.node.parent.width / 40) {// 说明是往右滑动this.revolve2Right();}else if (deltaX < -this.node.parent.width / 40) {// 说明是向左滑动this.revolve2Left();}
},
这里的重点就是getActionByTag方法。我们在revolve2Right和revolve2Left方法中给spawnAction设置了一个标签,如果spawnAction没有在执行(或者执行完毕),那么getActionByTag(1)就会返回null;而如果正在执行的话,就会返回一个object。
现在运行项目,旋转就正常了:
好,那今天的教程就到这,希望大家有所收获~
《Cocos Creator游戏实战》旋转循环页视图实现相关推荐
- 《Cocos Creator游戏实战》实现下拉框按钮ComboBox控件
实现下拉框按钮ComboBox控件 创建节点 编写脚本 该功能已收录在Many Widgets插件中,使用Cocos Creator 3.x版本的小伙伴可以用该插件快速生成下拉框ComboBox控件. ...
- 《Cocos Creator游戏实战》贪吃蛇平滑移动
贪吃蛇平滑移动 贪吃蛇平滑移动 初始化蛇头和蛇身 调整蛇头方向 贪吃蛇移动 蛇头和蛇身的节点顺序 添加食物 添加碰撞逻辑代码 从pointsArray中剔除无用的坐标点(更新) 在本教程中我们重点来学 ...
- 《Cocos Creator游戏实战》棋类游戏中的棋子摆放逻辑
棋类游戏中的棋子摆放逻辑 创建节点 代码编写 其实要点就一句话:我们看到的不应是棋盘,而是坐标. 现在通过下面的五子棋(或围棋)实例来看下如何理解这句话. 运行效果如下: Cocos Creator版 ...
- 《Cocos Creator游戏实战》摘星星进阶版
摘星星进阶版 添加开始按钮 实现按钮功能 显示"Game Over" 限制主角移动范围 让跳跃动作更加细腻 加入星星收集动画 编写动画脚本 加入触屏控制 添加游戏提示 Cocos ...
- 《Cocos Creator游戏实战》关卡功能实现
关卡功能实现 创建节点 设置关卡信息 实现关卡界面 为预制添加脚本 完善Game.js逻辑 在上一节教程中我们讲解了打砖块的主要功能与逻辑实现,在这一篇教程中,笔者会在它的基础上增加关卡功能(建议先阅 ...
- 《Cocos Creator游戏实战》老虎机抽奖效果实现思路
在线体验地址 Cocos Creator | SlotMachine Cocos Store 购买地址(如果没有显示,那就是还在审核): https://store.cocos.com/app/det ...
- 《Cocos Creator游戏实战》游戏转场时如何保留节点信息
游戏转场时如何保留节点信息 使用常驻节点 使用全局变量 使用本地存储 引擎同时只会运行一个场景,当切换场景时,默认会将场景内所有节点和其他实例销毁(本句来自Cocos Creator文档). 在这一节 ...
- 《Cocos Creator游戏实战》虚拟摇杆实现
虚拟摇杆实现 摇杆布局实现 摇杆功能实现 用摇杆控制主角 该功能已收录在Many Widgets插件中,使用Cocos Creator 3.x版本的小伙伴可以用该插件快速生成摇杆. 插件地址:http ...
- 《Cocos Creator游戏实战》新手引导实现
新手引导实现 新建节点 完成代码 该功能已收录在Many Widgets插件中,使用Cocos Creator 3.x版本的小伙伴可以用该插件快速生成新手引导. 插件地址:https://store. ...
最新文章
- java 冒泡排序和快速排序 实现
- 【斗医】【13】Web应用开发20天
- 春节后面试别人的经历总结之一,好岗位分享给还在找工作中的软件开发爱好者们【转】...
- django 不用自带的mysql_python笔记二 django自带后台管理系统、模版渲染以及使用mysql数据库...
- JavaScript 中 JSON.parse()和JSON.stringify()
- java之写接口回调编程经验改进
- oracle创建用户名了,oracle创建用户名
- .NET开发Silverlight程序:界面和对象模型
- asp.net文本编辑器FCKeditor使用方法详解 - 橙色大地 - 博客园
- es6之模块化(module)--绝对能看懂
- Mapreduce执行过程分析(基于Hadoop2.4)——(三)
- 【DB笔试面试1-100】
- 利用感应加热原理,3秒即可烧红铁棒!
- windows命令行工具
- 后端程序员福音 -- TellMe 推送助手
- python第一次作业
- ValueError: The view XXXView didn't return an HttpResponse object. It returned None
- 一个神奇的下载按钮css实现
- Openjudge:鸡尾酒疗法
- java基本语法实验体会_Java基本语法实验报告