cocos creater 基礎2,1.游戲開始結束繼續的場景切換。2.鍵盤監聽實現上下左右移動。3.下雨特效。


<!-- 第三天,繼續視頻教程做練習和讀代碼。今天主要三個練習,第一個是場景跳轉,第二個是通過鍵盤監聽實現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 });
Code1
 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 });
Code2
主要就是三個關鍵字 
scheduler ,director , loadScene 。
 
director 一個管理游戲流程的單例對象,用來創建處理主窗口,管理場景。初始化像素格式環境。  <!--api里面寫了一個注意用首字母小寫代替首字母大寫  注意:用 cc. director 代替 cc.Director。我去試了一下。網頁會報一個警告在后台,The 'cc.eventManager' will be removed in v2.0, please use 'cc.EventTarget or cc.systemEvent' instead. 里面說的是eventManager。api里面是被廢棄的類。可能是如果使用大寫字母會使用到這個類。記得用小寫就行了。(后來我發現director沒有觸發,這個警告和這個首字母大小寫沒有關系。實際情況是運行到跳轉的時候cc.Director.loadScene is not a function,首字母大寫的是會直接報錯的。)我理解這個一個專門管理場景的對象。附帶有一些對環境配置的管理。調用不同的方法對場景進行操作。主要操作就是加載,預加載,暫停,運行指定場景,啟動場景。獲取視頻像素點。還能getScene獲取當前邏輯場景。能點出來事件包括場景加載之前運行之后觸發事件,訪問渲染前后觸發的事件,梅一幀開始是觸發的事件。-->
 
loadScene 通過場景名稱機進行加載場景。
(method) cc.Director.loadScene(sceneName: string, onLaunched?: Function): boolean 看了有倆參數,第一個參數是場景的名字,類型是字符串。第二個參數是能傳入一個function,在場景加載完成之后執行。就好像是給你一個返回信號,表示我已經加載好了。<!--本來想試試,但是知道了function有限,不知道場景轉換玩,如何在新的場景里面輸出一個結果。理論上在新的場景節點加載這個腳本就能夠操作新的場景節點的label什么的做一個展示了,但是數據太少加載太快估計感覺不出來,所以我晚點再測試-->
例子:cc.director.loadScene('gameover');

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 });
Code3

主要使用到的關鍵字有 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 });
Code4

關鍵字:

EventListener.KEYBOARD 
onKeyPressed 
onKeyReleased
addListener
 
EventListener 封裝用戶的事件處理邏輯。 注意:這是一個抽象類,開發者不應該直接實例化這個類.
代碼25行,
KeyBoard (property) cc.EventListener.KEYBOARD: number 是作為抽象類EventListener的屬性被調用。cc.EventListener.KEYBOARD.返回的是一個表示鍵盤輸入數據的數字信息。
首先一個監聽事件的注冊 可以使用cc.node.on('mousedown',function(event){}),在演示代碼中是
cc.eventManager.addListener(Listener,target,node)
 
addListener 將事件監聽器添加到事件管理器中。
console.log('Hello'); 在控制台打印hello,我在網頁F12,查看報錯的地方看見了這個,在cocoscreator的控制台卻沒有看見。
等同cc.log(); 輸出一條消息到 Cocos Creator 編輯器的 Console 或運行時 Web 端的 Console 中。 
代碼中的eventmanager提示是過時的關鍵字,暫時沒看到其他的寫法。
鍵盤監聽的寫法是  
 
先定義一個函數。
a : funciton() {
  var self = this;  <!-- 在js中,this的用法,聲明函數賦值給變量時候會指向windows,但是在內部定義函數的this指向的是調用函數的標簽。所有需要把window對象實現傳進去使用。-->
  var Listener = {
  event:cc.EventListener.KEYBOARD,
  onKeyPressed: function(KeyCode,event){ KeyCode表示按鍵 
  event.getCurrentTarget() 返回其監聽器觸發事件的節點
  event
}
  onKeyReleased:function(KeyCode,event){  } 
 
}
cc.eventMananger.addmanager(listener,self.node)  <!--  這里的self。node就是指的window--> 將事件監聽器添加到事件管理器中。
}

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(),從事件管理器中移除事件監聽器。

<!-- 關於事件監聽還有很多不懂,這里想記錄寫法。后面在慢慢學習 -->

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM