(點擊圖片可進入試玩)
本篇文章為第三部分內容,這篇文章將接着上篇文章的內容,這篇文章的主要內容有:
7、游戲中的暫停與結束處理
8、排行榜界面
七、游戲中的暫停與結束處理
7.1 暫停
暫停處理:在游戲中,秋千的搖擺、柱子的移動等都是通過Tween動畫實現的,例如秋千搖擺我們可以加TweenRation動畫、柱子移動可以加TweenPosition動畫。當我們按下暫停鍵時,此時,秋千與柱子還有考拉等應該是靜止的,我還希望能彈出另一個界面,該界面有一些界面按鈕,點擊按鈕可以實現對應的操作,關閉彈出的界面時,我們又可以繼續游戲。首先我們可以在Main.js中加入代碼對暫停按鈕進行監聽點擊事件:代碼如下,

1 var Main = qc.defineBehaviour('qc.Koala.ui.Main', qc.Behaviour, function() { 2 // 風值 3 this.windValue = 0; 4 5 // 掉落事件控制器 6 this.dropTimer = null; 7 8 // 跳台對象 9 this._step = null; 10 11 // 秋千對象 12 this.swing = null; 13 }, { 14 // 柱子池 15 pillarPool : qc.Serializer.NODE, 16 // 考拉節點 17 koala : qc.Serializer.NODE, 18 // 暫停按鈕 19 pauseBtn : qc.Serializer.NODE, 20 // 風值 21 wind : qc.Serializer.NODE, 22 // 風向 23 windDirection : qc.Serializer.NODE, 24 // 分數節點 25 score : qc.Serializer.NODE 26 }); 27 /** 28 * 初始化 29 */ 30 Main.prototype.awake = function() { 31 var self = this; 32 33 // 監聽暫停按鈕點擊事件 34 this.addListener(this.pauseBtn.onClick, this._pause, this); 35 36 // 繼續游戲時,恢復暫停按鈕交互 37 this.addListener(qc.Koala.onContinue, function() { 38 this.pauseBtn.interactive = true; 39 }, this); 40 }; 41 /** 42 * 暫停游戲 43 */ 44 Main.prototype._pause = function () { 45 // 如果游戲結束,則暫停按鈕點擊不做任何處理 46 if (qc.Koala.logic.me.isDie) 47 return; 48 49 // 設置游戲暫停狀態 50 qc.Koala.logic.me.paused = true; 51 52 // 派發游戲暫停事件 53 qc.Koala.onPause.dispatch(); 54 };
在該代碼中有qc.Koala.onPause.dispatch(),意思是派發暫停事件。而我們可以在在Scripts/ui/Koala.js中加入事件接收,並停止秋千與考拉的動作從而達到暫停效果。代碼如下所示:

1 var Koala = qc.defineBehaviour('qc.Koala.ui.Koala', qc.Behaviour, function() { 2 // 秋千對象 3 this.swingScript = null; 4 5 // 考拉當前播放的動作 6 this.currAnimation = 'stand'; 7 }, { 8 // 相機節點 9 camera : qc.Serializer.NODE, 10 // 特效節點 11 effect : qc.Serializer.NODE, 12 // 文本 13 labelImg : qc.Serializer.NODE, 14 // 分數 15 scoreImg : qc.Serializer.NODE, 16 // 死亡效果圖片 17 dieImg : qc.Serializer.NODE, 18 // 剎車效果圖片 19 brakeImg : qc.Serializer.NODE 20 }); 21 22 /** 23 * 初始化 24 */ 25 Koala.prototype.awake = function () { 26 // 監聽游戲暫停事件 27 this.addListener(qc.Koala.onPause, this._pause, this); 28 29 }; 30 31 /** 32 * 暫停游戲 33 */ 34 Koala.prototype._pause = function () { 35 this.swingScript.stop(); 36 this.gameObject.stop(); 37 38 this.labelImg.getScript('qc.TweenAlpha').onFinished.removeAll(this); 39 40 // 並移除動作結束監聽 41 var s = this.gameObject.getScript('qc.TweenPosition'); 42 s.onFinished.remove(this.take, this); 43 44 // 停止考拉走路位移動畫 45 qc.Tween.stopGroup(this.gameObject, 3); 46 };
此時,我還希望在暫停的同時能夠彈出一個菜單界面。彈出的菜單界面效果圖如下所示:
菜單界面具體布局我就不詳述了,可以參看前兩篇文章的界面布局,也可以查看更詳細的界面布局信息《界面布局》。前面我們講過,當按下暫停按鈕時,該菜單界面也會彈出來。我們可以創建一個腳本:Pause.js,該腳本的主要功能是接收游戲暫停事件的派送、點擊"關閉"按鈕時又繼續游戲、以及上述中的按鈕按下時對應的功能,排行榜與分享的具體實現我會在后續游戲結束處理中詳細講述。代碼如下:

1 var Pause = qc.defineBehaviour('qc.Koala.ui.Pause', qc.Behaviour, function() { 2 }, { 3 // 繼續游戲按鈕 4 continueBtn : qc.Serializer.NODE, 5 restartBtn : qc.Serializer.NODE, 6 shareBtn : qc.Serializer.NODE, 7 moreBtn : qc.Serializer.NODE, 8 rankBtn : qc.Serializer.NODE 9 }); 10 11 /** 12 * 初始化 13 */ 14 Pause.prototype.awake = function() { 15 var self =this; 16 // 監聽游戲暫停事件 17 this.addListener(qc.Koala.onPause, this.show, this); 18 19 // 監聽繼續游戲按鈕點擊事件 20 this.addListener(this.continueBtn.onClick, this.onContinueBtnClick, this); 21 22 // 監聽重新開始游戲點擊事件 23 this.addListener(this.restartBtn.onClick, this.onRestartBtnClick, this); 24 25 // 監聽分享按鈕點擊事件 26 this.addListener(this.shareBtn.onClick, function() { 27 qc.Koala.showShareMsg.dispatch(); 28 }, this); 29 30 // 監聽更多游戲按鈕點擊事件 31 this.addListener(this.moreBtn.onClick, function() { 32 document.location.href = qc.Koala.logic.config.followHref; 33 }, this); 34 35 // 監聽排行榜按鈕點擊事件 36 this.addListener(this.rankBtn.onClick, this.onRankBtnClick, this); 37 }; 38 39 /** 重新開始游戲按鈕點擊后處理 */ 40 Pause.prototype.onRestartBtnClick = function() { 41 // 派發游戲開始事件,並指定為重新開始 42 qc.Koala.onStart.dispatch(true); 43 // 隱藏死亡界面 44 this.hide(); 45 }; 46 47 /** 48 * 繼續游戲按鈕點擊后處理 49 */ 50 Pause.prototype.onContinueBtnClick = function() { 51 // 設置游戲暫停狀態 52 qc.Koala.logic.me.paused = false; 53 54 // 派發繼續游戲事件 55 qc.Koala.onContinue.dispatch(); 56 57 // 隱藏界面 58 this.hide(); 59 }; 60 61 /** 62 * 排行榜按鈕點擊事件后處理 63 */ 64 Pause.prototype.onRankBtnClick = function () { 65 if (qc.Koala.logic.me.userInfo && 66 qc.Koala.logic.me.userInfo.subscribe) { 67 qc.Koala.onRankingClose.addOnce(this.show, this); 68 69 qc.Koala.showRanking.dispatch(); 70 71 this.hide(); 72 } 73 else { 74 //顯示關注界面 75 qc.Koala.showFollowMsg.dispatch(); 76 } 77 }; 78 79 /** 80 * 顯示界面 81 */ 82 Pause.prototype.show = function () { 83 this.gameObject.visible = true; 84 }; 85 86 /** 87 * 隱藏界面 88 */ 89 Pause.prototype.hide = function () { 90 this.gameObject.visible = false; 91 };
當我們點擊"關閉"按鈕時,我們希望繼續游戲。此時在Pause.js中的onContinueBtnClick方法中加入一個繼續游戲的事件派發qc.Koala.onContinue.dispatch(),剛才暫停時,我們停止秋千與考拉的動作,此時,我們可以相應地在Scripts/ui/Koala.js中加入事件接收用於恢復游戲,加入的代碼如下:

1 var Koala = qc.defineBehaviour('qc.Koala.ui.Koala', qc.Behaviour, function() { 2 // 秋千對象 3 this.swingScript = null; 4 5 // 考拉當前播放的動作 6 this.currAnimation = 'stand'; 7 }, { 8 // 相機節點 9 camera : qc.Serializer.NODE, 10 // 特效節點 11 effect : qc.Serializer.NODE, 12 // 文本 13 labelImg : qc.Serializer.NODE, 14 // 分數 15 scoreImg : qc.Serializer.NODE, 16 // 死亡效果圖片 17 dieImg : qc.Serializer.NODE, 18 // 剎車效果圖片 19 brakeImg : qc.Serializer.NODE 20 }); 21 22 /** 23 * 初始化 24 */ 25 Koala.prototype.awake = function () { 26 27 // 監聽游戲繼續事件 28 this.addListener(qc.Koala.onContinue, this._continue, this); 29 }; 30 31 /** 32 * 繼續游戲 33 * @method qc.Koala.ui.Koala#_continue 34 */ 35 Koala.prototype._continue = function () { 36 if (this.currAnimation !== 'die') 37 this[this.currAnimation](); 38 };
7.2 游戲結束
游戲結束處理:在上一篇文章中我們在碰撞中講到了當考拉碰到柱子的左邊緣或者超出游戲邊界時,則結束游戲;我希望游戲結束時,能夠彈出游戲結束界面,界面上可以顯示我這輪游戲的得分以及我歷史的最高分,由於在手機上我們可以微信登錄,所以我想游戲結束界面還應該有向好友分享的功能、查詢排行榜功能、以及重玩一次的功能。最終效果圖應該是這樣的:
界面布局比較簡單就不講述了,讀者們如果想知更多的界面布局信息也可以參考《界面布局》,需要講述的是,當考拉碰到柱子左邊緣或者超出游戲界面時,此時,在上一篇的腳本Main.js中的檢測碰撞代碼會返回對應死亡信息,如下面代碼:

1 Main.prototype._onDrop = function (vx0, vy0, t) { 2 // 計算橫向和縱向偏移值 3 var preY = this.koala.y, 4 deltaX = vx0 * t, 5 deltaY = vy0 * t; 6 7 // 設置考拉位置 8 this.koala.x += deltaX; 9 this.koala.y += deltaY; 10 11 // 調整相機位置 12 this.adjustCamera(deltaX, deltaY); 13 14 // 檢測考拉位置 15 var result = this._checkCollide(preY); 16 if (result !== 0) { 17 // 移除定時器 18 this.game.timer.remove(this.dropTimer); 19 this.dropTimer = null; 20 21 // 成功跳到下一個站台 22 if (result === 1) { 23 this._onStep(); 24 } 25 26 // 游戲結束 27 if (result < 0) { 28 this.gameOver(result); 29 } 30 } 31 }; 32 33 /** 34 * 檢測考拉是否可以站在平台上 35 * @param {number} preY - 考拉移動前的y軸位置 36 * @return {number} 返回值定義如下 37 * 1:落在跳台上; 38 * -1:超出游戲邊界; 39 * -2:碰到跳台的左邊緣; 40 * 0:還在掉落 41 */ 42 Main.prototype._checkCollide = function(preY) { 43 var x = this.koala.x, 44 y = this.koala.y, 45 step = this._step.gameObject; 46 47 // 判斷是否落到跳台上 48 if (x > step.x && 49 x < step.x + step.width && 50 preY <= step.y + step.parent.y && 51 y >= step.y + step.parent.y) 52 return 1; 53 54 // 超出游戲邊界,因為相機有跟着考拉在動,所以在這邊不需要判斷游戲屏幕x軸方向超邊 55 if (y > this.gameObject.height + this.koala.height - this.pillarPool.parent.y) 56 return -1; 57 58 // 判斷與跳台左邊緣碰撞 59 if (x > step.x && 60 x < step.x + step.width && 61 preY > step.y + step.parent.y) 62 return -2; 63 64 return 0; 65 };
在上述代碼中,我們可以判斷如果result返回的值為負的,則此時我們就可以判斷游戲結束並派發一個游戲結束的事件。在Main.js腳本代碼中加入如下代碼:

1 /** 2 * 游戲結束,並播放掉落動畫 3 * @param {number} result - 游戲死亡類型 4 * -1:超出游戲邊界; 5 * -2:碰到跳台的左邊緣; 6 */ 7 Main.prototype.gameOver = function(result) { 8 // 設置游戲死亡狀態 9 qc.Koala.logic.me.isDie = true; 10 11 // 禁止暫停按鈕交互 12 this.pauseBtn.interactive = false; 13 14 // 超出游戲邊界 15 if (result === -1) { 16 qc.Koala.onGameOver.dispatch(); 17 return; 18 } 19 20 // 碰到跳台的左邊緣 21 if (result === -2) { 22 // 播放死亡動作 23 var koalaScript = this.koala.getScript('qc.Koala.ui.Koala'); 24 koalaScript.die(function() { 25 qc.Koala.onGameOver.dispatch(); 26 }); 27 } 28 };
相應的我們可以在Script/ui文件夾下創建腳本:GameOver.js,該腳本的主要功能是監聽游戲結束事件的派發,分享功能、獲取玩家歷史最高分、查詢排行榜及再玩一次,代碼如下:

1 var GameOver = qc.defineBehaviour('qc.Koala.ui.GameOver', qc.Behaviour, function() { 2 }, { 3 // 重新開始游戲按鈕 4 restartBtn : qc.Serializer.NODE, 5 // 分享按鈕 6 shareBtn : qc.Serializer.NODE, 7 // 更逗游戲按鈕 8 moreBtn : qc.Serializer.NODE, 9 // 排行榜按鈕 10 rankBtn : qc.Serializer.NODE, 11 // 記錄更新 12 goalSign : qc.Serializer.NODE, 13 // 當前分數文本 14 scoreLabel : qc.Serializer.NODE, 15 // 最高分文本 16 bestLabel : qc.Serializer.NODE, 17 // 世界排名百分比 18 percentLabel : qc.Serializer.NODE 19 }); 20 21 GameOver.prototype.awake = function() { 22 // 監聽游戲結束事件 23 this.addListener(qc.Koala.onGameOver, this.show, this); 24 25 // 監聽重新開始游戲點擊事件 26 this.addListener(this.restartBtn.onClick, this.onRestartBtnClick, this); 27 28 // 監聽分享按鈕點擊事件 29 this.addListener(this.shareBtn.onClick, function() { 30 qc.Koala.showShareMsg.dispatch(); 31 }, this); 32 33 // 監聽更多游戲按鈕點擊事件 34 this.addListener(this.moreBtn.onClick, function() { 35 document.location.href = qc.Koala.logic.config.followHref; 36 }, this); 37 38 // 監聽排行榜按鈕點擊事件 39 this.addListener(this.rankBtn.onClick, this.onRankBtnClick, this); 40 };
7.3 分享
分享功能的實現。根據策划要求,微信分享時,根據玩家所得的分數分享不同的內容,此時我們也可以將這些數據配置到Excel表中,在上一篇Excel表中添加一個sheet表取名share,添加的表格內容如下:
表中的min與max表示玩家的得分是不是在這個范圍內,如果是則分享對應的內容。同樣我們需要創建一個腳本解析share sheet表中的內容並且可以提供一個方法,根據提供的分數返回對應的內容,在Scripts/logic文件夾下創建腳本:Share.js,代碼如下:

1 var ShareInfo = function(data) { 2 this.id = data.id * 1; 3 this.min = data.min * 1; 4 this.max = data.max * 1; 5 this.max = this.max == null ? Infinity : this.max; 6 this.content = data.content; 7 }; 8 9 var Share = qc.Koala.logic.Share = function(excel) { 10 this.shareMap = {}; 11 12 if (!excel) 13 excel = qc.Island.game.assets.find('config'); 14 15 var sheet = excel.findSheet('share'); 16 17 for (var i in sheet.rows) { 18 var row = sheet.rows[i]; 19 this.shareMap[row.id] = new ShareInfo(row); 20 } 21 22 //qc.Koala.onScoreChange.add(this.share, this); 23 }; 24 25 Share.prototype = {}; 26 Share.prototype.constructor = Share;
我們需要在入口腳本Koala.js的Koala.initLogic方法中將Share類實例化,如下:

1 Koala.initLogic = function(excel, game) { 2 3 // 設置游戲對象引用 4 this.game = game; 5 6 // 設置游戲幀率為60幀 7 game.time.frameRate = 60; 8 9 // 初始化系統配置 10 this.logic.config = new qc.Koala.logic.Config(excel); 11 12 // 游戲相關數據邏輯類 13 this.logic.me = new qc.Koala.logic.Me(); 14 15 // 柱子相關邏輯類 16 this.logic.pillar = new qc.Koala.logic.Pillar(excel); 17 18 // 風力值邏輯類 19 this.logic.wind = new qc.Koala.logic.Wind(excel); 20 21 // 分享相關邏輯類 22 this.logic.share = new qc.Koala.logic.Share(excel); 23 24 // 派發腳本准備就緒事件 25 this.onLogicReady.dispatch(); 26 };
需要說明是,當我們點擊分享成績按鈕時,此時我們需要點擊手機屏幕右上角的分享功能,我們可以在Scripts/ui文件夾下的Welcome.js中的awake方法中加入代碼,該代碼用於從Share類中獲取分享的內容,代碼如下:

1 Welcome.prototype.awake = function() { 2 // 監聽用戶點擊分享 3 this.addListener(wx.onShare, function(body) { 4 body.title = qc.Koala.logic.share.getContent(qc.Koala.logic.me.score); 5 body.imgUrl = qc.Koala.logic.config.shareIcon; 6 body.desc = ""; 7 }, this); 8 };
游戲結束時,我們需要將玩家的得分與歷史最高分作比較,如果高於歷史最高分,則將該得分上傳至服務器保存。需要說明的是:在游戲中,我們需要保存玩家的數據,數據分為兩大類:
1、本地數據:例如歷史最高分等。本地數據可以使用引擎提供的Storage功能來實現。前面的玩家分數管理用的就是Storage功能。
2、網絡數據:如提交歷史最高分、登錄信息、排行榜信息等。需要說明的是,網絡數據需要自行搭建服務器,服務器搭建好了之后,可以用引擎提供的AssetUtil功能來與服務器進行通信。搭建服務器代碼就不做詳述,大家可以選擇自己擅長的語言搭建服務器,這里只講解與服務器通信的接口。
在Scripts文件夾下創建腳本:Interactive.js,該腳本主要用於向服務器上傳玩家數據。如在GameOver.js中有向服務器上傳分數的代碼,而Interactive.js就是提供一個接口。代碼如下:

1 var Interactive = qc.defineBehaviour('qc.Interactive', qc.Behaviour, function() { 2 qc.interactive = this; 3 }, { 4 gameName: qc.Serializer.STRING, 5 serverUrl: qc.Serializer.STRING 6 }); 7 8 /** 9 * 上傳分數 10 * @param {string} rid - 用戶唯一標示 11 * @param {string} token - 當前登陸用戶的臨時標示 12 * @param {number} scorers - 分數 13 * @param {func} callbackFunc - 回調函數 14 */ 15 Interactive.updateScorers = function(rid, token, scorers, callbackFunc, onerror) { 16 var url = qc.interactive.serverUrl + "updateScorers03.php"; 17 url += "?rid=" + rid; 18 url += "&token=" + token; 19 url += "&scorers=" + scorers; 20 url += "&gameName=" + qc.interactive.gameName; 21 22 qc.AssetUtil.get(url, callbackFunc, onerror); 23 };
將該腳本掛載"歡迎界面"節點,其中ServerUrl為服務器路徑。
在結束界面我們顯示兩個得分,分別是當前游戲得分,另一個是歷史最高分,這兩個數據我們可以從我們玩家分數管理腳本中獲得,在GameOver.js中加入如下代碼,該段代碼的主要功能是顯示當前分數及歷史最高分,如果當前分高於歷史最高分的話,則更新歷史最高分:

1 /** 2 * 初始化界面 3 */ 4 GameOver.prototype.initUI = function() { 5 if (qc.Koala.logic.me.score === qc.Koala.logic.me.best) { 6 this.goalSign.visible = true; 7 8 // 判斷當前分數是否超過歷史最高分數 9 qc.Interactive.updateScorers( 10 qc.Koala.logic.me.rid, 11 qc.Koala.logic.me.token, 12 qc.Koala.logic.me.best, 13 function(data) { 14 // 更新分數成功 15 console.log("更新分數成功"); 16 } 17 ); 18 } 19 else { 20 this.goalSign.visible = false; 21 } 22 23 var score = qc.Koala.logic.me.score 24 this.scoreLabel.text = score + ''; 25 26 this.bestLabel.text = '最高分:' + qc.Koala.logic.me.best; 27 28 var percent = qc.Koala.logic.percent.getPercent(score); 29 this.percentLabel.text = '你擊敗了全球' + percent + '%的玩家'; 30 };
而再玩一次功能的實現,我們可以派發一個qc.Koala.onStart事件,即游戲重新開始,開始游戲時,也是通過派發一個qc.Koala.onStart事件,並將結束界面隱藏(即將結束界面的visible設置為false)實現比較簡單。在GameOver.js腳本中加入代碼:

1 /** 2 * 重新開始游戲按鈕點擊后處理 3 */ 4 GameOver.prototype.onRestartBtnClick = function() { 5 // 派發游戲開始事件,並指定為重新開始 6 qc.Koala.onStart.dispatch(true); 7 // 隱藏死亡界面 8 this.hide(); 9 };
查詢排行榜的功能實現將在后續中詳細講述。
將上面的代碼整合到一起,如下所示:

1 var GameOver = qc.defineBehaviour('qc.Koala.ui.GameOver', qc.Behaviour, function() { 2 }, { 3 // 重新開始游戲按鈕 4 restartBtn : qc.Serializer.NODE, 5 // 分享按鈕 6 shareBtn : qc.Serializer.NODE, 7 // 更逗游戲按鈕 8 moreBtn : qc.Serializer.NODE, 9 // 排行榜按鈕 10 rankBtn : qc.Serializer.NODE, 11 // 記錄更新 12 goalSign : qc.Serializer.NODE, 13 // 當前分數文本 14 scoreLabel : qc.Serializer.NODE, 15 // 最高分文本 16 bestLabel : qc.Serializer.NODE, 17 // 世界排名百分比 18 percentLabel : qc.Serializer.NODE 19 }); 20 21 GameOver.prototype.awake = function() { 22 // 監聽游戲結束事件 23 this.addListener(qc.Koala.onGameOver, this.show, this); 24 25 // 監聽重新開始游戲點擊事件 26 this.addListener(this.restartBtn.onClick, this.onRestartBtnClick, this); 27 28 // 監聽分享按鈕點擊事件 29 this.addListener(this.shareBtn.onClick, function() { 30 qc.Koala.showShareMsg.dispatch(); 31 }, this); 32 33 // 監聽更多游戲按鈕點擊事件 34 this.addListener(this.moreBtn.onClick, function() { 35 document.location.href = qc.Koala.logic.config.followHref; 36 }, this); 37 38 // 監聽排行榜按鈕點擊事件 39 this.addListener(this.rankBtn.onClick, this.onRankBtnClick, this); 40 }; 41 42 /** 43 * 初始化界面 44 */ 45 GameOver.prototype.initUI = function() { 46 if (qc.Koala.logic.me.score === qc.Koala.logic.me.best) { 47 this.goalSign.visible = true; 48 49 // 判斷當前分數是否超過歷史最高分數 50 qc.Interactive.updateScorers( 51 qc.Koala.logic.me.rid, 52 qc.Koala.logic.me.token, 53 qc.Koala.logic.me.best, 54 function(data) { 55 // 更新分數成功 56 console.log("更新分數成功"); 57 } 58 ); 59 } 60 else { 61 this.goalSign.visible = false; 62 } 63 64 var score = qc.Koala.logic.me.score 65 this.scoreLabel.text = score + ''; 66 67 this.bestLabel.text = '最高分:' + qc.Koala.logic.me.best; 68 69 var percent = qc.Koala.logic.percent.getPercent(score); 70 this.percentLabel.text = '你擊敗了全球' + percent + '%的玩家'; 71 }; 72 73 /** 74 * 重新開始游戲按鈕點擊后處理 75 */ 76 GameOver.prototype.onRestartBtnClick = function() { 77 // 派發游戲開始事件,並指定為重新開始 78 qc.Koala.onStart.dispatch(true); 79 // 隱藏死亡界面 80 this.hide(); 81 }; 82 83 84 /** 85 * 顯示界面 86 */ 87 GameOver.prototype.show = function () { 88 this.initUI(); 89 this.gameObject.visible = true; 90 }; 91 92 /** 93 * 隱藏界面 94 */ 95 GameOver.prototype.hide = function () { 96 this.gameObject.visible = false; 97 };
將該腳本掛載到"游戲結束"節點,並將節點拖入到對應屬性值上,如下圖:
八、排行榜界面
在游戲結束的界面,我們點擊排行榜,此時,我們希望出現一個排行榜,將玩家的得分、玩家的微信頭像、玩家的排名及其它玩家的信息也顯示到排行榜界面上,效果圖如下:
排行榜界面的布局比較簡單,與前面界面的布局類似。這里需要着重講一下,排行榜界面的每一條關於玩家的頭像、得分、排名及名字,我們可以做成一個預制,在顯示時,需要在排行榜上顯示多少玩家我們就可以產生多少預制。具體實現是:創建一個Empty Node節點取名rankingRow,依次創建玩家頭像信息(在做預制時,可隨意指定玩家頭像信息,游戲中,我們可以通過微信獲取相應玩家的頭像信息並重置相應玩家的頭像),排行名次、玩家名稱及玩家得分,並將這些節點都掛載到"rankingRow"節點下,效果圖如下:
不同的玩家有不同的玩家信息如頭像、得分、名字等,為了能夠正常的顯示對應玩家的信息。在Scripts/ui文件夾下創建腳本:RankingRow.js,腳本代碼如下:

1 var RankingRow = qc.defineBehaviour('qc.Koala.ui.RankingRow', qc.Behaviour, function() { 2 3 }, { 4 rankingLabel : qc.Serializer.NODE, 5 headIcon : qc.Serializer.NODE, 6 nameLabel : qc.Serializer.NODE, 7 score : qc.Serializer.NODE 8 }); 9 10 // 1, 2, 3名對應的排名文本相關顏色 11 RankingRow.COLORMAP = { 12 '1' : { color : new qc.Color('#F9FB02'), stroke : new qc.Color('#860001') }, 13 '2' : { color : new qc.Color('#C5C6C1'), stroke : new qc.Color('#3A3436') }, 14 '3' : { color : new qc.Color('#FEB266'), stroke : new qc.Color('#591B02') } 15 }; 16 17 // 排行榜默認的排名文本相關顏色 18 RankingRow.DEFAULTCOLOR = { color : new qc.Color('#FFFFFF'), stroke : new qc.Color('#A00F0A') }; 19 20 RankingRow.prototype.init = function(row) { 21 // 獲取用戶數據,並設置用戶名和分數 22 this.nameLabel.text = row.name; 23 this.score.text = row.scorers + ''; 24 25 // 加載圖片資源 26 var url = row.headurl; 27 var headIcon = this.headIcon; 28 if (url) 29 this.game.assets.loadTexture(row.rid, url, function(texture) { 30 headIcon.texture = texture; 31 }); 32 33 // 獲取名次 34 var ranking = row.ranking || '100+', 35 rankLabel = ranking + '', 36 color = RankingRow.DEFAULTCOLOR; 37 38 // 1,2,3名分別設置不同的排名文本顏色 39 if (ranking <= 3) { 40 // 獲取文本內容及文本相關顏色 41 rankLabel = 'NO.' + ranking; 42 color = RankingRow.COLORMAP[ranking]; 43 } 44 else { 45 // 設置排名文本字體大小 46 this.rankingLabel.fontSize = 52; 47 } 48 49 // 設置排名文本顏色及描邊顏色 50 this.rankingLabel.color = color.color; 51 this.rankingLabel.stroke = color.stroke; 52 this.rankingLabel.strokeThickness = 3; 53 54 // 設置名次文本 55 this.rankingLabel.text = rankLabel; 56 };
將該腳本掛載到"rankingRow"節點,並將對應的節點拖入到對應的屬性值,如下圖:
現在就有一個問題了,如果我們要顯示的玩家個數大於排行榜界面大小時,我們將不能看到超出排行榜界面的玩家。此時,我們可以使用引擎提供的ScrollView用於解決此問題,具體做法是在"排行榜界面"節點下創建一個ScrollView節點,創建完成后我們可以看到如下信息:
其中Content屬性值的含義是當我們創建玩家信息預制時,將玩家信息節點放到該節點下(圖中是將玩家信息節點放到node節點下)。因為我們是要垂直滾動信息,所以在Vertical屬性值上打鈎,其它的屬性具體含義可查看《ScrollView》。
前面我們已經把玩家預制做好了,但是怎么讓它正確的顯示出來,怎么去獲取玩家的頭像、分數、及排名等信息呢?我們可以這樣做,把玩家的數據都上傳至服務器並保存到數據庫中,需要獲取玩家的排名時,我們可以通過在前面的通信接口類腳本Interactive.js中加入下面代碼:

1 /** 2 * 獲取排行榜 3 * @param {string} rid - 用戶唯一標示 4 * @param {string} token - 當前登陸用戶的臨時標示 5 * @param {string} channel - 渠道 6 * @param {func} callbackFunc - 回調函數 7 */ 8 Interactive.getRank = function(rid, token, channel, callbackFunc, onerror) { 9 var url = qc.interactive.serverUrl + "getRank03.php"; 10 url += "?rid=" + rid; 11 url += "&token=" + token; 12 url += "&channel=" + channel; 13 url += "&gameName=" + qc.interactive.gameName; 14 15 qc.AssetUtil.get(url, callbackFunc, onerror); 16 };
從而相應我們需要創建一個腳本:Ranking.js,該腳本的主要功能是請求玩家數據並解析,代碼如下:

1 var Ranking = qc.defineBehaviour('qc.Koala.ui.Ranking', qc.Behaviour, function() { 2 this._rankingData = []; 3 4 this._iconKeyList = []; 5 }, { 6 rankingList : qc.Serializer.NODE, 7 rankingRowPrefab : qc.Serializer.PREFAB, 8 ownRanking : qc.Serializer.NODE, 9 waiting : qc.Serializer.NODE, 10 closeBtn : qc.Serializer.NODE 11 }); 12 13 Ranking.prototype.awake = function () { 14 this.addListener(qc.Koala.showRanking, this.show, this); 15 16 this.addListener(this.closeBtn.onClick, this.close, this); 17 }; 18 19 Ranking.prototype.getRanking = function () { 20 // TODO 獲取排行榜數據,監聽到獲取成功,調用getRankingSuccess方法 21 var self = this; 22 var me = qc.Koala.logic.me; 23 qc.Interactive.getRank(me.rid, me.token, me.channel, function(data) { 24 data = JSON.parse(data); 25 var rank = 0; 26 var rankTop = data.rankTop; 27 for (var i = 0; i < rankTop.length; i++) { 28 var u = rankTop[i]; 29 if (u.rid === me.rid) { 30 rank = i + 1; 31 } 32 u.ranking = i + 1; 33 } 34 data.selfRank = data.userData[0]; 35 if (data.selfRank) 36 data.selfRank.ranking = rank; 37 38 self.getRankingSuccess(data); 39 }); 40 }; 41 42 Ranking.prototype.getRankingSuccess = function (data) { 43 this.waiting.stop(); 44 this.waiting.visible = false; 45 46 // 初始化排行榜列表 47 var n = this.rankingList.getScript('qc.Koala.ui.RankData'); 48 n.rankData = data.rankTop; 49 n.dispatchDataChange(); 50 51 52 // 初始化我的排名 53 this.initOwnRanking(data.selfRank); 54 }; 55 56 Ranking.prototype.initOwnRanking = function (row) { 57 var s = this.ownRanking.getScript('qc.Koala.ui.RankingRow'); 58 s.init(row); 59 60 this.ownRanking.visible = true; 61 }; 62 63 Ranking.prototype.show = function () { 64 this.gameObject.visible = true; 65 66 this.waiting.visible = true; 67 this.waiting.playAnimation('zhuan', null, true); 68 69 this.getRanking(); 70 }; 71 72 Ranking.prototype.close = function () { 73 this.gameObject.visible = false; 74 this._rankingData.length = 0; 75 76 this._iconKeyList.forEach(function(icon) { 77 this.game.assets.unload(icon); 78 }, this); 79 80 this._iconKeyList.length = 0; 81 82 //this.rankingList.content.removeChildren(); 83 84 qc.Koala.onRankingClose.dispatch(); 85 };
將該腳本掛載到"排行榜界面"節點上,將對應的節點拖入對應的屬性值上,如下圖:
到這里,所有的游戲功能開發已經全部完成了。