Phaser学习之路——飞机星战

一直想尝试html5游戏的制作,闲来无事,发现了phaser这个html5的游戏开发框架,尝试完成一个小游戏,此博文就作为自己的开发和学习的记录。

1 什么是Phaser

Phaser是一个开源的桌面和移动HTML5 2D游戏开发框架,官网地址: http://www.phaser.io/

2  环境搭建

没什么说的,官网下载phaser的js文件,html页面进行引入

3  创建项目

创建一个项目文件StarCrash,文件层级如下:

Phaser学习之路——飞机星战

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的基本入门吧,游戏比较简单,后期扩展的点还是挺多的,有时间可以继续优化。

相关推荐