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

效果如下:

 

这样云朵就绘制好了。

posted @ 2016-11-19 15:04  逐影  阅读(...)  评论(...编辑  收藏