<!-- 第三天,继续视频教程做练习和读代码。今天主要三个练习,第一个是场景跳转,第二个是通过键盘监听实现node节点上下左右自由移动,第三个是下雨特效,使用到预构节点。这些内容都来源昨天说的那个视频教程,感觉蛮有用的,今天第三天,使用学到的这些应该能做个简陋版的打飞机了,飞机移动和射击都能够实现了。对于不停刷新获取坐标的方法再搞清楚点,就能够做敌机被击落或者掉血的操作了-->
第一个:做一个场景切换练习。代码如下:<!-- 类似网页跳转,知道有加载和预加载。教程有提到键盘监听需要点击下屏幕,我试着把它作为第二个场景,点击开始之后加载到需要键盘监听的场景时候不需要点一下屏幕,就可以让图片上下左右移动了,可能这就是不同于网页吧,在这种类似bug的需要点一下的要求上,跳转场景并不等同于跳转网页,有类似于将某些共有加载项传递到下一个场景的感觉。瞎猜的。-->
这个练习用到两个jsp文件,一个是控制第一个场景到中间游戏正文,一个是从正文到游戏结束的跳转。按照顺序为code1,code2.

1 cc.Class({ 2 extends: cc.Component, 3 4 properties: { 5 6 }, 7 8 // LIFE-CYCLE CALLBACKS: 9 10 onLoad () { 11 this.node.on('mousedown',function(){ 12 cc.director.loadScene('game'); 13 }); 14 }, 15 16 start () { 17 }, 18 19 // update (dt) {}, 20 });

1 cc.Class({ 2 extends: cc.Component, 3 4 properties: { 5 timeLabel:{ 6 default:null, 7 type:cc.Label 8 } 9 }, 10 11 onLoad () { 12 var times = 500; 13 this.schedule( 14 function(){ 15 times--; 16 this.timeLabel.string = times; 17 if(times===0){ 18 cc.director.loadScene('gameover'); 19 } 20 },1) 21 }, 22 23 start () { 24 25 }, 26 27 // update (dt) {}, 28 });
scheduler 是负责触发回调函数的类。通常情况下,建议使用 cc.director.getScheduler() 来获取系统定时器。 <!-- 之前做雨点效果的时候,明明生成一次,function里面也是return的一个sequence的动作,结果一直在下雨,满屏幕都是,后来找到原因是因为写到了update代码块里面去了,scheduler类似update,可以自定义循环的间隔,次数,延迟。api表示通常情况下,建议使用 cc.director.getScheduler() 来获取系统定时器。-->就是一个定时器控制,能够对控制器进行管理,包括加速减速,对定时器里面的函数的优先级进行管理。它的一个方法是schedule,就是使用它来完成循环动作。对label标签倒计时操作的。<!--教程里是直接this.schedule,在api建议使用写法是 cc.director.getScheduler().schedule(callback,target,interval,repeat,delay,paused) 下面详细说参数是什么-->
schedule 定时器。
(method) cc.Scheduler.schedule(callback: Function, target: any, interval: number, paused?: boolean): void (+1 overload)
参数分别是 回调函数,目标对象,区间数,重复数,延迟数,是否暂停。一般回用到的是,callback的函数,target的目标和延迟数。<!-- 你可以直接就是this.schedule()就开始用,四个参数,第一个函数,第二个是间隔,第三个是次数,第四个是延迟数。如果按照api里的写法,第二个目标是必须写的,我测试过,要写个this,不然会报错加载不上场景,但是this.schedule()就不需要。估计是这样写就是默认参数为this-->
第二个:实现雨点特效。
代码:

1 cc.Class({ 2 extends: cc.Component, 3 4 properties: { 5 hj : { 6 default: null, 7 type: cc.Prefab 8 }, 9 /* plane : { 10 default: null, 11 type: cc.Node 12 }*/ 13 14 }, 15 16 // LIFE-CYCLE CALLBACKS: 17 18 // onLoad () {}, 19 newHJ:function(position) { 20 var newHJ = cc.instantiate(this.hj); 21 this.node.addChild(newHJ,100); 22 newHJ.setPosition(position); 23 var hjdown = cc.moveBy(cc.random0To1()*5+1,cc.p(0,-this.node.height-100)); 24 var hjfilish = cc.callFunc(newHJ.removeFromParent,newHJ); 25 newHJ.runAction(cc.sequence(hjdown,hjfilish)); 26 }, 27 start () { 28 29 }, 30 31 getStartPosition: function(){ 32 var y = this.node.height/2+100; 33 var x = cc.random0To1()*960-480; 34 return cc.p(x,y); 35 }, 36 onLoad: function () { 37 38 this.schedule(function(){ 39 this.newHJ(this.getStartPosition()); 40 },3,3,3 41 ); 42 /* this.schedule( function () { 43 this.newHJ(cc.p(this.plane.x,this.plane.y)) 44 },1)*/ 45 }, 46 update (dt) { 47 48 }, 49 50 });
主要使用到的关键字有 instantiate addChild random0To1 callFunc removeFromParent
instantiate 克隆指定的任意类型的对象,或者从 Prefab 实例化出新节点。
function cc.instantiate<any>(original: any): any (+1 overload) 就是返回一个新的对象,可以用来克隆任何对象。克隆出一个之后,可以通过.original。返回一个原始对象。 <!--original:原件 overload:过载 Instantiate 时,function 和 dom 等非可序列化对象会直接保留原有引用,Asset 会直接进行浅拷贝,可序列化类型会进行深拷贝。)-->
addChild 添加子节点。Secene.addChild(),node.addChild(Child,locaZorder,tag),三个参数,一个是子节点对象。第二个是增加的子节点的层级,第三个是可选的标签标记.<!--可能在生成大量的节点需要单独出来进行操作的时候会用到这个参数。想雨点效果这种就不需要。>
random0To1 返回一个0到1之间随机的浮点数。<!-- 大概用法,比如你想要获得正600到负六百中间的随机数,写法就是 c.random0To1()*1200-600。大概思路就是,假设返回值为x,则 0<x<1,不等式两边同时乘一个1200,就是0到1200,再不等式两边同时减去600就等到想要的结果了。举个特殊的例子,123到234,123<x<234,等式两边减去123,然后同时除(234-123),就回到了 0<x<1 我知道你懂了。-->
callFunc 执行回调函数 callFunc(function(){},target,date) 返回一个ActionInstant 即时动作 <!-- 我理解传入一个函数和一个目标,然后把函数处理目标的过程封装成一个即时动作返回。-->
ActionStant 即时动作,和ActionInterval事件间隔动作 都是继承于finiteTimeAction 有限时间动作。<!--暂时没遇到返回ActionStant的,callFunc是第一个。之前遇到ActionInterval有moveBy和moveTo能返回一个ActionInterval对象-->
removeFromParent 从父节点删除该节点。如果不传入 cleanup 参数或者传入 true
,那么这个节点上所有绑定的事件、action 都会被删除。建议调用这个 API 时总是传入 false
参数。如果该节点上的所有操作和回调都应该删除,则为false。<!--我以为是移除,结果解释是删除这个节点上绑定的事件和action。那么问题来了,这个节点还在不在呢。我觉得应该是在的,只是断掉了所有的联系,变成了孤儿。api里面解释是如果这个一个孤节点,什么事情都不会发生。让节点回到孤独,断了它身上所有的牵绊。-->
第三个,利用键盘事件监听,实现图片的上下左右等八个方向的自由移动。
代码

1 cc.Class({ 2 extends: cc.Component, 3 4 properties: { 5 speed:0, 6 plane:{ 7 default:null, 8 type:cc.Node 9 } 10 11 }, 12 setInputControl: function() { 13 var self = this; 14 var listener = { 15 event:cc.EventListener.KEYBOARD, 16 onKeyPressed: function(KeyCode,event){ 17 switch(KeyCode){ 18 case cc.KEY.a: 19 self.accLeft = true; 20 break; 21 case cc.KEY.d: 22 self.accRight = true; 23 break; 24 case cc.KEY.w: 25 self.accUp = true; 26 break; 27 case cc.KEY.s: 28 self.accDown = true; 29 break; 30 } 31 }, 32 onKeyReleased: function(KeyCode,event){ 33 switch(KeyCode){ 34 case cc.KEY.a: 35 self.accLeft = false; 36 break; 37 case cc.KEY.d: 38 self.accRight = false; 39 break; 40 case cc.KEY.w: 41 self.accUp = false; 42 break; 43 case cc.KEY.s: 44 self.accDown = false; 45 break; 46 } 47 }, 48 }; 49 cc.eventManager.addListener(listener,self.node); 50 }, 51 52 onLoad () { 53 //定义四个方向是否发生移动的变量 54 this.accLeft = false; 55 this.accRight = false; 56 this.accDown = false; 57 this.accUp = false; 58 this.setInputControl(); 59 }, 60 61 start () { 62 63 }, 64 test :function () { 65 if(this.accLeft && this.plane.x>-389){ 66 this.plane.x -= this.speed; 67 } 68 if(this.accRight && this.plane.x<389){ 69 this.plane.x += this.speed; 70 } 71 if(this.accUp && this.plane.y<260){ 72 this.plane.y += this.speed; 73 } 74 if(this.accDown && this.plane.y>-260){ 75 this.plane.y -= this.speed; 76 } 77 }, 78 update (dt) { 79 this.test(); 80 /*if (this.plane.x>-389) { 81 this.test(); 82 }else{ 83 this.plane.x++;} 84 if (this.plane.x<389) { 85 this.test(); 86 }else{ 87 this.plane.x--;} 88 if (this.plane.y>-260) { 89 this.test(); 90 }else{ 91 this.plane.y++;} 92 if (this.plane.y>-260) { 93 this.test(); 94 }else{ 95 this.plane.y--;}*/ 96 }, 97 });
关键字:
event.getCurrentTarget() 返回其监听器触发事件的节点
event
}
EventListener 官方api中的用法如下。
stener.create({ event: cc.EventListener.KEYBOARD,
onKeyPressed: function (keyCode, event) { cc.log('pressed key: ' + keyCode); },
onKeyReleased: function (keyCode, event) { cc.log('released key: ' + keyCode); } });
// Create ACCELERATION EventListener. cc.EventListener.create({ event: cc.EventListener.ACCELERATION, callback: function (acc, event) { cc.log('acc: ' + keyCode); } }); 加速器事件监听器类型 <!-- 加速器事件监听器暂时不知道是什么,把例子先写到这里 :
// Create ACCELERATION EventListener. cc.EventListener.create({ event: cc.EventListener.ACCELERATION, callback: function (acc, event) { cc.log('acc: ' + keyCode); } });
-->
类似的有 removeListener(),从事件管理器中移除事件监听器。
<!-- 关于事件监听还有很多不懂,这里想记录写法。后面在慢慢学习 -->