phaser2->3:來個打地鼠試水

本文中phaser具體版本 phaser2:2.8.1
phaser3:3.17.0html

1、實現效果
2、實現細節
3、項目總結
4、參考文檔前端

1、實現效果

效果圖片

體驗地址
源碼地址(phaser2&phaser3):https://github.com/jinglecjy/phaser-dadishu/
體驗地址:https://jinglecjy.github.io/phaser-dadishu/ver-phaser2/dist/

2、實現細節

這個demo實際上是以前學習phaser2的時候作的,如今用來改爲phaser3,恰好能夠接觸一下新的API變更有多大。
按照遊戲實現的邏輯順序,下面捋一捋用到的Phaser3 API,同時也與Phaser2 API進行簡單對比。git

第一步:初始化遊戲new Phaser.Game

初始化畫布參數,包括畫布寬高,渲染方式,並將其插入dom結構中。phaser3中用scenes替代了phaser2中的states,爲了不與state machines概念混淆。
遊戲中的一個scene是一個獨立的場景,擁有本身的獨立資源,包括相機系統、顯示列表、更新步驟、事件處理、物理系統等等。遊戲一次只能執行一個scene,一個場景經過多個鉤子函數來維護,包括init、preload、create、update等。github

// phaser 3:https://photonstorm.github.io/phaser3-docs/Phaser.Types.Core.html#.GameConfig
conf = {
  width: 750, 
  height: 750/window.innerWidth*window.innerHeight,
  type: Phaser.AUTO, // 渲染方法
  parent: 'container', // 將包含遊戲畫布的dom元素
  backgroundColor: '#f9c04c', 
  scale: {
      mode: Phaser.Scale.FIT // 縮放模式,此處按比例調整畫布大小,至關於contain
  },
  scene: { // 初始化場景,遊戲最開始狀態
    init: function(){ 
        // 當場景開始時第一個執行,能夠用於初始化變量或重定向到其餘場景 
    },
    preload: function(){ 
        // 第二個執行的函數,預加載遊戲資源,不會在這裏建立對象 
    },
    create: function(){
        // 當preload完成以後執行,preload的資源加載完成,能夠在這裏建立對象 
    },
    update: function(){ 
        // 畫布更新,在遊戲的每一幀都執行 
    },
    // ...... 其餘函數
  }
}
game = new Phaser.Game(conf);

// phaser 2:http://phaser.io/docs/2.6.2/Phaser.Game.html
game = new Phaser.Game(750, 750/window.innerWidth*window.innerHeight, Phaser.AUTO, 'container', 
  { // 初始化場景,遊戲最開始狀態
    init: function(){ 
        // 當場景開始時第一個執行,能夠用於初始化變量或重定向到其餘場景 
    },
    preload: function(){ 
        // 第二個執行的函數,預加載遊戲資源,不會在這裏建立對象 
    },
    create: function(){
        // 當preload完成以後執行,preload的資源加載完成,能夠在這裏建立對象 
    },
    update: function(){ 
        // 畫布更新,在遊戲的每一幀都執行 
    },
    // ...... 其餘函數
  })

複製代碼

第二步:預加載資源

預加載資源操做通常在preload函數中執行,這一部分的API,phaser2和phaser3基本一致,不過phaser3對遊戲對象結構進行了修改,phaser2中是樹狀結構,遊戲中全部對象都來自於根對象Phaser.Game,對象也擁有本身的子對象。phaser3中將這些對象拆解出來,遊戲對象Phaser.Game不包含其餘對象組,且對象組不具備任何的位置或者屬性。json

// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Loader.LoaderPlugin.html
preload: function () {
    console.log("start loading ...");
    this.numbersJson = require('../json/numbers.json');

    // loader掛載在Phaser.Scene下
    this.load.image('bg', './img/holes-bg.png');
    this.load.image('hamster', './img/hamster.png');
    this.load.image('hammer', './img/hammer.png');
    this.load.image('lightning', './img/lightning.png');
    this.load.atlas('sprite_numbers', './img/numbers.png', this.numbersJson);
    this.load.on('complete', loadProgress);

    function loadProgress(loader, finishedNum) {
        console.log(`${finishedNum}個資源加載完畢,能夠開始遊戲了!`);
        $(".cjy_panel .start_btn").click(function () {
            // 移除開始界面
            $(".cjy_panel").hide();
            customGame.scene.start('play');
        })
    }
}
// phaser2: http://phaser.io/docs/2.6.2/Phaser.Loader.html
preload: function () {
  console.log("start loading ...");
  this.numbersJson = require('../json/numbers.json');
  console.log(window.customGame)
  
  // 這些屬性在Phaser3中已被移除,須要經過初始化配置
  window.customGame.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
  window.customGame.stage.backgroundColor = '#f9c04c';

  // loader掛載在Phaser.game下
  window.customGame.load.image('bg', './img/holes-bg.png');
  window.customGame.load.image('hamster', './img/hamster.png');
  window.customGame.load.image('hammer', './img/hammer.png');
  window.customGame.load.image('lightning', './img/lightning.png');
  window.customGame.load.atlasJSONHash('sprite_numbers', './img/numbers.png', '', this.numbersJson);
  window.customGame.load.onLoadComplete.add(loadProgress, this);
  function loadProgress() {
    console.log('資源加載完畢,能夠開始遊戲啦!')
    $(".cjy_panel .start_btn").click(function () {
        console.log("開始遊戲!");
        // 移除開始界面
        $(".cjy_panel").hide();
        customGame.state.start('play');
    })
  }
}
複製代碼

第三步:建立對象

建立對象操做通常在create函數中執行,這一部分的API基本一致,差異與load類似,都是因爲修改了總體數據結構致使的。bash

// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.GameObjectCreator.html
// 對象的建立
this.hammer = this.add.sprite(hammerx, hammery, 'hammer').setOrigin(0, 0.8);

// phaser2: http://phaser.io/docs/2.6.2/Phaser.GameObjectFactory.html
this.hammer = customGame.add.sprite(hammerx, hammery, 'hammer');
this.hammer.anchor.setTo(0, 0.8);
複製代碼

第四步:動畫

phaser2和phaser3都提供了內置tween動畫供開發者使用,相比較於phaser2,phaser3中的tween動畫配置更加靈活豐富,具體完整的配置項列表能夠參照官方文檔數據結構

// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Tweens.TweenManager.html
this.tweens.add({
  targets: [this.hammer],
  angle: 45,
  duration: 50,
  callbackScope: this,
  ease: 'Linear'
})

// phaser2: http://phaser.io/docs/2.6.2/Phaser.Tween.html
var rotateTween = customGame.add.tween(this.hammer);
rotateTween.to({
    angle: 45
}, 50, Phaser.Easing.Cubic.In, true);
複製代碼

第五步:交互行爲

phaser自己沒有dom概念,全部的交互都須要依賴phaser自身的API,經過Phaser.Input統一管理全部的input事件。當交互發生時,與之交互的Phaser.Game對象將向下分發事件,phaser3能夠在scene/gameObject中監聽該事件,不一樣的位置監聽事件其做用域不一樣,優先級也不一樣,優先級較高的事件處理器可阻止向低優先級事件傳遞(stop propagation)。dom

// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Input.Events.html
this.input.on('pointerdown', onTap, this);
function onTap(pointer,currentlyOver) { ... }

// phaser2: http://phaser.io/docs/2.6.2/Phaser.Input.html
customGame.input.onTap.add(onTap, this);
function onTap(pointer, doubleTap) { ... }
複製代碼

第六步:計時器

// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Time.TimerEvent.html
this.time.addEvent({
  loop: true,
  delay: 1000,
  callback: timerFn,
  callbackScope: this
})

// phaser2: http://phaser.io/docs/2.6.2/Phaser.Timer.html#loop
customGame.time.events.loop(Phaser.Timer.SECOND, this.timerFn, this); //利用時鐘對象來重複產生管道
customGame.time.events.start();
複製代碼

3、項目總結

一些能夠改進優化的細節:ide

  • 【前端】資源預加載與遊戲過程應當在同一個scene中,以前沒捋清楚邏輯,把這兩個步驟拆開了
  • 【交互】瘋狂點擊頁面會出現不少個小錘子,短期內屢次點擊應該只響應一次
  • 【交互】打到地鼠時的反饋感增強,好比地鼠有暈眩動效/音效提示/+1效果等等
  • 【玩法】地鼠出現時間愈來愈快
  • 【玩法】主角多樣化,除了地鼠還能夠有炸彈/手拿禮物的地鼠/其餘道具,分數不一樣

phaser2上手較快,API簡單,官方文檔示例比較豐富,值得繼續探索,後續會試水一下物理引擎。phaser3是正在開發的版本,相較於phaser2 API變化較多,文檔完善度不夠,基本上是查源碼猜API。試水過程能夠感覺到phaser3對API設計從新考量,好比用對象來代替原有的基本數據類型做爲函數參數,可讀性和靈活性更佳。另外,phaser3加強了camera的功能,新增了對Matter.js物理引擎的支持,對2D骨骼動畫的支持等等,此處不進行贅述,詳細的能夠查看phaser官網的具體公告,或者是參考文章 全新Phaser3遊戲引擎特性一覽(來自凹凸實驗室)
關於自學:我的以爲phaser API的學習方法最直觀的是在控制檯打印一下,尤爲是對於初學者來講,對於其中的結構沒有清晰的認識,直接看文檔容易混亂,具體使用也能夠參照官方示例。 彩虹屁結束以後,不得不說,若是是項目實際使用,建議仍是使用穩定版本phaser2,簡單的小遊戲仍是夠用的。函數

6、參考文檔

  1. Phaser官網:http://phaser.io/
  2. Phaser2 API文檔:http://phaser.io/docs/2.6.2/index
  3. Phaser3 API文檔:https://photonstorm.github.io/phaser3-docs/
  4. Phaser3官方示例:https://labs.phaser.io/
  5. 全新Phaser3遊戲引擎特性一覽:https://aotu.io/notes/2018/12/23/phaser3/
相關文章
相關標籤/搜索