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

運行效果:

 

這樣地面的繪制及滾動就完成了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM