在上一篇《Chrome自带恐龙小游戏的源码研究(一)》中实现了地面的绘制和运动,这一篇主要研究云朵的绘制。

  云朵的绘制通过Cloud构造函数完成。Cloud实现代码如下:

 Cloud.config = {
HEIGHT:14, //云朵sprite的高度
MAX_CLOUD_GAP:400, //两朵云之间的最大间隙
MAX_SKY_LEVEL:30, //云朵的最大高度
MIN_CLOUD_GAP:100, //两朵云之间的最小间隙
MIN_SKY_LEVEL:71, //云朵的最小高度
WIDTH:46, //云朵sprite的宽度
MAX_CLOUDS:6,//最大云朵数量
CLOUD_FREQUENCY:.5 //云朵出现频率
}; //用于存储云朵
Cloud.clouds = []; /**
* canvas 用于绘制的画布
* spritePos 在雪碧图中的坐标
* containerWidth 容器宽度
*/ function Cloud(canvas,spritePos,containerWidth) {
this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this.spritePos = spritePos;
this.containerWidth = containerWidth;
this.xPos = containerWidth; //云朵初始x坐标在屏幕外
this.yPos = 0; //云朵初始高度
this.remove = false; //是否移除 //云朵之间的间隙400~100
this.cloudGap = getRandomNum(Cloud.config.MIN_CLOUD_GAP,Cloud.config.MAX_CLOUD_GAP);
this.init();
}

主要的逻辑代码在Cloud的原型链中:

 Cloud.prototype = {
init:function () {
//设置云朵的高度为随机30~71
this.yPos = getRandomNum(Cloud.config.MAX_SKY_LEVEL,Cloud.config.MIN_SKY_LEVEL);
this.draw();
},
draw:function () {
this.ctx.save();
var sourceWidth = Cloud.config.WIDTH,
sourceHeight = Cloud.config.HEIGHT; this.ctx.drawImage(imgSprite,
this.spritePos.x,this.spritePos.y,
sourceWidth,sourceHeight,
this.xPos,this.yPos,
sourceWidth,sourceHeight);
this.ctx.restore();
},
//添加云朵并控制其移动
updateClouds:function(speed) {
var numClouds = Cloud.clouds.length;
if(numClouds) {
for(var i = numClouds - 1; i >= 0; i--) {
Cloud.clouds[i].update(speed);
} var lastCloud = Cloud.clouds[numClouds - 1]; //若当前存在的云朵数量小于最大云朵数量 //并且云朵位置大于间隙时 //随机添加云朵
if(numClouds < Cloud.config.MAX_CLOUDS &&
(DEFAULT_WIDTH - lastCloud.xPos) > lastCloud.cloudGap &&
Cloud.config.CLOUD_FREQUENCY > Math.random()) {
this.addCloud();
} //过滤掉已经移出屏幕外的云朵
Cloud.clouds = Cloud.clouds.filter(function(obj){
return !obj.remove;
});
} else {
this.addCloud();
}
},
update:function(speed) {
//仅绘制符合条件的云朵
if(!this.remove) {
//向左移动
this.xPos -= Math.ceil(speed);
this.draw(); if(!this.isVisible()) {
this.remove = true;
}
}
},
//判断云朵是否移出屏幕外
isVisible:function() {
return this.xPos + Cloud.config.WIDTH > 0;
},
//将云朵添加至数组
addCloud:function () {
var cloud = new Cloud(this.canvas,spriteDefinition.CLOUD,DEFAULT_WIDTH);
Cloud.clouds.push(cloud);
}
};

最后测试一下这个方法:

 window.onload = function () {
var h = new HorizonLine(c,spriteDefinition.HORIZON);
var cloud = new Cloud(c,spriteDefinition.CLOUD,DEFAULT_WIDTH);
var startTime = 0;
(function draw(time) {
ctx.clearRect(0,0,600,150);
time = time || 0;
h.update(time - startTime,3);
cloud.updateClouds(0.2);
startTime = time;
window.requestAnimationFrame(draw,c);
})();
};

效果如下:

 

// this.bumpThreshold ? this.dimensions.WIDTH : 0;
},
draw:function() {
this.ctx.drawImage(imgSprite,
this.sourceXPos[0], this.spritePos.y,
this.dimensions.WIDTH, this.dimensions.HEIGHT,
this.xPos[0],this.yPos,
this.dimensions.WIDTH,this.dimensions.HEIGHT);

this.ctx.drawImage(imgSprite,
this.sourceXPos[1], this.spritePos.y,
this.dimensions.WIDTH, this.dimensions.HEIGHT,
this.xPos[1],this.yPos,
this.dimensions.WIDTH,this.dimensions.HEIGHT);

},
updateXPos:function(pos,increment) {
var line1 = pos,
line2 = pos === 0 ? 1 : 0;

this.xPos[line1] -= increment;
this.xPos[line2] = this.xPos[line1] + this.dimensions.WIDTH;

if(this.xPos[line1] = 0; i--) {
Cloud.clouds[i].update(speed);
}
var lastCloud = Cloud.clouds[numClouds - 1];
if(numClouds lastCloud.cloudGap &&
Cloud.config.CLOUD_FREQUENCY > Math.random()) {
this.addCloud();
}

Cloud.clouds = Cloud.clouds.filter(function(obj){
return !obj.remove;
});
} else {
this.addCloud();
}
},
update:function(speed) {
if(!this.remove) {
//向左移动
this.xPos -= Math.ceil(speed);
this.draw();

if(!this.isVisible()) {
this.remove = true;
}
}

},
//判断云朵是否移出屏幕外
isVisible:function() {
return this.xPos + Cloud.config.WIDTH > 0;
},
addCloud:function () {
var cloud = new Cloud(this.canvas,spriteDefinition.CLOUD,DEFAULT_WIDTH);
Cloud.clouds.push(cloud);
}
};

window.onload = function () {
var h = new HorizonLine(c,spriteDefinition.HORIZON);
var cloud = new Cloud(c,spriteDefinition.CLOUD,DEFAULT_WIDTH);
var startTime = 0;
(function draw(time) {
ctx.clearRect(0,0,600,150);
time = time || 0;
h.update(time - startTime,3);
cloud.updateClouds(0.2);
startTime = time;
window.requestAnimationFrame(draw,c);
})();
};
// ]]>

这样云朵就绘制好了。

最新文章

  1. 如果你也会C#,那不妨了解下F#(4):了解函数及常用函数
  2. Python In Action:一、入门小例子
  3. PD4F将HTML转换为PDF乱码问题
  4. @Html.Partials 加载分布视图传参数
  5. AJAX是什么? AJAX的交互模型(流程)?同步和异步的区别? AJAX跨域的解决办法?
  6. 关于 三星 I9100 (水货)
  7. Boost库
  8. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**
  9. 你不知道的JavaScript上卷笔记
  10. 使用GDI绘制文本
  11. TCP连接之未连接队列的理解[转]
  12. properties基本用法
  13. 使用vba做一个正则表达式提取文本工具
  14. 拼多多、饿了么、蚂蚁金服Java面试题大集合
  15. 【Spark调优】小表join大表数据倾斜解决方案
  16. CAN通信详解
  17. D - Football (aka Soccer)
  18. CSS 样式属性
  19. Spring之Method Injection
  20. Zookeeper命令行zkCli.sh&amp;zkServer.sh的使用(四)

热门文章

  1. 从零开始学习OpenCL开发(一)架构【转】
  2. [SaltStack] Crontab部署
  3. 属性动画详解一(Property Animation)
  4. nodejs后台启动
  5. 洛谷 P2089 烤鸡【DFS递归/10重枚举】
  6. Codeforces 761E Dasha and Puzzle(构造)
  7. HDFS写文件过程分析
  8. Algorithm | Sort
  9. Codeforces 869 C The Intriguing Obsession
  10. 《C++编程思想》第二章 数 据 抽 象(原书代码+习题+答案)