使用Phaser開發你的第一個H5遊戲(一)

本文來自網易雲社區html

做者:王鴿web


不知你是否還記得當年風靡一時的2048這個遊戲,一個簡單而又不簡單的遊戲,總會讓你在空閒時間玩上一下子。算法


在這篇文章裏,咱們將使用開源的H5框架——Phaser來重現這個遊戲。這裏你能夠了解到遊戲內的狀態管理、Sprite元件對象等,以及如何使用Preload、Create等方法。canvas

H5遊戲框架衆多,爲什麼選擇它?數組

因爲近幾年H5的火熱,H5遊戲框架如雨後春筍般出現,甚至有不少定位不是遊戲開發的框架都被歸到這個範疇中。那麼爲何選擇Phaser?如下是我選擇它的緣由:瀏覽器

  • 支持原生JS。服務器

  • 能夠方便地在Canvas和WebGL之間切換。框架

  • 定位明確,專一H5遊戲開發。編輯器

  • 完善的文檔及示例。函數

  • 持續更新,目前Phaser 3正在開發。



2048遊戲的最終呈現效果以下


開發準備

首先訪問Phaser官網http://www.phaser.io,下載JavaScript版本的Phaser,並搭建好項目結構

項目文件結構以下:

在index.html中引入相關js文件,定義一個div做爲phaser生成canvas的父容器

<!DOCTYPE html> 
<head> 
   <meta charset="UTF-8" />
   <title>2048</title>
    <script src="js/phaser.min.js"></script>
    <script src="js/Menu.js"></script>
    <script src="js/Game.js"></script>
    <script src="js/index.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      canvas {
        margin: 0 auto;
      }
      .game {
        position: absolute;
        width: 100%;
        height: 100%;
      }
    </style>
</head>
<body>
  <div id="game" >"game"></div>
</body>


遊戲是如何進行的

在html文件中咱們已經引入了Phaser庫,這使咱們擁有了一個名爲Phaser的全局對象,經過這個對象,咱們能夠訪問Phaser庫中哪些用於構建遊戲的方法和函數。

如今咱們使用Phaser對象來建立一個遊戲實例,這個對象用來表明整個遊戲,咱們會爲他添加不一樣的狀態。

index.js,在其中建立遊戲實例,註冊各個遊戲狀態以及啓動遊戲。

//實例化遊戲對象,參數爲寬、高、渲染方式,父容器
window.game = new Phaser.Game(240, 400, Phaser.CANVAS, 'game');

//添加狀態,參數爲狀態應用的Key值,狀態所包含的對象
game.state.add('Menu', Menu);
game.state.add('Game', Game);

//狀態切換 開始遊戲
game.state.start('Menu');

Phaser中的「狀態(state)」管理使遊戲的場景切換變得很是容易,此處的「狀態」能夠看理解爲不一樣的遊戲界面,2048這個遊戲比較簡單,只須要首頁和遊戲內兩個界面便可。

  • 主頁狀態,由menu.js處理,用於加載遊戲資源並顯示遊戲開始界面,點擊開始按鈕後切換到遊戲狀態而且開始遊戲。

  • 遊戲狀態,由game.js處理,用於顯示遊戲界面、控制遊戲邏輯,遊戲結束後顯示分數面板

接下來初始化菜單狀態對象(Menu),在Menu.js中定義一個新對象Menu併爲它添加函數。狀態啓動時,首先會調用對象內的preload函數,一般加載遊戲所需資源會在這一步進行;加載完成後,調用create函數,初始化遊戲界面以及邏輯對象等等。

var Menu = {
    preload: function () {
        //加載圖像,參數爲建立元件時所使用的Key值,文件路徑
        game.load.image('background', 'assets/bg.png');
        game.load.image('btnStart', 'assets/btn-start.png');
        game.load.image('btnRestart', 'assets/btn-restart.png');
        game.load.image('logo', 'assets/logo.png');
        game.load.image('btnTryagain', 'assets/btn-tryagain.png');
    },
    create: function () {
        //建立重複元件,能夠重複圖片 通常用於重複紋理的底圖等
        game.add.tileSprite(0, 0, game.width, game.height, 'background');

        //建立圖片,此處是遊戲logo,參數爲x,y,加載圖片是所保存的Key值
        var logo = game.add.image(0, 0, 'logo');
        logo.reset((game.width - logo.width) / 2, (game.height - logo.height) / 2 - 50);

        //開始按鈕用來啓動遊戲
        var startBtn =  game.add.sprite(0, 0, 'btnStart');
        startBtn.reset((game.width - startBtn.width) / 2, (game.height - startBtn.height) / 2 + 100);
        //開啓元件點擊監聽,並添加監聽事件
        startBtn.inputEnabled = true;
        startBtn.events.onInputDown.add(this.startGame);
    },
    startGame: function () {
        //轉換狀態至遊戲界面
        game.state.start('Game');
    }
};


至此,啓動界面已經完成了,開啓本地web服務器後,在瀏覽器中打開index.html,就能夠看到遊戲的啓動界面了。


接着在Game.js開始處理遊戲的界面以及邏輯

var Game = {
    create: function () {
        //添加背景
        game.add.tileSprite(0, 0, game.width, game.height, 'background');

        //變量用於保存遊戲分數
        this.score = 0;
        this.best = 0;

        //文字樣式,font:字體字號等 fill:顏色
        var titleStyle = { font: "bold 12px Arial", fill: "#4DB3B3", boundsAlignH: "center" };
        var scoreStyle = { font: "bold 20px Arial", fill: "#FFFFFF", boundsAlignH: "center" };
        var scoreSprite = game.add.sprite(10, 10);

        //使用graphics繪製圖形做爲界面UI
        var scoreGraphics = game.add.graphics(0, 0);
        scoreGraphics.lineStyle(5, 0xA1C5C5);
        scoreGraphics.beginFill(0x308C8C);
        //繪製一個帶圓角的矩形
        scoreGraphics.drawRoundedRect(0, 0, 70, 50, 10);
        scoreGraphics.endFill();
        //把圖形添加到父容器上,便於總體調整位置等
        scoreSprite.addChild(scoreGraphics);

        //添加文字 參數爲x,y,文字內容,文字樣式
        var scoreTitle = game.add.text(0, 5, "SCORE", titleStyle);
        scoreTitle.setTextBounds(0, 0, 70, 50);
        //把文字添加到父容器上,便於總體調整位置等
        scoreSprite.addChild(scoreTitle);

        this.scoreText = game.add.text(0, 20, this.score, scoreStyle);
        this.scoreText.setTextBounds(0, 0, 70, 50);
        scoreSprite.addChild(this.scoreText);

        ......

        //添加鍵盤方向件的監聽以及監聽事件
        var up = this.game.input.keyboard.addKey(Phaser.Keyboard.UP);
        up.onDown.add(function () {...});
        var down = this.game.input.keyboard.addKey(Phaser.Keyboard.DOWN);
        down.onDown.add(function () {...});
        var left = this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
        left.onDown.add(function () {...});
        var right = this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
        right.onDown.add(function () {...});
        
        ......

        //獲取手勢滑動的X軸差值和Y軸差值 用於計算滑動方向
        var deltaX = this.game.input.activePointer.position.x - this.game.input.activePointer.positionDown.x;
        var deltaY = this.game.input.activePointer.position.y - this.game.input.activePointer.positionDown.y;
        
        ......

2048這個遊戲的規則很是簡單,開發的思路也很是明確,維護一個4*4的數組,每次觸發移動事件時遍歷數組,進行方向上的疊加判斷,而後在數組中尋找空格,隨機生成新的數字,若是沒有則遊戲結束。相關的一些開發思路以及算法優化在此也就不詳述了,你們能夠自行查閱。


資料推薦

雖然這個遊戲很是簡單,但經過這個項目,能夠了解到Phaser的多個方面。若是對此感興趣,能夠再深刻接觸如下資料:


網易雲免費體驗館,0成本體驗20+款雲產品!

更多網易研發、產品、運營經驗分享請訪問網易雲社區


相關文章:
【推薦】 Android複雜列表的實現
【推薦】 論用戶體驗測試:牛逼的功能千篇一概,好的體驗萬里挑一

相關文章
相關標籤/搜索