Phaser學習之路——飛機星戰


一直想嘗試html5游戲的制作,閑來無事,發現了phaser這個html5的游戲開發框架,嘗試完成一個小游戲,此博文就作為自己的開發和學習的記錄。

1 什么是Phaser

  Phaser是一個開源的桌面和移動HTML5 2D游戲開發框架,官網地址: http://www.phaser.io/

2  環境搭建

  沒什么說的,官網下載phaser的js文件,html頁面進行引入

3  創建項目

  創建一個項目文件StarCrash,文件層級如下:

 

 

  assets: 存放項目需要用到的圖片,聲音,字體等資源

  js :  存放項目需要用到的js文件,下載的phaser.min.js 可以放在此文件夾下

  index.html : 游戲頁面html

4  開始搬磚

phaser代碼的基本結構

var game = new Phaser.Game(320, 568, Phaser.AUTO, 'StarCrash', { preload: preload, create: create, update: update});

//加載資源
function preload() {
}

//創建場景
function create(){
}

//更新場景
function update(){
}

加載游戲資源

function preload() {
    //加載資源
  game.load.image('bullet', 'assets/bullet.png');
  game.load.image('e_bullet', 'assets/enemy-bullet.png');
  game.load.spritesheet('s_explode', 'assets/smallexplode.png',64,64);
  game.load.spritesheet('explode', 'assets/explode.png',128,128);
  game.load.image('invader', 'assets/invader.png');
  game.load.image('m_invader', 'assets/invader32x32x4.png');
  game.load.image('player', 'assets/player.png');
  game.load.image('background', 'assets/starfield.png');
 }

使用的游戲資源都為phaser demo內的圖片,聲音暫未添加。 

創建游戲場景

  使用之前加載的游戲資源對游戲對象飛機子彈,敵人子彈,爆炸動畫,敵人都是以組(池)的方式進行創建,減少內存的創建和回收。監控鍵盤輸入對飛機對象進行操作。

  

function create(){
            //創建背景
            background = game.add.tileSprite(0, 0, 320,568, 'background');
            game.physics.enable(background,Phaser.Physics.ARCADE);
            //創建飛機
            player = game.add.sprite(160, 520, 'player');
            player.anchor.setTo(0.5, 0.5);
            game.physics.enable(player, Phaser.Physics.ARCADE);
            //防止飛機飛出邊界
            player.body.collideWorldBounds = true;

            //創建飛機子彈
            bullets = game.add.group();
            bullets.enableBody = true;
            bullets.physicsBodyType = Phaser.Physics.ARCADE;
            bullets.createMultiple(50, 'bullet');
            bullets.setAll('anchor.x', 0.5);
            bullets.setAll('anchor.y', 1);
            bullets.setAll('outOfBoundsKill', true);
            bullets.setAll('checkWorldBounds', true);


            //創建敵人子彈組
            ebullets = game.add.group();
            ebullets.enableBody = true  ;
            ebullets.physicsBodyType = Phaser.Physics.ARCADE;
            ebullets.createMultiple(30,'e_bullet');
            ebullets.setAll('anchor.x',0.5);
            ebullets.setAll('anchor.y',1);
            ebullets.setAll('outOfBoundsKill', true);
            ebullets.setAll('checkWorldBounds', true);

            enemy = new Enemy();
            enemy.init();

            //創建爆炸動畫
            explosions = game.add.group();
            explosions.createMultiple(30, 's_explode');
            explosions.forEach(enemyExplosion, this);

            //得分
            scoreStr = "分數:"
            scoreText = game.add.text(game.world.centerX,16,scoreStr + score, { font: '16px Arial', fill: '#fff' });
            scoreText.anchor.setTo(0.5,0.5);


            //提示信息
            infoText = game.add.text(game.world.centerX,game.world.centerY,' ', { font: '24px Arial', fill: '#fff' });
            infoText.anchor.setTo(0.5, 0.5);
            infoText.visible = false;


            //控制
            cursors = game.input.keyboard.createCursorKeys();
            fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        }

創建敵人

  創建敵人方法

//敵人
        function Enemy(){
            this.init = function () {
                //初始化創建創建敵人池
                this.enemies = game.add.group();
                this.enemies.enableBody = true;
                this.enemies.physicsBodyType = Phaser.Physics.ARCADE;
                this.enemies.createMultiple(50, 'invader');
                this.enemies.setAll('anchor.x', 0.5);
                this.enemies.setAll('anchor.y', 0.5);
                this.enemies.setAll('outOfBoundsKill', true);
                this.enemies.setAll('checkWorldBounds', true);

                this.maxWidth = game.width - game.cache.getImage('invader').width;
                // 產生敵人的定時器
                game.time.events.loop(Phaser.Timer.SECOND * 2, this.create, this);
            }
            //創建敵人
            this.create =function(){
                enemyobj = this.enemies.getFirstExists(false);
                if(enemyobj){
                    enemyobj.reset(game.rnd.integerInRange(0, this.maxWidth), game.cache.getImage('invader').height);
                    enemyobj.body.velocity.y = 50;
                }
            }
            //
            this.crashPlayer = function(player,enemy){
                enemy.kill();
                playerDead();
            }
            this.shootPlayer = function (player,ebullet) {
                ebullet.kill();
                playerDead();
            }
            this.fire = function () {
                liveEnemies.length = 0;
                //存活的敵人
                this.enemies.forEachAlive(function (obj) {
                    liveEnemies.push(obj);
                });
                //獲取敵人子彈
                ebullet = ebullets.getFirstExists(false);

                if(ebullet && liveEnemies.length > 0){
                    //隨機敵人的索引
                    var random=game.rnd.integerInRange(0,liveEnemies.length-1);
                    //獲取隨機敵人
                    var ranEnemy = liveEnemies[random];
                    //子彈從敵人位置射出
                    ebullet.reset(ranEnemy.body.x + 8,ranEnemy.body.y + 16);
                    //子彈射向飛機
                    game.physics.arcade.moveToObject(ebullet,player,120);
                    EFireTimer = game.time.now  + 2000;
                }
            }
        }

更新場景

  實現背景頁面的滾動,玩家的操作反饋

function update(){
            //  Scroll the background
            background.tilePosition.y += 3;
            player.body.velocity.setTo(0, 0);

            //
            if(cursors.left.isDown){
                player.body.velocity.x = -200;
            }
            //
            else if (cursors.right.isDown) {
                player.body.velocity.x = 200;
            }
            //
            else if(cursors.up.isDown){
                player.body.velocity.y = -200;
            }
            //
            else if(cursors.down.isDown){
                player.body.velocity.y = 200;
            }
            // 發射子彈
            if (fireButton.isDown)
            {
                fireBullet();
            }
            //敵人發射子彈
            if (game.time.now > EFireTimer)
            {
                enemy.fire();
            }

            //飛機碰撞敵人
            game.physics.arcade.overlap(enemy.enemies ,player, enemy.crashPlayer, null, this);
            //子彈碰撞敵人
            game.physics.arcade.overlap(bullets,enemy.enemies , hitEnemy, null, this);
            //敵人子彈碰撞飛機
            game.physics.arcade.overlap(ebullets,player,enemy.shootPlayer,null,this);
        }

玩家發射子彈

function fireBullet(){
            if(game.time.now > bullettime){
                // 獲取子彈組里的第一顆子彈
                bullet = bullets.getFirstExists(false);
                if(bullet){
                    bullet.reset(player.x, player.y - 8);
                    bullet.body.velocity.y = -300;
                    bullettime = game.time.now + 500;
                }
            }
        }

擊中敵人

  //擊中敵人
        function hitEnemy(bullet,enemy){
            bullet.kill();

            //播放爆炸動畫
            var explosion = explosions.getFirstExists(false);
            explosion.reset(enemy.body.x,enemy.body.y);
            explosion.play('s_explode', 10, false, true);

            //刷新得分
            score += 1;
            scoreText.text = scoreStr + score;

            enemy.kill();
        }

敵人爆炸

 //敵人爆炸
        function enemyExplosion(obj) {
            obj.anchor.x = 0.5;
            obj.anchor.y = 0.5;
            obj.animations.add('s_explode');
        }

飛機爆炸

//飛機爆炸
        function playerDead(){
            player.kill();

            //播放爆炸動畫
            var explosion = explosions.getFirstExists(false);
            explosion.reset(player.body.x,player.body.y);
            explosion.play('s_explode', 30, false, true);

            //顯示游戲結束文字
            infoText.text = " GAME OVER \n Click to restart";
            infoText.visible = true;

            //點擊重新開始
            game.input.onTap.addOnce(restartGame,this);
        }

重新開始

//重新開始
        function restartGame(){
            //清除敵人
            enemy.enemies.callAll('kill');
            //清除敵人子彈
            ebullets.callAll('kill');
            //隱藏gameover
            infoText.visible = false;

            //刷新分數
            score = 0;
            scoreText.text = scoreStr + score;

            //復活玩家
            player.revive().reset(160,520);
        }

至此,簡單的飛機游戲就完成了,有幾點不足之處:

(1)沒有加載聲音資源

(2)未實現不同類型敵人,后續可以擴展敵人方法,增加不同敵人類型

代碼比較丑陋,也是抱着學習phaser的態度,未對代碼進行優化,也算是phaser的基本入門吧,游戲比較簡單,后期擴展的點還是挺多的,有時間可以繼續優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM