Chrome自帶恐龍小游戲的源碼研究(二)


  在上一篇《Chrome自帶恐龍小游戲的源碼研究(一)》中實現了地面的繪制和運動,這一篇主要研究雲朵的繪制。

  雲朵的繪制通過Cloud構造函數完成。Cloud實現代碼如下:

 1 Cloud.config = {
 2     HEIGHT:14,  //雲朵sprite的高度
 3     MAX_CLOUD_GAP:400,  //兩朵雲之間的最大間隙
 4     MAX_SKY_LEVEL:30,   //雲朵的最大高度
 5     MIN_CLOUD_GAP:100,  //兩朵雲之間的最小間隙
 6     MIN_SKY_LEVEL:71,   //雲朵的最小高度
 7     WIDTH:46,    //雲朵sprite的寬度
 8     MAX_CLOUDS:6,//最大雲朵數量
 9     CLOUD_FREQUENCY:.5 //雲朵出現頻率
10 };
11 
12 //用於存儲雲朵
13 Cloud.clouds = [];
14 
15 
16 
17 /**
18 * canvas 用於繪制的畫布
19 * spritePos 在雪碧圖中的坐標
20 * containerWidth 容器寬度
21 */
22 
23 function Cloud(canvas,spritePos,containerWidth) {
24     this.canvas = canvas;
25     this.ctx = canvas.getContext("2d");
26     this.spritePos = spritePos;
27     this.containerWidth = containerWidth;
28     this.xPos = containerWidth; //雲朵初始x坐標在屏幕外
29     this.yPos = 0;  //雲朵初始高度
30     this.remove = false;    //是否移除
31 
32     //雲朵之間的間隙400~100
33     this.cloudGap = getRandomNum(Cloud.config.MIN_CLOUD_GAP,Cloud.config.MAX_CLOUD_GAP);
34     this.init();
35 }

主要的邏輯代碼在Cloud的原型鏈中:

 1 Cloud.prototype = {
 2     init:function () {
 3         //設置雲朵的高度為隨機30~71
 4         this.yPos = getRandomNum(Cloud.config.MAX_SKY_LEVEL,Cloud.config.MIN_SKY_LEVEL);
 5         this.draw();
 6     },
 7     draw:function () {
 8         this.ctx.save();
 9         var sourceWidth = Cloud.config.WIDTH,
10             sourceHeight = Cloud.config.HEIGHT;
11 
12         this.ctx.drawImage(imgSprite,
13             this.spritePos.x,this.spritePos.y,
14             sourceWidth,sourceHeight,
15             this.xPos,this.yPos,
16             sourceWidth,sourceHeight);
17         this.ctx.restore();
18     },
19     //添加雲朵並控制其移動
20     updateClouds:function(speed) {
21         var numClouds = Cloud.clouds.length;
22         if(numClouds) {
23             for(var i = numClouds - 1; i >= 0; i--) {
24                 Cloud.clouds[i].update(speed);
25             }
26 
27             var lastCloud = Cloud.clouds[numClouds - 1];
28 
29             //若當前存在的雲朵數量小於最大雲朵數量
30 
31             //並且雲朵位置大於間隙時
32 
33             //隨機添加雲朵
34             if(numClouds < Cloud.config.MAX_CLOUDS &&
35                 (DEFAULT_WIDTH - lastCloud.xPos) > lastCloud.cloudGap &&
36                 Cloud.config.CLOUD_FREQUENCY > Math.random()) {
37                 this.addCloud();
38             }
39 
40             //過濾掉已經移出屏幕外的雲朵
41             Cloud.clouds = Cloud.clouds.filter(function(obj){
42                 return !obj.remove;
43             });
44         } else {
45             this.addCloud();
46         }
47     },
48     update:function(speed) {
49         //僅繪制符合條件的雲朵
50         if(!this.remove) {
51             //向左移動
52             this.xPos -= Math.ceil(speed);
53             this.draw();
54 
55             if(!this.isVisible()) {
56                 this.remove = true;
57             }
58         }
59     },
60     //判斷雲朵是否移出屏幕外
61     isVisible:function() {
62         return this.xPos + Cloud.config.WIDTH > 0;
63     },
64     //將雲朵添加至數組
65     addCloud:function () {
66         var cloud = new Cloud(this.canvas,spriteDefinition.CLOUD,DEFAULT_WIDTH);
67         Cloud.clouds.push(cloud);
68     }
69 };

最后測試一下這個方法:

 1 window.onload = function () {
 2     var h = new HorizonLine(c,spriteDefinition.HORIZON);
 3     var cloud = new Cloud(c,spriteDefinition.CLOUD,DEFAULT_WIDTH);
 4     var startTime = 0;
 5     (function draw(time) {
 6         ctx.clearRect(0,0,600,150);
 7         time = time || 0;
 8         h.update(time - startTime,3);
 9         cloud.updateClouds(0.2);
10         startTime = time;
11         window.requestAnimationFrame(draw,c);
12     })();
13 };

效果如下:

 

這樣雲朵就繪制好了。


免責聲明!

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



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