第四節 遊戲暫停、分數記錄、音頻添加
這一節其實就是做一下收尾工作,完成以上三個功能後,一個標準的俄羅斯方塊遊戲就完成了。當然我們之後還會加上微信排行榜和好友分享等功能,不過在這一節我們只用看下標題中的這三個點。
遊戲暫停
首先在層級管理器中添加一個按鈕節點,命名爲pauseResume,該按鈕用暫停遊戲(按一下暫停,再按一下繼續):
利用Widget組件將按鈕固定在屏幕右上角:
節點設置好後,我們來編寫腳本。
首先在properties中加入如下屬性:
// Game.js
properties: {
...
pauseResumeBtn: cc.Node,
pausePic: cc.SpriteFrame,
resumePic: cc.SpriteFrame,
},
- pauseResumeBtn就是按鈕節點,當玩家點擊按鈕後我們要修改按鈕的圖片。
- pausePic是暫停圖片。
- resumePic是播放(繼續)圖片。
接着在onLoad方法中添加一個變量,用於判斷遊戲當前是暫停還是繼續:
// Game.js
onLoad () {
...
// 用於判斷是否已經暫停
this.isPaused = false;
},
然後在左移、右移、旋轉和下落四個按鈕的事件函數開頭加入判斷——如果遊戲已經暫停,則按鈕點擊無效:
// Game.js
leftBtn() {
if (this.isPaused)
return;
...
},
rotateBtn() {
if (this.isPaused)
return;
...
},
dropBtn() {
if (this.isPaused)
return;
...
},
rightBtn() {
if (this.isPaused)
return;
...
}
現在編寫暫停按鈕的事件函數pauseResume:
// Game.js
pauseResume() {
// 遊戲暫停
if (!this.isPaused) {
this.isPaused = true; // 設置isPaused變量
this.unschedule(this.moveDown); // 取消計時器
let btnBg = this.pauseResumeBtn.children[0]; // 修改按鈕背景
btnBg.getComponent(cc.Sprite).spriteFrame = this.resumePic;
}
else {
this.isPaused = false; // 設置isPaused變量
this.schedule(this.moveDown, 1); // 取消計時器
let btnBg = this.pauseResumeBtn.children[0]; // 修改按鈕背景
btnBg.getComponent(cc.Sprite).spriteFrame = this.pausePic;
}
},
首先判斷當前是否是暫停狀態:
- 如果不是,則設置isPaused爲true,取消掉計時器,並且重新設置按鈕的圖片,這樣遊戲就進入暫停狀態了。
- 如果是,則設置isPaused爲false,開啓計時器,並且重新設置按鈕的圖片,這樣遊戲繼續了。
最後在屬性檢查器中添加按鈕的事件函數,然後將各相關節點拖入Game組件中就可以了(關於節點拖入以及按鈕的事件函數設置的操作,筆者之後將不再贅述。請讀者在編寫好代碼後記得將相關屬性設置好,不然遊戲運行會報錯der~):
分數記錄
同樣我們現在層級管理器中添加一個Label控件,命名爲score:
使用Widget組件將該節點固定在屏幕左上方:
因爲分數會逐漸變大,位數會增加,那爲了讓文本在長度變化時不會超出屏幕,我們需要將錨點中的x座標設置爲0。這樣左邊就會固定住,文本只會向右邊長:
接下來編寫腳本。在properties中添加scoreLabel屬性:
// Game.js
properties: {
...
scoreLabel: cc.Label, // 分數文本
},
在onLoad方法中添加一個this.score變量用來做加法運算:
// Game.js
onLoad () {
...
// 分數
this.score = 0;
},
然後我們編寫一個addScore方法:
// Game.js
addScore() {
// 分數+1
this.score += 1;
this.scoreLabel.string = "分數:" + String(this.score);
},
非常簡單,就是給this.score變量加上1,再調用String()轉爲字符串即可。
最後我們在dropConfirmedTiles調用addScore方法:
// Game.js
dropConfirmedTiles (lines) {
// 讓其他未消除的方塊下落
if (lines.length) {
for (let i=0; i<lines.length; i++) {
for (let j=0; j<this.confirmedTileArray.length; j++) {
let confirmedY = Math.round(this.confirmedTileArray[j].y);
// 只有消除行上方的方塊才允許下降
if (confirmedY <= -lines[i]*this.tileHeight)
continue;
this.confirmedTileArray[j].y -= this.tileHeight;
}
// 增加分數
this.addScore();
}
}
},
每消除一行,分數加上1。
運行截圖如下:
音效添加
以下是筆者在這個遊戲中將使用的音頻文件:
- bg是背景音樂。
- btn是左右移動和旋轉按鈕音效。
- drop是下落音效。
- lose是失敗音效
- pauseResume是暫停/繼續音效。
- remove是消除音效。
在properties中添加如下屬性:
// Game.js
properties: {
...
// 音頻
bgAudio: {
default: null,
type: cc.AudioClip
},
btnAudio: {
default: null,
type: cc.AudioClip
},
dropAudio: {
default: null,
type: cc.AudioClip
},
pauseResumeAudio: {
default: null,
type: cc.AudioClip
},
removeAudio: {
default: null,
type: cc.AudioClip
},
loseAudio: {
default: null,
type: cc.AudioClip
}
},
首先我們在onLoad方法中循環播放背景音樂:
// Game.js
onLoad () {
...
// 播放背景音樂
this.bgAudio = cc.audioEngine.playMusic(this.bgAudio, true);
cc.audioEngine.setMusicVolume(0.7);
},
這裏之所以要獲取音頻ID並保存在this.bgAudio,是因爲我們之後還需要停止該背景音樂。
然後分別給移動、旋轉、下落和暫停按鈕添加音效(音效不循環播放):
// Game.js
leftBtn() {
if (this.isPaused)
return;
cc.audioEngine.playEffect(this.btnAudio, false);
...
},
rotateBtn() {
if (this.isPaused)
return;
cc.audioEngine.playEffect(this.btnAudio, false);
...
},
dropBtn() {
if (this.isPaused)
return;
cc.audioEngine.playEffect(this.dropAudio, false);
...
},
rightBtn() {
if (this.isPaused)
return;
cc.audioEngine.playEffect(this.btnAudio, false);
...
},
pauseResume() {
...
cc.audioEngine.playEffect(this.pauseResumeAudio, false);
},
消除音效添加如下:
// Game.js
dropConfirmedTiles (lines) {
// 讓其他未消除的方塊下落
if (lines.length) {
...
cc.audioEngine.playEffect(this.removeAudio, false);
}
},
最後是失敗時候播放的音效:
// Game.js
lose () {
...
cc.audioEngine.stop(this.bgAudio); // 停止播放背景音樂
cc.audioEngine.playEffect(this.loseAudio); // 播放失敗音效
},
遊戲失敗,則停止背景音樂,播放失敗音效。
到這裏三個方面我們都已經實現了。有沒有覺得記錄分數的文本字體有點不好看?在下一節,筆者將教大家如何來製作自己的位圖字體。