但是每种敌机的逻辑都是一样的,只是里面有一些参数不太一样,所以这里把敌机抽象出来一个类,类中的一些方法也很简单,包括初始化,开火,被敌机打中,产生等等逻辑。这里简单说一下,被打中后消灭的爆炸效果。其实爆炸效果也是使用了对象池,因为同一刻可能存在好几个爆炸点,而爆炸结束后同样需要回收动画资源,所以也通过一个池子进行管理。每次发生爆炸的时候,从池子中拿出一个爆炸的动画对象,然后播放动画,完毕后再将爆炸资源回收。
function Enemy(config) { this.init = function() { this.enemys = game.add.group(); this.enemys.enableBody = true; this.enemys.createMultiple(config.selfPool, config.selfPic); this.enemys.setAll('outOfBoundsKill', true); this.enemys.setAll('checkWorldBounds', true); // 敌人的子弹 this.enemyBullets = game.add.group(); this.enemyBullets.enableBody = true; this.enemyBullets.createMultiple(config.bulletsPool, config.bulletPic); this.enemyBullets.setAll('outOfBoundsKill', true); this.enemyBullets.setAll('checkWorldBounds', true); // 敌人的随机位置范围 this.maxWidth = game.width - game.cache.getImage(config.selfPic).width; // 产生敌人的定时器 game.time.events.loop(Phaser.Timer.SECOND * config.selfTimeInterval, this.generateEnemy, this); // 敌人的爆炸效果 this.explosions = game.add.group(); this.explosions.createMultiple(config.explodePool, config.explodePic); this.explosions.forEach(function(explosion) { explosion.animations.add(config.explodePic); }, this); } // 产生敌人 this.generateEnemy = function() { var e = this.enemys.getFirstExists(false); if(e) { e.reset(game.rnd.integerInRange(0, this.maxWidth), -game.cache.getImage(config.selfPic).height); e.life = config.life; e.body.velocity.y = config.velocity; } } // 敌人开火 this.enemyFire = function() { this.enemys.forEachExists(function(enemy) { var bullet = this.enemyBullets.getFirstExists(false); if(bullet) { if(game.time.now > (enemy.bulletTime || 0)) { bullet.reset(enemy.x + config.bulletX, enemy.y + config.bulletY); bullet.body.velocity.y = config.bulletVelocity; enemy.bulletTime = game.time.now + config.bulletTimeInterval; } } }, this); }; // 打中了敌人 this.hitEnemy = function(myBullet, enemy) { try { config.firesound.play(); } catch(e) {} myBullet.kill(); enemy.life--; if(enemy.life <= 0) { try { config.crashsound.play(); } catch(e) {} enemy.kill(); var explosion = this.explosions.getFirstExists(false); explosion.reset(enemy.body.x, enemy.body.y); explosion.play(config.explodePic, 30, false, true); score += config.score; config.game.updateText(); } }; }碰撞检测,可以使用phaser中的game.physics.arcade.overlap,也是十分的方便,指定两个对象进行碰撞后,需要回调的函数。
游戏中场景是一个非常重要的场景,也是这个游戏的核心,讲到这里已经差不多了,更加具体的逻辑,大家自己看源码进行分析吧。
结束场景
结束场景相对就比较简单了,背景、版权、飞机、分数、两个按钮,将它们排布好就行了。
在这里想介绍一下分享功能的实现。因为一般来说,我们做的游戏会放到微信中进行分享,分享给我们的小伙伴们。