• Chrome自带恐龙小游戏的源码研究(一)


    目录

    Chrome自带恐龙小游戏的源码研究(一)——绘制地面

    Chrome自带恐龙小游戏的源码研究(二)——绘制云朵

    Chrome自带恐龙小游戏的源码研究(三)——昼夜交替

    Chrome自带恐龙小游戏的源码研究(四)——绘制障碍物

    Chrome自带恐龙小游戏的源码研究(五)——绘制霸王龙

    Chrome自带恐龙小游戏的源码研究(六)——跳跃

    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 };

    运行效果:

     

    这样地面的绘制及滚动就完成了。

  • 相关阅读:
    网线接线分类
    MongoDB修改用户密码
    win10计算器和商店英文改中文
    电脑微信双开
    ajax
    get和post的区别
    javascript中各种继承方式的优缺点
    原型
    高阶函数的封装
    深浅拷贝
  • 原文地址:https://www.cnblogs.com/undefined000/p/trex_1.html
Copyright © 2020-2023  润新知