首页 > 代码库 > Chrome自带恐龙小游戏的源码研究(一)
Chrome自带恐龙小游戏的源码研究(一)
众所周知,Chrome浏览器在网络不通的情况下,会出现一个霸王龙翻越障碍的小游戏:
这个游戏做得小巧精致,于是探究了一下它的源码,发现代码写得相当严谨并且富有技巧性,用来学习再好不过了。
游戏虽然看起来简单,但也有几千行的代码量。主要包括五个构造函数:
游戏逻辑控制函数Runner
背景管理函数Horizon
- 地面 (HorizonLine)
- 云朵 (Cloud)
- 昼夜更替 (NightMode)
- 障碍物 (Obstacle)
霸王龙函数Trex
分数记录函数DistanceMeter
游戏结束操作面板函数GameOverPanel
其余的方法还包含一些对移动设备的适配、针对不同屏幕加载不同的资源 、声音的播放等等。这是游戏用到的雪碧图:
为方便研究,从简单的背景管理函数开始。首先是地面的绘制。地面绘制通过HorizonLine完成:
1 //定义属性 2 3 HorizonLine.dimensions = { 4 WIDTH:600, //宽600 5 HEIGHT:12, //高12像素 6 YPOS:127 //在canvas中的位置 7 }; 8 9 var spriteDefinition = {10 HORIZON: {x: 2, y: 54}//地面在雪碧图中的位置11 };12 13 14 15 /**16 * canvas 地面将绘制到此画布上17 * spritePos 地面在雪碧图中的坐标18 */19 function HorizonLine(canvas,spritePos) {20 this.spritePos = spritePos;21 this.canvas = canvas;22 this.ctx = canvas.getContext("2d");23 this.dimensions = HorizonLine.dimensions;24 25 //在雪碧图中坐标为2和602处分别为不同的地形26 this.sourceXPos = [this.spritePos.x,this.spritePos.x + this.dimensions.WIDTH];27 28 this.xPos = []; //地面在画布中的x坐标29 this.yPos = 0; //地面在画布中的y坐标30 31 this.bumpThreshold = 0.5; //随机地形系数32 33 this.setSourceDimesions();34 this.draw();35 }
再来看看HorizonLine原型链中的方法:
1 HorizonLine.prototype = { 2 setSourceDimesions:function() { 3 //地面在画布上的位置 4 this.xPos = [0,this.dimensions.WIDTH];//0,600 5 this.yPos = this.dimensions.YPOS; 6 }, 7 //随机地形 8 getRandomType:function() { 9 //返回第一段地形或者第二段地形10 return Math.random() > this.bumpThreshold ? this.dimensions.WIDTH : 0;11 },12 draw:function() {13 //使用9参数的drawImage方法14 this.ctx.drawImage(imgSprite,15 this.sourceXPos[0], this.spritePos.y,16 this.dimensions.WIDTH, this.dimensions.HEIGHT,17 this.xPos[0],this.yPos,18 this.dimensions.WIDTH,this.dimensions.HEIGHT);19 20 this.ctx.drawImage(imgSprite,21 this.sourceXPos[1], this.spritePos.y,22 this.dimensions.WIDTH, this.dimensions.HEIGHT,23 this.xPos[1],this.yPos,24 this.dimensions.WIDTH,this.dimensions.HEIGHT);25 },26 updateXPos:function(pos,increment) {27 var line1 = pos,28 line2 = pos === 0 ? 1 : 0;29 30 this.xPos[line1] -= increment;31 this.xPos[line2] = this.xPos[line1] + this.dimensions.WIDTH;32 33 //若第一段地面完全移出canvas外34 if(this.xPos[line1] <= -this.dimensions.WIDTH) {35 //则将其移动至canvas外右侧36 this.xPos[line1] += this.dimensions.WIDTH * 2;37 //同时将第二段地面移动至canvas内38 this.xPos[line2] = this.xPos[line1] - this.dimensions.WIDTH;39 40 //选择随机地形41 this.sourceXPos[line1] = this.getRandomType() + this.spritePos.x;42 }43 },44 update:function(deltaTime,speed) {45 var increment = Math.floor(speed * (FPS / 1000) * deltaTime);46 47 if(this.xPos[0] <= 0) {//交换地面一和二48 this.updateXPos(0, increment);49 } else {50 this.updateXPos(1, increment);51 }52 this.draw();53 },54 reset:function() {55 this.xPos[0] = 0;56 this.xPos[1] = this.dimensions.WIDTH;57 }58 };
原型链中的方法实现了地面的运动和随机地形。
最后测试一下这一段代码:
1 window.onload = function () { 2 var h = new HorizonLine(canvas,spriteDefinition.HORIZON); 3 var startTime = 0; 4 (function draw(time) { 5 ctx.clearRect(0,0,600,150); 6 time = time || 0; 7 h.update(time - startTime,3); 8 startTime = time; 9 window.requestAnimationFrame(draw);10 })();11 };
运行效果:
这样地面的绘制及滚动就完成了。
Chrome自带恐龙小游戏的源码研究(一)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。