上一节咱们完成了游戏核心场景play的大部分工做,能操控主角,能随机掉落苹果了。那么这一节咱们来完成游戏剩余的部分,主要是计算分数、如何结束游戏等等。git
主角加入物理运动github
检测接触事件编程
接到苹果后,让苹果消失,并加分segmentfault
对主角的修改:app
game.physics.enable(man); // 加入物理运动 man.body.allowGravity = false; // 清除重力影响
检测接触事件要写在play场景的update生命周期内,意思为每次更新视图都会去检测主角和苹果是否有接触,有的话,则执行pickApple方法。ide
this.update = function() { // 监听接触事件 game.physics.arcade.overlap(man, apples, pickApple, null, this); }
接触事件则很是简单,调用apple的kill方法,则可让苹果从场景中清除。同时,咱们更新一下分数。字体
// 接触事件 function pickApple(man, apple) { apple.kill(); title.text = ++score; }
示例代码:https://jsfiddle.net/Vincent_...优化
检测苹果与场景边缘的接触动画
一旦接触,则游戏结束,跳转到结束场景this
布置结束场景,并显示分数
为结束场景添加点击事件,点击后再玩一次
onWorldBounds属性可设置为一个Phaser.Signal对象,当开启了collideWorldBounds而且接触到场景边缘时,将触发Signal的事件。另外,这个特殊的Signal提供了上下左右四个值来让咱们判断物体到底接触的是哪条边,考虑到有些苹果会接触到左右两边,咱们只在和下边界接触的时候才结束游戏。
// 设置苹果与游戏边缘碰撞, apple.body.collideWorldBounds = true; apple.body.onWorldBounds = new Phaser.Signal(); apple.body.onWorldBounds.add(function(apple, up, down, left, right) { if (down) { apple.kill(); game.state.start('over', true, false, score); } });
布置结束场景,和以前布置其余场景同样,添加背景、文本等等。不一样的是此次多了init这个生命周期,主要是因为在play场景中跳转到这个场景时会带上score,这个score会传入init这个生命周期的方法中。
// 结束场景 over: function() { var score = 0; this.init = function() { score = arguments[0]; } this.create = function() { // 添加背景 var bg = game.add.image(0, 0, 'bg'); bg.width = game.world.width; bg.height = game.world.height; // 添加文本 var title = game.add.text(game.world.centerX, game.world.height * 0.25, '游戏结束', { fontSize: '40px', fontWeight: 'bold', fill: '#f2bb15' }); title.anchor.setTo(0.5, 0.5); var scoreStr = '你的得分是:'+score+'分'; var scoreText = game.add.text(game.world.centerX, game.world.height * 0.4, scoreStr, { fontSize: '30px', fontWeight: 'bold', fill: '#f2bb15' }); scoreText.anchor.setTo(0.5, 0.5); } }
最后咱们在结束场景添加一个点击事件,点击后跳转到play场景,再玩一次。
var remind = game.add.text(game.world.centerX, game.world.height * 0.6, '点击任意位置再玩一次', { fontSize: '20px', fontWeight: 'bold', fill: '#f2bb15' }); remind.anchor.setTo(0.5, 0.5); // 添加点击事件 game.input.onTap.add(function() { game.state.start('play'); });
示例代码:https://jsfiddle.net/Vincent_...
为不一样苹果设置不一样的得分
接到苹果时添加对应的得分图片到场景中
为得分图片添加过渡效果
先来介绍一下Phaser的过渡:
要使用过渡,首先要建立过渡对象,传入的是要应用过渡效果的对象,例如apple。
// 建立过渡对象 game.add.tween(obj);
而后使用得最多的是Tween的to方法,也就是过渡到指定状态的方法。能够指定过渡时间曲线,延迟、是否重复、过渡时间等等参数,使用Tween已经能够实现大部分的动画效果。
因而咱们修改以前的pickApple方法,也就是接到苹果后的方法。
function pickApple(man, apple) { var point = 1; var img = 'one'; if (apple.type === 'red') { point = 3; img = 'three'; } else if (apple.type === 'yellow') { point = 5; img = 'five'; } // 添加得分图片 var goal = game.add.image(apple.x, apple.y, img); var goalImg = game.cache.getImage(img); goal.width = apple.width; goal.height = goal.width / (goalImg.width / goalImg.height); goal.alpha = 0; // 添加过渡效果 var showTween = game.add.tween(goal).to({ alpha: 1, y: goal.y - 20 }, 100, Phaser.Easing.Linear.None, true, 0, 0, false); showTween.onComplete.add(function() { var hideTween = game.add.tween(goal).to({ alpha: 0, y: goal.y - 20 }, 100, Phaser.Easing.Linear.None, true, 200, 0, false); hideTween.onComplete.add(function() { goal.kill(); }); }); // 更新分数 score += point; title.text = score; // 清除苹果 apple.kill(); }
示例代码:https://jsfiddle.net/Vincent_...
随机掉落炸弹
加入接到苹果或炸弹的音效
接到炸弹后游戏结束
要想随机掉落炸弹很是简单,只须要在以前的appleTypes里面加入bomb便可,同时若是有其余东西(例如梨子)要加入的话也能够这样。
var appleTypes = ['green', 'red', 'yellow', 'bomb'];
同时,因为咱们不接炸弹,所以炸弹掉到地上也不会致使游戏结束,所以修改一下代码:
apple.body.onWorldBounds.add(function(apple, up, down, left, right) { if (down) { apple.kill(); if (apple.type !== 'bomb') game.state.start('over', true, false, score); } });
接到苹果和炸弹时播放音效,这个很简单,直接调用音频对象的play
方法便可。接到炸弹后结束和苹果掉地上的调用方式是同样的。咱们继续来修改pickApple方法:
function pickApple(man, apple) { if (apple.type === 'bomb') { // 播放音效 bombMusic.play(); game.state.start('over', true, false, score); } else { var point = 1; var img = 'one'; if (apple.type === 'red') { point = 3; img = 'three'; } else if (apple.type === 'yellow') { point = 5; img = 'five'; } // 添加得分图片 var goal = game.add.image(apple.x, apple.y, img); var goalImg = game.cache.getImage(img); goal.width = apple.width; goal.height = goal.width / (goalImg.width / goalImg.height); goal.alpha = 0; // 添加过渡效果 var showTween = game.add.tween(goal).to({ alpha: 1, y: goal.y - 20 }, 100, Phaser.Easing.Linear.None, true, 0, 0, false); showTween.onComplete.add(function() { var hideTween = game.add.tween(goal).to({ alpha: 0, y: goal.y - 20 }, 100, Phaser.Easing.Linear.None, true, 200, 0, false); hideTween.onComplete.add(function() { goal.kill(); }); }); // 更新分数 score += point; title.text = score; // 清除苹果 apple.kill(); // 播放音效 scoreMusic.play(); } }
示例代码:https://jsfiddle.net/Vincent_...
游戏终于完成了它的逻辑,算是一个完整的游戏了。固然了,效果远未达到理想,要说的话,游戏水很是深,这个系列的教程只是从零到一,引导你们接触并上手Phaser.js。
这里能够抛出一些优化的方向,你们也能够当作Phaser的练习题目去作:
游戏中字体的更换
地面应该和小恐龙底部持平,而非屏幕底部,如何实现?
如今三种苹果和炸弹的出现几率是随机的,如何调整它们各自的出现几率?
如今苹果和炸弹出现的时间间隔是固定的,如何随着游戏进行加快节奏?
如何调整游戏难度梯度?
如今炸弹和苹果有可能会相邻出现,致使很难接到苹果而不碰到炸弹,如何避免?
……
原本没想写这么多点的,一不当心。可见游戏优化的空间仍是很大的,但愿你们能继续发掘Phaser.js的潜力,作出更多的优秀的小游戏~
Github地址:https://github.com/VincentPat...
扫描下面二维码的话也能够用手机查看效果了:
若是接下来有时间整理的话,会补充一篇Phaser.js的实战技巧和注意事项。本系列文章写做纯粹我的喜爱,若有写得不严谨或不正确的地方,还请多多包涵。第一次花这么长时间写技术分享,仍是用那句话勉励本身:
若是你喜欢这几篇文章,或者说从零到一这个系列,给我点个赞,我就心满意足了。