Shawn前段时间尝试用Cocos Creator做了一个PPT,发现还挺好玩的,有很多东西值得去研究,这里给大家分享一点使用Creator制作PPT的一些思路和方法。
1. 页面切换
相信大多数人都知道,PPT是由一页页顺序组成的幻灯片所构成,在Creator中直接使用场景来充当灯片页面是最简单的方式,看下图:
页面之间的衔接有两种方式,一种是使用我们之前讲在过的场景切换组件LoadScene,将组件挂载到一个节点上,点击即可切换,看下图:
这种方式就像做超链接,用起来是简单,但需要一页页地去配置。Shawn这里还尝试了一种方式,编写一个导航组件,解析所有场景文件名并做一个排序,提供向前翻页、向后翻页的接口函数,可以提供Button组件调用,看下面代码:
//Navigation.js
cc.Class({
extends: cc.Component,
onLoad () {
this.pageIndex = 0;
//获取所有场景并排序
this._sceneArray = cc.game._sceneInfos.sort((info1, info2) => {
let num1 = parseFloat(cc.path.basename(info1.url, '.fire').split('-')[1]);
let num2 = parseFloat(cc.path.basename(info2.url, '.fire').split('-')[1]);
return num1 - num2;
});
//设置为常驻节点
cc.game.addPersistRootNode(this.node);
this.node.on(cc.Node.EventType.TOUCH_END, () => {
this.loadScene();
});
},
//根据pageIndex变量加载场景
loadScene() {
let info = this._sceneArray[this.pageIndex];
if (info) {
cc.director._loadSceneByUuid(info.uuid);
}
},
//修改pageIndex
next() {
this.pageIndex++;
this.loadScene();
},
//修改pageIndex
back() {
this.pageIndex--;
this.loadScene();
},
});
将上面这个组件挂载到首场景的一个节点上,在内部放入两个按钮,一个调用组件的next方法,一个调用back方法,看下图:
有了这个导航组件,只需要注意场景命名就行了,场景中的内容尽量使用Widget组件做好相对布局与自适应。
2. 内容逐一显示
在PPT中加入一些互动操作,比如点击屏幕时让文字或内容逐一显示,比如像下面演示一样:
这个操作实现的方法有很多,我在这里写了一个组件脚本,将要控制的节点收集起来,在组件start运行时将节点全部隐藏。
老方法使用Button去调用ActiveNode.setActive函数:
利用这个组件不管是显示图片和文字都可以,现在来看它还有些缺点,如果我们有几十个节点需要逐一显示,要拖动几十次,很是麻烦,如何解决这个问题,大家可以想一下。
在这个组件上还可以做一些扩展,一种是点击显示,一种是由时间间隔显示,可以让我们这个PPT的表现更丰富一点。
3. 点击切换图片
点击图片,切换下一张,可以使用之前讲过的SpriteIndex搞定,不过这里为了让组件少一点,使用起来简单一些,我是从cc.Sprite上继承的,看下代码:
let SpriteEx = cc.Class({
extends: cc.Sprite,
properties: {
spriteFrames: [cc.SpriteFrame],
_index: 0,
index: {
type: cc.Integer,
range: [0, 100],
set(value) {
this._index = value % this.spriteFrames.length;
this.spriteFrame = this.spriteFrames[this._index];
},
get() {
return this._index;
}
}
},
next() {
this.index++;
},
});
//屏蔽一些cc.Sprite不需要的属性
cc.Class.Attr.setClassAttr(SpriteEx, 'spriteFrame', 'visible', false);
cc.Class.Attr.setClassAttr(SpriteEx, '_atlas', 'visible', false);
//条件显示cc.Sprite上的一些属性
cc.Class.Attr.setClassAttr(SpriteEx, 'fillType', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
cc.Class.Attr.setClassAttr(SpriteEx, 'fillCenter', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
cc.Class.Attr.setClassAttr(SpriteEx, 'fillStart', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
cc.Class.Attr.setClassAttr(SpriteEx, 'fillEnd', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
cc.Class.Attr.setClassAttr(SpriteEx, 'fillRange', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
cc.Class.Attr.setClassAttr(SpriteEx, 'srcBlendFactor', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
cc.Class.Attr.setClassAttr(SpriteEx, 'dstBlendFactor', 'visible', function() {
return this._type === cc.Sprite.Type.FILLED;
});
module.exports = SpriteEx;
上面代码有点多,主要是继承cc.Sprite后会有一大堆属性会显示到属性面板上,会对组件的使用者产生不好的体验,使用可以cc.Class.Attr.setClassAttr
来控制组件属性的显示。