從零到一:用Phaser.js寫意地開發小遊戲(Chapter 5 - 遊戲大功告成)

圖片描述

回顧

上一節咱們完成了遊戲核心場景play的大部分工做,能操控主角,能隨機掉落蘋果了。那麼這一節咱們來完成遊戲剩餘的部分,主要是計算分數、如何結束遊戲等等。git

正式開始

第一步:接住蘋果得分
  • 主角加入物理運動github

  • 檢測接觸事件編程

  • 接到蘋果後,讓蘋果消失,並加分segmentfault

對主角的修改:app

game.physics.enable(man); // 加入物理運動
man.body.allowGravity = false; // 清除重力影響

檢測接觸事件要寫在play場景的update生命週期內,意思爲每次更新視圖都會去檢測主角和蘋果是否有接觸,有的話,則執行pickApple方法。ide

this.update = function() {
    // 監聽接觸事件
    game.physics.arcade.overlap(man, apples, pickApple, null, this);
}

接觸事件則很是簡單,調用apple的kill方法,則可讓蘋果從場景中清除。同時,咱們更新一下分數。字體

// 接觸事件
function pickApple(man, apple) {
    apple.kill();
    title.text = ++score;
}

示例代碼:https://jsfiddle.net/Vincent_...優化


第二步:蘋果掉地上,遊戲結束
  • 檢測蘋果與場景邊緣的接觸動畫

  • 一旦接觸,則遊戲結束,跳轉到結束場景this

  • 佈置結束場景,並顯示分數

  • 爲結束場景添加點擊事件,點擊後再玩一次

onWorldBounds屬性可設置爲一個Phaser.Signal對象,當開啓了collideWorldBounds而且接觸到場景邊緣時,將觸發Signal的事件。另外,這個特殊的Signal提供了上下左右四個值來讓咱們判斷物體到底接觸的是哪條邊,考慮到有些蘋果會接觸到左右兩邊,咱們只在和下邊界接觸的時候才結束遊戲。

// 設置蘋果與遊戲邊緣碰撞,
apple.body.collideWorldBounds = true;
apple.body.onWorldBounds = new Phaser.Signal();
apple.body.onWorldBounds.add(function(apple, up, down, left, right) {
    if (down) {
        apple.kill();
        game.state.start('over', true, false, score);
    }
});

佈置結束場景,和以前佈置其餘場景同樣,添加背景、文本等等。不一樣的是此次多了init這個生命週期,主要是因爲在play場景中跳轉到這個場景時會帶上score,這個score會傳入init這個生命週期的方法中。

// 結束場景
over: function() {
    var score = 0;
    this.init = function() {
        score = arguments[0];
    }
    this.create = function() {
        // 添加背景
        var bg = game.add.image(0, 0, 'bg');
        bg.width = game.world.width;
        bg.height = game.world.height;
        // 添加文本
        var title = game.add.text(game.world.centerX, game.world.height * 0.25, '遊戲結束', {
            fontSize: '40px',
            fontWeight: 'bold',
            fill: '#f2bb15'
        });
        title.anchor.setTo(0.5, 0.5);
        var scoreStr = '你的得分是:'+score+'分';
        var scoreText = game.add.text(game.world.centerX, game.world.height * 0.4, scoreStr, {
            fontSize: '30px',
            fontWeight: 'bold',
            fill: '#f2bb15'
        });
        scoreText.anchor.setTo(0.5, 0.5);
    }
}

最後咱們在結束場景添加一個點擊事件,點擊後跳轉到play場景,再玩一次。

var remind = game.add.text(game.world.centerX, game.world.height * 0.6, '點擊任意位置再玩一次', {
    fontSize: '20px',
    fontWeight: 'bold',
    fill: '#f2bb15'
});
remind.anchor.setTo(0.5, 0.5);
// 添加點擊事件
game.input.onTap.add(function() {
    game.state.start('play');
});

示例代碼:https://jsfiddle.net/Vincent_...


第三步:添加得分效果
  • 爲不一樣蘋果設置不一樣的得分

  • 接到蘋果時添加對應的得分圖片到場景中

  • 爲得分圖片添加過渡效果

先來介紹一下Phaser的過渡:

要使用過渡,首先要建立過渡對象,傳入的是要應用過渡效果的對象,例如apple。

// 建立過渡對象
game.add.tween(obj);

而後使用得最多的是Tween的to方法,也就是過渡到指定狀態的方法。能夠指定過渡時間曲線,延遲、是否重複、過渡時間等等參數,使用Tween已經能夠實現大部分的動畫效果。

clipboard.png

因而咱們修改以前的pickApple方法,也就是接到蘋果後的方法。

function pickApple(man, apple) {
    var point = 1;
    var img = 'one';
    if (apple.type === 'red') {
        point = 3;
        img = 'three';
    } else if (apple.type === 'yellow') {
        point = 5;
        img = 'five';
    }
    // 添加得分圖片
    var goal = game.add.image(apple.x, apple.y, img);
    var goalImg = game.cache.getImage(img);
    goal.width = apple.width;
    goal.height = goal.width / (goalImg.width / goalImg.height);
    goal.alpha = 0;
    // 添加過渡效果
    var showTween = game.add.tween(goal).to({
        alpha: 1,
        y: goal.y - 20
    }, 100, Phaser.Easing.Linear.None, true, 0, 0, false);
    showTween.onComplete.add(function() {
        var hideTween = game.add.tween(goal).to({
            alpha: 0,
            y: goal.y - 20
        }, 100, Phaser.Easing.Linear.None, true, 200, 0, false);
        hideTween.onComplete.add(function() {
            goal.kill();
        });
    });
    // 更新分數
    score += point;
    title.text = score;
    // 清除蘋果
    apple.kill();
}

示例代碼:https://jsfiddle.net/Vincent_...


第四步:加入炸彈,豐富音效
  • 隨機掉落炸彈

  • 加入接到蘋果或炸彈的音效

  • 接到炸彈後遊戲結束

要想隨機掉落炸彈很是簡單,只須要在以前的appleTypes裏面加入bomb便可,同時若是有其餘東西(例如梨子)要加入的話也能夠這樣。

var appleTypes = ['green', 'red', 'yellow', 'bomb'];

同時,因爲咱們不接炸彈,所以炸彈掉到地上也不會致使遊戲結束,所以修改一下代碼:

apple.body.onWorldBounds.add(function(apple, up, down, left, right) {
    if (down) {
        apple.kill();
        if (apple.type !== 'bomb') game.state.start('over', true, false, score);
    }
});

接到蘋果和炸彈時播放音效,這個很簡單,直接調用音頻對象的play方法便可。接到炸彈後結束和蘋果掉地上的調用方式是同樣的。咱們繼續來修改pickApple方法:

function pickApple(man, apple) {
    if (apple.type === 'bomb') {
        // 播放音效
        bombMusic.play();
        game.state.start('over', true, false, score);
    } else {
        var point = 1;
        var img = 'one';
        if (apple.type === 'red') {
            point = 3;
            img = 'three';
        } else if (apple.type === 'yellow') {
            point = 5;
            img = 'five';
        }
        // 添加得分圖片
        var goal = game.add.image(apple.x, apple.y, img);
        var goalImg = game.cache.getImage(img);
        goal.width = apple.width;
        goal.height = goal.width / (goalImg.width / goalImg.height);
        goal.alpha = 0;
        // 添加過渡效果
        var showTween = game.add.tween(goal).to({
            alpha: 1,
            y: goal.y - 20
        }, 100, Phaser.Easing.Linear.None, true, 0, 0, false);
        showTween.onComplete.add(function() {
            var hideTween = game.add.tween(goal).to({
                alpha: 0,
                y: goal.y - 20
            }, 100, Phaser.Easing.Linear.None, true, 200, 0, false);
            hideTween.onComplete.add(function() {
                goal.kill();
            });
        });
        // 更新分數
        score += point;
        title.text = score;
        // 清除蘋果
        apple.kill();
        // 播放音效
        scoreMusic.play();
    }
}

示例代碼:https://jsfiddle.net/Vincent_...


大功告成

遊戲終於完成了它的邏輯,算是一個完整的遊戲了。固然了,效果遠未達到理想,要說的話,遊戲水很是深,這個系列的教程只是從零到一,引導你們接觸並上手Phaser.js。

這裏能夠拋出一些優化的方向,你們也能夠當作Phaser的練習題目去作:

  • 遊戲中字體的更換

  • 地面應該和小恐龍底部持平,而非屏幕底部,如何實現?

  • 如今三種蘋果和炸彈的出現機率是隨機的,如何調整它們各自的出現機率?

  • 如今蘋果和炸彈出現的時間間隔是固定的,如何隨着遊戲進行加快節奏?

  • 如何調整遊戲難度梯度?

  • 如今炸彈和蘋果有可能會相鄰出現,致使很難接到蘋果而不碰到炸彈,如何避免?

  • ……

原本沒想寫這麼多點的,一不當心。可見遊戲優化的空間仍是很大的,但願你們能繼續發掘Phaser.js的潛力,作出更多的優秀的小遊戲~

Github地址:https://github.com/VincentPat...

掃描下面二維碼的話也能夠用手機查看效果了:

圖片描述

未完待續...?

回顧:

若是接下來有時間整理的話,會補充一篇Phaser.js的實戰技巧和注意事項。本系列文章寫做純粹我的喜愛,若有寫得不嚴謹或不正確的地方,還請多多包涵。第一次花這麼長時間寫技術分享,仍是用那句話勉勵本身:

但願我是真的喜歡編程,由始至終。

若是你喜歡這幾篇文章,或者說從零到一這個系列,給我點個贊,我就心滿意足了。

相關文章
相關標籤/搜索