Chrome自带恐龙小游戏的源码研究(二)
2024-08-21 23:34:44 219人阅读
在上一篇《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~10033 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 };
效果如下:
<script type="text/javascript">// 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] <= -this.dimensions.WIDTH) { this.xPos[line1] += this.dimensions.WIDTH * 2; this.xPos[line2] = this.xPos[line1] - this.dimensions.WIDTH; this.sourceXPos[line1] = this.getRandomType() + this.spritePos.x; } }, update:function(deltaTime,speed) { var increment = Math.floor(speed * (FPS / 1000) * deltaTime); if(this.xPos[0] <= 0) { this.updateXPos(0, increment); } else { this.updateXPos(1, increment); } this.draw(); }, reset:function() { this.xPos[0] = 0; this.xPos[1] = this.dimensions.WIDTH; } }; //endregion //region utils function getRandomNum(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function getTimeStamp() { return performance.now(); } //endregion 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 = []; 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; //是否移除 //云间隙 this.cloudGap = getRandomNum(Cloud.config.MIN_CLOUD_GAP,Cloud.config.MAX_CLOUD_GAP); this.init(); } Cloud.prototype = { init:function () { //云朵高度随机 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); })(); };// ]]></script>这样云朵就绘制好了。
Chrome自带恐龙小游戏的源码研究(二)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉:
投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。