1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 《Cocos Creator游戏实战》滚动数字

《Cocos Creator游戏实战》滚动数字

时间:2019-05-02 22:35:31

相关推荐

《Cocos Creator游戏实战》滚动数字

滚动数字

创建节点

滚动原理

编写脚本

该功能已收录在Many Widgets插件中,使用Cocos Creator 3.x版本的小伙伴可以用该插件快速生成滚动数字。

插件地址:/app/detail/3147

演示地址:/video/BV1jP4y1s7DY/

本节我们来实现数字滚动的效果。

运行效果如下:

Cocos Creator版本:2.2.0

公众号后台回复"滚动数字",获取完整项目源码:

创建节点

层级管理器中我们创建以下节点:

esitbox即EditBox控件,用于输入数字。ok_btn即一个按钮控件,当玩家输完数字,点击按钮后,数字滚动。all_layout是一个横向布局节点,具体用处之后会介绍。number_layout是本节教程的核心,它是一个垂直布局节点,其中放入值为0-9以及"."符号的这些Label控件。

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.jsproperties: { numLayoutPrefab: cc.Prefab,allLayoutNode: cc.Node,editNode: cc.Node,rollTime: 2,},

numLayoutPrefab就是number_layout变成的预制。allLayoutNode就是all_layout节点。editNode就是editbox节点。rollTime为滚动动作所需时间。

在onLoad方法中我们编写如下代码:

// Roll.jsonLoad () {// 节点池this.prefabPool = new cc.NodePool();// 预制数组,方便管理this.prefabArray = [];// 获取每个数字长度,用于获取y坐标let numLayout = cc.instantiate(this.numLayoutPrefab);this.eachHeight = numLayout.height / 11;this.prefabPool.put(numLayout);},

节点池用来提高性能。这里的prefabArray挺重要的,我们之后会讲到它的用法。为了准确地显示出数字,我们需要求出number_layout中每个数字的高度(即每个Label控件的高度),这样就可以求出number_layout目标坐标点的y值了。

现在我们实现getNumStr方法来获取输入框文本:

// Roll.jsgetNumStr () {// 获取编辑框中输入的数字(字符串)let numStr = this.editNode.getComponent(cc.EditBox).string;return numStr;},

接着在okBtn方法中判断玩家输入的字符串是否可以转为数字(记得给ok_btn按钮绑上该方法):

// Roll.jsokBtn () {// 首先获取数字(字符串)let numStr = this.getNumStr();// 再判断是否可以转换为数字let num = Number(numStr);if (!isNaN(num)) {console.log('是数字!');}else {console.log('非数字!');}},

当确认玩家输入的是数字后,我们就可以生成相应位数的数字,并执行滚动效果。

数字的位数可以直接通过numStr的长度来判断,有多少位我们就生成多少个预制:

// Roll.jsokBtn () {// 首先获取数字(字符串)let numStr = this.getNumStr();// 再判断是否可以转换为数字let num = Number(numStr);if (!isNaN(num)) {// 根据numStr长度生成相应数量的预制for(let i=0; i<numStr.length; i++) {// 将生成的预制放入数组中this.prefabArray.push(this.getNewPrefab());}}else {console.log('非数字!');}},

我们注意到每个通过getNewPrefab()生成的预制都被放到了prefabArray数组中。其实该数组变量的作用就是为了更好地管理各个预制(比如后期删除)。在这里我们还可以通过该数组控制数字上的各个位数——数组的第一个元素就是数字的最高位。

生成预制的getNewPrefab方法实现如下:

// Roll.jsgetNewPrefab () {// 生成预制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.jsokBtn () {...if (!isNaN(num)) {// 根据numStr长度生成相应数量的预制for(let i=0; i<numStr.length; i++) {// 将生成的预制放入数组中this.prefabArray.push(this.getNewPrefab());}// 执行滚动效果for(let i=0; i<numStr.length; i++) {this.roll(numStr[i], this.prefabArray[i])}}else {console.log('非数字!');}},

roll方法实现如下:

// Roll.jsroll (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.jsokBtn () {// 删除节点this.allLayoutNode.removeAllChildren();// 恢复坐标,回收预制,清空数组for(let i=0; i<this.prefabArray.length; i++) {this.prefabArray[i].setPosition(0, 0);this.prefabPool.put(this.prefabArray[i]);}this.prefabArray = [];...},

注意要删除之前的节点,并将prefabArray数组清空,各个预制回收前也要恢复坐标(可以自行考虑下为什么)。

现在将Roll.js脚本挂到Canvas节点上,拖入相应节点,然后就可以运行项目啦:

那本期教程就到这,希望大家有所收获!

欢迎关注我的微信公众号,发现更多有趣内容:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。