创建节点
滚动原理
编写脚本
本节我们来实现数字滚动的效果。
运行效果如下:
Cocos Creator版本:2.2.0
公众号后台回复"滚动数字",获取完整项目源码:
在层级管理器中我们创建以下节点:
number_layout节点:
注:水平和垂直布局的缩放模式(Resize Mode)都为CONTAINER。
此时场景编辑器显示如下:
注:节点的坐标大家可以自己摆放,或者打开笔者的项目查看,这里就不再截图。
其实数字滚动的原理非常简单,就是改变number_layout节点的y坐标。
我们先给all_layout加上Mask组件,把其余的数字或"."符号先遮住:
注:若要添加Mask节点,须将节点上的Sprite组件先移除。
那现在笔者把number_layout节点的y坐标变大,也就是让整个节点往上走,显示出来的就是比5大的数字了:
同理,如果笔者把y坐标变小,显示的就会是比5小的数字。
number_layout代表的就是数字上某一位,如果要表示多位数,那么我们只用多创建几个number_layout就行了(自然而然想到应该把number_layout变为预制)。
我们创建一个名称为Roll.js的脚本,在properties中添加如下属性:
// Roll.js
properties: {
numLayoutPrefab: cc.Prefab,
allLayoutNode: cc.Node,
editNode: cc.Node,
rollTime: 2,
},
在onLoad方法中我们编写如下代码:
// Roll.js
onLoad () {
// 节点池
this.prefabPool = new cc.NodePool();
// 预制数组,方便管理
this.prefabArray = [];
// 获取每个数字长度,用于获取y坐标
let numLayout = cc.instantiate(this.numLayoutPrefab);
this.eachHeight = numLayout.height / 11;
this.prefabPool.put(numLayout);
},
现在我们实现getNumStr方法来获取输入框文本:
// Roll.js
getNumStr () {
// 获取编辑框中输入的数字(字符串)
let numStr = this.editNode.getComponent(cc.EditBox).string;
return numStr;
},
接着在okBtn方法中判断玩家输入的字符串是否可以转为数字(记得给ok_btn按钮绑上该方法):
// Roll.js
okBtn () {
// 首先获取数字(字符串)
let numStr = this.getNumStr();
// 再判断是否可以转换为数字
let num = Number(numStr);
if (!isNaN(num)) {
console.log('是数字!');
}
else {
console.log('非数字!');
}
},
当确认玩家输入的是数字后,我们就可以生成相应位数的数字,并执行滚动效果。
数字的位数可以直接通过numStr的长度来判断,有多少位我们就生成多少个预制:
// Roll.js
okBtn () {
// 首先获取数字(字符串)
let numStr = this.getNumStr();
// 再判断是否可以转换为数字
let num = Number(numStr);
if (!isNaN(num)) {
// 根据numStr长度生成相应数量的预制
for(let i=0; i
我们注意到每个通过getNewPrefab()生成的预制都被放到了prefabArray数组中。其实该数组变量的作用就是为了更好地管理各个预制(比如后期删除)。在这里我们还可以通过该数组控制数字上的各个位数——数组的第一个元素就是数字的最高位。
生成预制的getNewPrefab方法实现如下:
// Roll.js
getNewPrefab () {
// 生成预制
let numLayout = null;
// 根据节点池大小判断是从预制池中获取还是新生成一个
if (this.prefabPool.size() > 0)
numLayout = this.prefabPool.get();
else
numLayout = cc.instantiate(this.numLayoutPrefab);
// 添加到总布局中
this.allLayoutNode.addChild(numLayout);
return numLayout;
},
预制生成后就是执行滚动效果了:
// Roll.js
okBtn () {
...
if (!isNaN(num)) {
// 根据numStr长度生成相应数量的预制
for(let i=0; i
roll方法实现如下:
// Roll.js
roll (num, prefab) {
// 关键是获取y坐标
let y = null;
if (num != '.')
y = (Number(num)-5)*this.eachHeight;
else
y = (10-5)*this.eachHeight;
let moveTo = cc.moveTo(this.rollTime, cc.v2(0, y)).easing(cc.easeCubicActionOut());
prefab.runAction(moveTo);
}
该方法有两个参数,一个是num,一个是 prefab。前者就是要显示的数字或"."符号,后者即相应位数上的number_layout预制。
我们首先判断num值,如果不是"."符号的话,那我们将调用Number()将该字符转为数字,减去5(5的y坐标为0),再乘以每个数字的高度;是"."符号的话就用直接用10减去5再乘以数字高度("."符号排在最后个)。这样我们就得出了目标点的y坐标,接着将number_layout移到相应位置就可以了。
最后我们还要对okBtn()进行完善。每次点击ok按钮后,我们应当对之前生成的各个预制进行回收:
// Roll.js
okBtn () {
// 删除节点
this.allLayoutNode.removeAllChildren();
// 恢复坐标,回收预制,清空数组
for(let i=0; i
注意要删除之前的节点,并将prefabArray数组清空,各个预制回收前也要恢复坐标(可以自行考虑下为什么)。
现在将Roll.js脚本挂到Canvas节点上,拖入相应节点,然后就可以运行项目啦:
那本期教程就到这,希望大家有所收获!
欢迎关注我的微信公众号,发现更多有趣内容: