内容简介:文章首发于我的上一篇文章:《这个游戏结束时的
文章首发于我的 个人博客
前言
上一篇文章:《 Chrome 小恐龙游戏源码探究九 -- 游戏碰撞检测 》实现了游戏的碰撞检测,这一篇文章中将利用碰撞检测的结果,实现游戏的结束。
绘制 Game Over 面板
这个游戏结束时的 Game Over 面板是通过 GameOverPanel 类绘制的。
定义 GameOverPanel 类:
/**
* 游戏结束面板类
* @param {!HTMLCanvasElement} 画布元素
* @param {Object} textImgPos 文字 "Game Over" 在雪碧图中的位置
* @param {Object} restartImgPos 重置按钮在雪碧图中的位置
* @param {!Object} dimensions 游戏画布的尺寸
*/
function GameOverPanel(canvas, textImgPos, restartImgPos, dimensions) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.canvasDimensions = dimensions;
this.textImgPos = textImgPos;
this.restartImgPos = restartImgPos;
this.draw();
};
相关的配置参数,以及原型链上的方法:
// 配置参数
GameOverPanel.dimensions = {
TEXT_X: 0, // 文字 "Game Over" 的 x 坐标
TEXT_Y: 13,
TEXT_WIDTH: 191, // 文字 "Game Over" 的宽度
TEXT_HEIGHT: 11,
RESTART_WIDTH: 36, // 重置按钮的宽度
RESTART_HEIGHT: 32,
};
GameOverPanel.prototype = {
draw: function() {
var dimensions = GameOverPanel.dimensions;
var centerX = this.canvasDimensions.WIDTH / 2;
// 文字 "Game Over"
var textSourceX = dimensions.TEXT_X;
var textSourceY = dimensions.TEXT_Y;
var textSourceWidth = dimensions.TEXT_WIDTH;
var textSourceHeight = dimensions.TEXT_HEIGHT;
var textTargetX = Math.round(centerX - (dimensions.TEXT_WIDTH / 2));
var textTargetY = Math.round((this.canvasDimensions.HEIGHT - 25) / 3);
var textTargetWidth = dimensions.TEXT_WIDTH;
var textTargetHeight = dimensions.TEXT_HEIGHT;
// 重置按钮
var restartSourceWidth = dimensions.RESTART_WIDTH;
var restartSourceHeight = dimensions.RESTART_HEIGHT;
var restartTargetX = centerX - (dimensions.RESTART_WIDTH / 2);
var restartTargetY = this.canvasDimensions.HEIGHT / 2;
textSourceX += this.textImgPos.x;
textSourceY += this.textImgPos.y;
// 文字 "Game over"
this.ctx.drawImage(Runner.imageSprite,
textSourceX, textSourceY, textSourceWidth, textSourceHeight,
textTargetX, textTargetY, textTargetWidth, textTargetHeight);
// 重置按钮
this.ctx.drawImage(Runner.imageSprite,
this.restartImgPos.x, this.restartImgPos.y,
restartSourceWidth, restartSourceHeight,
restartTargetX, restartTargetY, dimensions.RESTART_WIDTH,
dimensions.RESTART_HEIGHT);
}
};
然后需要在游戏结束时,调用 GameOverPanel 类。
在 gameOver 方法中调用 GameOverPanel 类,并更新小恐龙的状态和一些标志位:
Runner.prototype = {
// 游戏结束
gameOver: function () {
this.stop();
+ this.crashed = true; // 小恐龙撞到了障碍物
+ this.distanceMeter.achievement = false; // 结束分数闪动特效
+ // 更新小恐龙为碰撞状态
+ this.tRex.update(100, Trex.status.CRASHED);
+ // 绘制游戏结束面板
+ if (!this.gameOverPanel) {
+ this.gameOverPanel = new GameOverPanel(this.canvas,
+ this.spriteDef.TEXT_SPRITE, this.spriteDef.RESTART,
+ this.dimensions);
+ } else {
+ this.gameOverPanel.draw();
+ }
if (this.distanceRan > this.highestScore) {
this.highestScore = Math.ceil(this.distanceRan);
this.distanceMeter.setHighScore(this.highestScore); // 保存最高分
}
// 重置时间
this.time = getTimeStamp();
},
};
补充数据:
Runner.spriteDefinition = {
LDPI: {
// ...
+ RESTART: {x: 2, y: 2}, // 重置游戏按钮
},
};
前面的文章中,为了演示效果,我们把 gameOver 方法的调用临时放在了判断页面是否失焦的 onVisibilityChange 方法中。现在我们就不需要这个临时调用了,删除即可。 gameOver 实际的调用如下:
Runner.prototype = {
update: function () {
// ...
if (this.playing) {
// ...
// 碰撞检测
var collision = hasObstacles &&
- checkForCollision(this.horizon.obstacles[0], this.tRex, this.ctx);
+ checkForCollision(this.horizon.obstacles[0], this.tRex);
+ if (!collision) {
this.distanceRan += this.currentSpeed * deltaTime / this.msPerFrame;
if (this.currentSpeed < this.config.MAX_SPEED) {
this.currentSpeed += this.config.ACCELERATION;
}
+ } else {
+ this.gameOver();
+ }
var playAchievementSound = this.distanceMeter.update(deltaTime,
Math.ceil(this.distanceRan));
// ...
}
// ...
},
};
这样就实现了结束游戏后, Game Over 面板的绘制,效果如下:
查看添加和修改的代码, 戳这里
重新开始游戏
想要重新开始游戏,无非就是把保存的数据清零以及把标志位给重置:
Runner.prototype = {
// 重新开始游戏
restart: function() {
if (!this.raqId) {
this.runningTime = 0; // 重置游戏运行时间
this.setPlayStatus(true); // 游戏重置为进行状态
this.paused = false; // 游戏没有暂停
this.crashed = false; // 小恐龙没有撞到障碍物
this.distanceRan = 0; // 重置游戏移动距离(分数)
this.currentSpeed = this.config.SPEED; // 重置游戏当前的速度
this.time = getTimeStamp(); // 重置计时器
this.clearCanvas(); // 清空画布
this.distanceMeter.reset(); // 重置分数类
this.horizon.reset(); // 重置背景类
this.tRex.reset(); // 重置小恐龙类
this.invert(true); // 重置页面为没有进行颜色反转
this.update(); // 重置后更新游戏
}
},
};
其中 Trex 类上的 reset 方法已经定义过了。 DistanceMeter 、 Horizon 类上的 reset 方法定义如下:
DistanceMeter.prototype = {
// 重置当前分数为 '00000'
reset: function() {
this.update(0); // 更新分数
this.achievement = false; // 分数不进行闪动特效
}
};
Horizon.prototype = {
// 重置背景类
reset: function() {
this.obstacles = []; // 清空障碍物
this.horizonLine.reset(); // 重置地面
this.nightMode.reset(); // 重置夜晚模式
},
};
同样的, HorizonLine 、 NightMode 类上的 reset 方法定义如下:
HorizonLine.prototype = {
reset: function() {
// 重置两段地面的坐标
this.xPos[0] = 0;
this.xPos[1] = HorizonLine.dimensions.WIDTH;
},
};
NightMode.prototype = {
reset: function() {
this.currentPhase = 0; // 重置月期
this.opacity = 0; // 重置夜晚模式中的物体透明度
this.update(false); // 重置夜晚模式位未激活状态
},
};
最后,调用 restart 方法:
Runner.prototype = {
onKeyUp: function(e) {
var keyCode = String(e.keyCode);
var isjumpKey = Runner.keyCodes.JUMP[keyCode];
if (this.isRunning() && isjumpKey) { // 跳跃
this.tRex.endJump();
} else if (Runner.keyCodes.DUCK[keyCode]) { // 躲避状态
this.tRex.speedDrop = false;
this.tRex.setDuck(false);
+ } else if (this.crashed) {
+ var deltaTime = getTimeStamp() - this.time;
+
+ // 按下回车键或者等待 750 毫秒后,按下空格键,重新开始游戏
+ if (Runner.keyCodes.RESTART[keyCode] ||
+ (deltaTime >= this.config.GAMEOVER_CLEAR_TIME &&
+ Runner.keyCodes.JUMP[keyCode])) {
+ this.restart();
+ }
+ }
},
};
效果如下:
查看添加和修改的代码, 戳这里
加载游戏音效
TODO
Demo 体验地址:[]() TODO
游戏的其他要素
到这里,我们已经把游戏的必要功能都实现了。原游戏中,还实现了移动端适配,高分屏的适配,是否需要进入街机模式的处理,游戏画布对浏览器窗口大小的自适应。
这些功能我们就不再实现,感兴趣的可以自行尝试。
结语
利用十多天的业余时间探究了小恐龙游戏的源码,收获很多,也为自己以后开发 H5 游戏提供了一定的思路。
由于水平有限,如果文章存在有歧义或错误的地方,欢迎评论指出。
(完)
| 上一篇 | 下一篇 | Chrome 小恐龙游戏源码探究九 -- 游戏碰撞检测 | 无 |
以上所述就是小编给大家介绍的《Chrome 小恐龙游戏源码探究完 -- 游戏结束和其他要素》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Chrome 小恐龙游戏源码探究六 -- 记录游戏分数
- Chrome 小恐龙游戏源码探究九 -- 游戏碰撞检测
- Chrome 小恐龙游戏源码探究五 -- 随机绘制障碍
- Chrome 小恐龙游戏源码探究二 -- 让地面动起来
- Chrome 小恐龙游戏源码探究八 -- 奔跑的小恐龙
- 跨域不完全探究
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Beginning ASP.NET 4 in C# and Vb
Imar Spaanjaars / Wrox / 2010-3-19 / GBP 29.99
This book is for anyone who wants to learn how to build rich and interactive web sites that run on the Microsoft platform. With the knowledge you gain from this book, you create a great foundation to ......一起来看看 《Beginning ASP.NET 4 in C# and Vb》 这本书的介绍吧!