html5canvas开发详解可以做什么游戏

下次自动登录
现在的位置:
& 综合 & 正文
怎样用HTML5 Canvas制作一个简单的游戏
原文连接:
自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML5 Canvas制作游戏的入门教程。花了一点时间考虑怎么着手写这篇文章后,我决定先实现一个我觉得最最简单的游戏,然后一行代码一行代码地进行讲解。
让我们开始吧,首先看看game.js,当然你也可以先玩玩这个游戏(译注:附件是游戏源码,用浏览器打开其中的index.html就可以玩了,或者也可以到官网上去玩)。
附件下载地址:
1. 创建一个Canvas对象
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 480;
document.body.appendChild(canvas);
我们首先要做的是创建一个canvas对象。可以用JavaScript或HTML来做,都非常简单。此处我用的是JS。当创建了canvas之后,我们就可以获取它的上下文对象(context)、设置尺寸,并且把它加到当前文档中。
2. 载入图片
// Background image
var bgReady =
var bgImage = new Image();
bgImage.onload = function () {
bgImage.src = "images/background.png";
游戏需要图像,所以让我们载入一些图片吧。我想尽量简单化,所以只用了Image对象来做,当然,还可以将载入图像的功能封装成一个类或别的任何形式。代码中的bgReady用来标识图片是否已完全载入,只有当图片载入完成后,我们才能使用它,如果在载入完成前就对其进行绘制或渲染,JS将会报一个DOM error的错误。
我们会用到三张图片(背景、英雄、怪物),每张图片都需要这样处理。
3. 定义游戏要使用的对象
// Game objects
var hero = {
speed: 256, // movement in pixels per second
var monster = {
var monstersCaught = 0;
定义一些变量,稍后会用到。hero对象的speed属性表示英雄的移动速度(像素/秒);monster对象不会移动,所以仅仅具有一对坐标;monstersCaught表示玩家抓住的怪物数量。
4. 处理玩家输入
// Handle keyboard controls
var keysDown = {};
addEventListener("keydown", function (e) {
keysDown[e.keyCode] =
}, false);
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode];
}, false);
现在进行输入的处理。(对具有web开发背景的人来说,这是目前为止第一个具有挑战性的部分)对一般的网页来说,当用户开始输入时,可能需要马上开始播放动画或请求数据。但在这里,我们想让游戏逻辑在一个单独的地方对游戏中发生的事情进行处理。为此我们需要将用户输入保存下来以备稍后处理,而不是立即处理。
我们通过简单地将事件对应的键编码(keyCode)保存在keysDown变量中来实现。如果该变量中具有某个键编码,就表示用户目前正按下这个键。简单吧!5. 新游戏
// Reset the game when the player catches a monster
var reset = function () {
hero.x = canvas.width / 2;
hero.y = canvas.height / 2;
// Throw the monster somewhere on the screen randomly
monster.x = 32 + (Math.random() * (canvas.width - 64));
monster.y = 32 + (Math.random() * (canvas.height - 64));
通过调用reset函数来开始新游戏。该函数将英雄(即玩家角色)放到屏幕中间,然后随机选择一个位置来安置怪物。6. 更新对象
// Update game objects
var update = function (modifier) {
if (38 in keysDown) { // Player holding up
hero.y -= hero.speed *
if (40 in keysDown) { // Player holding down
hero.y += hero.speed *
if (37 in keysDown) { // Player holding left
hero.x -= hero.speed *
if (39 in keysDown) { // Player holding right
hero.x += hero.speed *
// Are they touching?
hero.x &= (monster.x + 32)
&& monster.x &= (hero.x + 32)
&& hero.y &= (monster.y + 32)
&& monster.y &= (hero.y + 32)
++monstersC
这是update函数,游戏每隔一定时间会调用它一次。它所做的第一件事情是检查用户是否按下了上下左右四个箭头键。如果是,就将我们的英雄向相应的方向移动。update有一个modifier参数,这看起来好像有点奇怪。你会在游戏的主函数即main函数中看到它,不过我在这儿先解释一下。modifier参数是一个从1开始的与时间相关的数。如果间隔刚好为1秒时,它的值就会为1,英雄移动的距离即为256像素(英雄的速度为256像素/秒);而如果间隔是0.5秒,它的值就为0.5,即英雄移动的距离为其速度的一半,以此类推。通常update函数调用的间隔很短,所以modifier的值很小,但用这种方式能够确保不管代码执行的速度怎么样,英雄的移动速度都是相同的。我们已经实现了根据用户的输入来移动英雄,但我们还可以在移动英雄时对其进行检查,以确定是否有其他事件发生。例如:英雄是否与怪物发生了碰撞——当英雄与怪物发生碰撞时,我们为玩家进行计分(monstersCaught加1)并重置游戏(调用reset函数)。7. 渲染对象
// Draw everything
var render = function () {
if (bgReady) {
ctx.drawImage(bgImage, 0, 0);
if (heroReady) {
ctx.drawImage(heroImage, hero.x, hero.y);
if (monsterReady) {
ctx.drawImage(monsterImage, monster.x, monster.y);
ctx.fillStyle = "rgb(250, 250, 250)";
ctx.font = "24px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Goblins caught: " + monstersCaught, 32, 32);
当你能够看到你的行动时游戏才会变得更有趣,所以让我们在屏幕上绘制吧。首先我们将背景图片绘制到canvas,然后是英雄和怪物。注意顺序很重要,因为任何位于表层的图片都会将其下面的像素覆盖掉。接下来是文字,这有些不同,我们调用fillText函数显示玩家的分数。因为不需要复杂的动画或者对文字进行移动,所以只是绘制一下就ok了。8. 游戏主循环
// The main game loop
var main = function () {
var now = Date.now();
var delta = now -
update(delta / 1000);
游戏的主循环用来控制游戏流程。首先我们要获得当前的时间,这样我们才能计算时间差(自上次循环以来经过的时间)。然后计算modifier的值并交给update(需要将delta除以1000以将其转换为毫秒)。最后调用render并更新记录的时间。更多关于游戏循环的内容见“”。9. 开始游戏吧
// Let's play this game!
var then = Date.now();
setInterval(main, 1); // Execute as fast as possible
快完成了,这是最后一段代码。首先调用reset来开始新游戏。(还记得吗,这会将英雄置中并随机安放怪物)。然后将起始时间保存到变量then中并启动游戏的主循环。OK!(但愿)你现在已经理解了在HTML5 Canvas中用JS来开发游戏的基础知识了。建议最好是能够自己亲自试一把!
【上篇】【下篇】利用HTML5 Canvas制作一个简单的打飞机游戏
互联网 & 发布时间: 17:41:22 & 作者:佚名 &
这篇文章主要介绍了利用HTML5 Canvas制作一个简单的打飞机游戏,作者也给出了相关的Javascript代码,需要的朋友可以参考下
之前在当耐特的DEMO里看到个打飞机的游戏,然后就把他的图片和音频扒了了下来。。。。自己凭着玩的心情重新写了一个。仅供娱乐哈。。。。。。我没有用框架,所有js都是自己写的。。。。。。所以就可以来当个简单的教程,对那些刚玩canvas的,或许能有些帮助,楼主玩canvas也不是很久,技术不是很好,请见谅哈。
  闲话不多说,先上DEMO撒:飞机游戏&& 楼主写这个人纯碎娱乐,没想着写成多正式的游戏哈。
  步入主题啦:打飞机游戏文件有index.html入口文件,allSprite.js精灵的逻辑处理文件,loading.js加载处理文件以及data.js(初始化的一些数据)。
  首先,正常的游戏基本上都需要一个loading,loading页面就是用来预加载数据的,包括精灵表图片,音频等,因为这是个小游戏,要加载的就只有一些音频和图片。里面的加载代码主要就下面这些,其他是制作loading动画的,那个比较简单,就不贴了,如果有兴趣的直接在DEMO里看控制台就行了:
loadImg:function(datas){ &&
&&&&&&&&&&&&var&_this&=& &&
&&&&&&&&&&&&var&dataIndex&=&0; &&
&&&&&&&&&&&&li(); &&
&&&&&&&&&&&&function&li(){ &&
&&&&&&&&&&&&&&&&if(datas[dataIndex].indexOf(&mp3&)=0){ &&
&&&&&&&&&&&&&&&&&&&&var&audio&=&document.createElement(&audio&); &&
&&&&&&&&&&&&&&&&&&&&document.body.appendChild(audio); &&
&&&&&&&&&&&&&&&&&&&&audio.preload&=&&auto&; &&
&&&&&&&&&&&&&&&&&&&&audio.src&=&datas[dataIndex]; &&
&&&&&&&&&&&&&&&&&&&&audio.oncanplaythrough&=&function(){ &&
&&&&&&&&&&&&&&&&&&&&&&&&this.oncanplaythrough&=&null; &&
&&&&&&&&&&&&&&&&&&&&&&&&dataIndex++; &&
&&&&&&&&&&&&&&&&&&&&&&&&if(dataIndex===datas.length){ &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&_this.percent&=&100; &&
&&&&&&&&&&&&&&&&&&&&&&&&}else&{ &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&_this.percent&=&parseInt(dataIndex/datas.length*100); &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&li.call(_this); &&
&&&&&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&}else&{ &&
&&&&&&&&&&&&&&&&&&&&preLoadImg(datas[dataIndex]&,&function(){ &&
&&&&&&&&&&&&&&&&&&&&&&&&dataIndex++; &&
&&&&&&&&&&&&&&&&&&&&&&&&if(dataIndex===datas.length){ &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&_this.percent&=&100; &&
&&&&&&&&&&&&&&&&&&&&&&&&}&else&{ &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&_this.percent&=&parseInt(dataIndex/datas.length*100); &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&li.call(_this); &&
&&&&&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&&&&&}) &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&}, &&
//再贴出preLoadImg的方法 &&
function&preLoadImg(src&,&callback){ &&
&&&&var&img&=&new&Image(); &&
&&&&img.src&=& &&
&&&&if(img.complete){ &&
&&&&&&&&callback.call(img); &&
&&&&}else&{ &&
&&&&&&&&img.onload&=&function(){ &&
&&&&&&&&&&&&callback.call(img); &&
&&&&&&&&} &&
我先在data.js里面用一个数组保存文件的链接,然后判断这些链接是图片还是音频,如果是图片就用preLoadImg加载,预加载图片的代码很简单,就是new一个图片对象,然后把链接赋给它,加载完后再回调。音频的加载则是通过生成一个HTML5的audio dom对象,把链接赋给它,audio有一个事件&canplaythrough&,浏览器预计能够在不停下来进行缓冲的情况下持续播放指定的音频/视频时,会发生 canplaythrough 事件,也就是说当canplaythrough被调用时,音频就已经被加载的差不多了,可以进行下一个音频的加载了。就这样当把所有东西都加载完后,再进行回调,开始游戏。
  游戏开始了,一个游戏,会需要很多的对象,所以我就统一写成了一个精灵对象,不同对象之间的每一帧的运动情况直接用behavior来分别编写就行了。
W.Sprite&=&function(name&,&painter&,&behaviors&,&args){ &&
&&&&if(name&!==&undefined)&this.name&=& &&
&&&&if(painter&!==&undefined)&this.painter&=& &&
&&&&this.top&=&0; &&
&&&&this.left&=&0; &&
&&&&this.width&=&0; &&
&&&&this.height&=&0; &&
&&&&this.velocityX&=&3; &&
&&&&this.velocityY&=&2; &&
&&&&this.visible&=&true; &&
&&&&this.animating&=&false; &&
&&&&this.behaviors&=& &&
&&&&this.rotateAngle&=&0; &&
&&&&this.blood&=&50; &&
&&&&this.fullBlood&=&50; &&
&&&&if(name===&plan&){ &&
&&&&&&&&this.rotateSpeed&=&0.05; &&
&&&&&&&&this.rotateLeft&=&false; &&
&&&&&&&&this.rotateRight&=&false; &&
&&&&&&&&this.fire&=&false; &&
&&&&&&&&this.firePerFrame&=&10; &&
&&&&&&&&this.fireLevel&=&1; &&
&&&&}else&if(name===&star&){ &&
&&&&&&&&this.width&=&Math.random()*2; &&
&&&&&&&&this.speed&=&1*this.width/2; &&
&&&&&&&&this.lightLength&=&5; &&
&&&&&&&&this.cacheCanvas&=&document.createElement(&canvas&); &&
&&&&&&&&thisthis.cacheCtx&=&this.cacheCanvas.getContext('2d'); &&
&&&&&&&&thisthis.cacheCanvas.width&=&this.width+this.lightLength*2; &&
&&&&&&&&thisthis.cacheCanvas.height&=&this.width+this.lightLength*2; &&
&&&&&&&&this.painter.cache(this); &&
&&&&}else&if(name===&badPlan&){ &&
&&&&&&&&this.badKind&=&1; &&
&&&&&&&&this.speed&=&2; &&
&&&&&&&&this.rotateAngle&=&Math.PI; &&
&&&&}else&if(name===&missle&){ &&
&&&&&&&&this.width&=&missleWidth; &&
&&&&}else&if(name===&boom&){ &&
&&&&&&&&this.width&=&boomWidth; &&
&&&&}else&if(name===&food&){ &&
&&&&&&&&this.width&=&40; &&
&&&&&&&&this.speed&=&3; &&
&&&&&&&&this.kind&=&&LevelUP&&&
&&&&this.toLeft&=&false; &&
&&&&this.toTop&=&false; &&
&&&&this.toRight&=&false; &&
&&&&this.toBottom&=&false; &&
&&&&this.outArcRadius&=&Math.sqrt((this.width/2*this.width/2)*2); &&
&&&&if(args){ &&
&&&&&&&&for(var&arg&in&args){ &&
&&&&&&&&&&&&this[arg]&=&args[arg]; &&
&&&&&&&&} &&
Sprite.prototype&=&{ &&
&&&&constructor:Sprite, &&
&&&&paint:function(){ &&
&&&&&&&&if(this.name===&badPlan&){this.update();} &&
&&&&&&&&if(this.painter&!==&undefined&&&&this.visible){ &&
&&&&&&&&&&&&if(this.name!==&badPlan&)&{ &&
&&&&&&&&&&&&&&&&this.update(); &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(this.name===&plan&||this.name===&missle&||this.name===&badPlan&){ &&
&&&&&&&&&&&&&&&&ctx.save(); &&
&&&&&&&&&&&&&&&&ctx.translate(this.left&,&this.top); &&
&&&&&&&&&&&&&&&&ctx.rotate(this.rotateAngle); &&
&&&&&&&&&&&&&&&&this.painter.paint(this); &&
&&&&&&&&&&&&&&&&ctx.restore(); &&
&&&&&&&&&&&&}else&{ &&
&&&&&&&&&&&&&&&&this.painter.paint(this); &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&update:function(time){ &&
&&&&&&&&if(this.behaviors){ &&
&&&&&&&&&&&&for(var&i=0;i;i++){ &&
&&&&&&&&&&&&&&&&this.behaviors[i].execute(this,time); &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
写出精灵类后,就可以通过编写每个的painter以及behavior来生成不同的对象了。接下来就是写painter了,painter分成两种,一种是普通的painter,一种就是精灵表painter,因为像爆炸动画,飞机开枪动画,都不是一张图片就能搞定的,所以就需要用到精灵表了:
而绘制这些就要为他们定制一个精灵表绘制器,下面这个是最简单的精灵表绘制器,针对游戏的复杂性可以相对的修改精灵表写法,直到合适,不过原理都大同小异,就是小修小改而已:
var&SpriteSheetPainter&=&function(cells){ &&
&&&&&&&&&&&&this.cells&=&cells&||&[]; &&
&&&&&&&&&&&&this.cellIndex&=&0; &&
&&&&&&&&} &&
&&&&&&&&SpriteSheetPainter.prototype&=&{ &&
&&&&&&&&&&&&advance:function(){ &&
&&&&&&&&&&&&&&&&if(this.cellIndex&===&this.cells.length-1){ &&
&&&&&&&&&&&&&&&&&&&&this.cellIndex&=&0; &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&else&this.cellIndex++; &&
&&&&&&&&&&&&}, &&
&&&&&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&&&&&var&cell&=&this.cells[this.cellIndex]; &&
&&&&&&&&&&&&&&&&context.drawImage(spritesheet&,&cell.x&,&cell.y&,&cell.w&,&cell.h&,&sprite.left&,&sprite.top&,&cell.w&,&cell.h); &&
&&&&&&&&&&&&} &&
&&&&&&&&}&&&&&
而普通的绘制器就更简单了,直接写一个painter,把要画的什么东西都写进去就行了。
有了精灵类和精灵表绘制器后,我们就可以把星星,飞机,子弹,爆炸对象都写出来了:下面是整个allSprite.js的代码:
(function(W){ &&
&&&&&use&strict&&&
&&&&var&planWidth&=&24, &&
&&&&&&&&planHeight&=&24, &&
&&&&&&&&missleWidth&=&70, &&
&&&&&&&&missleHeight&=&70, &&
&&&&&&&&boomWidth&=&60; &&
&&&&W.Sprite&=&function(name&,&painter&,&behaviors&,&args){ &&
&&&&&&&&if(name&!==&undefined)&this.name&=& &&
&&&&&&&&if(painter&!==&undefined)&this.painter&=& &&
&&&&&&&&this.top&=&0; &&
&&&&&&&&this.left&=&0; &&
&&&&&&&&this.width&=&0; &&
&&&&&&&&this.height&=&0; &&
&&&&&&&&this.velocityX&=&3; &&
&&&&&&&&this.velocityY&=&2; &&
&&&&&&&&this.visible&=&true; &&
&&&&&&&&this.animating&=&false; &&
&&&&&&&&this.behaviors&=& &&
&&&&&&&&this.rotateAngle&=&0; &&
&&&&&&&&this.blood&=&50; &&
&&&&&&&&this.fullBlood&=&50; &&
&&&&&&&&if(name===&plan&){ &&
&&&&&&&&&&&&this.rotateSpeed&=&0.05; &&
&&&&&&&&&&&&this.rotateLeft&=&false; &&
&&&&&&&&&&&&this.rotateRight&=&false; &&
&&&&&&&&&&&&this.fire&=&false; &&
&&&&&&&&&&&&this.firePerFrame&=&10; &&
&&&&&&&&&&&&this.fireLevel&=&1; &&
&&&&&&&&}else&if(name===&star&){ &&
&&&&&&&&&&&&this.width&=&Math.random()*2; &&
&&&&&&&&&&&&this.speed&=&1*this.width/2; &&
&&&&&&&&&&&&this.lightLength&=&5; &&
&&&&&&&&&&&&this.cacheCanvas&=&document.createElement(&canvas&); &&
&&&&&&&&&&&&this.cacheCtx&=&this.cacheCanvas.getContext('2d'); &&
&&&&&&&&&&&&this.cacheCanvas.width&=&this.width+this.lightLength*2; &&
&&&&&&&&&&&&this.cacheCanvas.height&=&this.width+this.lightLength*2; &&
&&&&&&&&&&&&this.painter.cache(this); &&
&&&&&&&&}else&if(name===&badPlan&){ &&
&&&&&&&&&&&&this.badKind&=&1; &&
&&&&&&&&&&&&this.speed&=&2; &&
&&&&&&&&&&&&this.rotateAngle&=&Math.PI; &&
&&&&&&&&}else&if(name===&missle&){ &&
&&&&&&&&&&&&this.width&=&missleW &&
&&&&&&&&}else&if(name===&boom&){ &&
&&&&&&&&&&&&this.width&=&boomW &&
&&&&&&&&}else&if(name===&food&){ &&
&&&&&&&&&&&&this.width&=&40; &&
&&&&&&&&&&&&this.speed&=&3; &&
&&&&&&&&&&&&this.kind&=&&LevelUP&&&
&&&&&&&&} &&
&&&&&&&&this.toLeft&=&false; &&
&&&&&&&&this.toTop&=&false; &&
&&&&&&&&this.toRight&=&false; &&
&&&&&&&&this.toBottom&=&false; &&
&&&&&&&&this.outArcRadius&=&Math.sqrt((this.width/2*this.width/2)*2); &&
&&&&&&&&if(args){ &&
&&&&&&&&&&&&for(var&arg&in&args){ &&
&&&&&&&&&&&&&&&&this[arg]&=&args[arg]; &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&Sprite.prototype&=&{ &&
&&&&&&&&constructor:Sprite, &&
&&&&&&&&paint:function(){ &&
&&&&&&&&&&&&if(this.name===&badPlan&){this.update();} &&
&&&&&&&&&&&&if(this.painter&!==&undefined&&&&this.visible){ &&
&&&&&&&&&&&&&&&&if(this.name!==&badPlan&)&{ &&
&&&&&&&&&&&&&&&&&&&&this.update(); &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&if(this.name===&plan&||this.name===&missle&||this.name===&badPlan&){ &&
&&&&&&&&&&&&&&&&&&&&ctx.save(); &&
&&&&&&&&&&&&&&&&&&&&ctx.translate(this.left&,&this.top); &&
&&&&&&&&&&&&&&&&&&&&ctx.rotate(this.rotateAngle); &&
&&&&&&&&&&&&&&&&&&&&this.painter.paint(this); &&
&&&&&&&&&&&&&&&&&&&&ctx.restore(); &&
&&&&&&&&&&&&&&&&}else&{ &&
&&&&&&&&&&&&&&&&&&&&this.painter.paint(this); &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&}, &&
&&&&&&&&update:function(time){ &&
&&&&&&&&&&&&if(this.behaviors){ &&
&&&&&&&&&&&&&&&&for(var&i=0;i&this.behaviors.i++){ &&
&&&&&&&&&&&&&&&&&&&&this.behaviors[i].execute(this,time); &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&W.SpriteSheetPainter&=&function(cells&,&isloop&,&endCallback&,&spritesheet){ &&
&&&&&&&&this.cells&=&cells&||&[]; &&
&&&&&&&&this.cellIndex&=&0; &&
&&&&&&&&this.dateCount&=&null; &&
&&&&&&&&this.isloop&=& &&
&&&&&&&&this.endCallback&=&endC &&
&&&&&&&&this.spritesheet&=& &&
&&&&SpriteSheetPainter.prototype&=&{ &&
&&&&&&&&advance:function(){ &&
&&&&&&&&&&&&this.cellIndex&=&this.isloop?(this.cellIndex===this.cells.length-1?0:this.cellIndex+1):(this.cellIndex+1); &&
&&&&&&&&}, &&
&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&if(this.dateCount===null){ &&
&&&&&&&&&&&&&&&&this.dateCount&=&new&Date(); &&
&&&&&&&&&&&&}else&{ &&
&&&&&&&&&&&&&&&&var&newd&=&new&Date(); &&
&&&&&&&&&&&&&&&&var&tc&=&newd-this.dateC &&
&&&&&&&&&&&&&&&&if(tc&40){ &&
&&&&&&&&&&&&&&&&&&&&this.advance(); &&
&&&&&&&&&&&&&&&&&&&&this.dateCount&=& &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(this.cellIndex&this.cells.length&||&this.isloop){ &&
&&&&&&&&&&&&&&&&var&cell&=&this.cells[this.cellIndex]; &&
&&&&&&&&&&&&&&&&ctx.drawImage(this.spritesheet&,&cell.x&,&cell.y&,&cell.w&,&cell.h&,&sprite.left-sprite.width/2&,&sprite.top-sprite.width/2&,&cell.w&,&cell.h); &&
&&&&&&&&&&&&}&else&if(this.endCallback){ &&
&&&&&&&&&&&&&&&&this.endCallback.call(sprite); &&
&&&&&&&&&&&&&&&&this.cellIndex&=&0; &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&W.controllSpriteSheetPainter&=&function(cells&,&spritesheet){ &&
&&&&&&&&this.cells&=&cells&||&[]; &&
&&&&&&&&this.cellIndex&=&0; &&
&&&&&&&&this.dateCount&=&null; &&
&&&&&&&&this.isActive&=&false; &&
&&&&&&&&this.derection&=&true; &&
&&&&&&&&this.spritesheet&=& &&
&&&&controllSpriteSheetPainter.prototype&=&{ &&
&&&&&&&&advance:function(){ &&
&&&&&&&&&&&&if(this.isActive){ &&
&&&&&&&&&&&&&&&&this.cellIndex++; &&
&&&&&&&&&&&&&&&&if(this.cellIndex&===&this.cells.length){ &&
&&&&&&&&&&&&&&&&&&&&this.cellIndex&=&0; &&
&&&&&&&&&&&&&&&&&&&&this.isActive&=&false; &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&}, &&
&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&if(this.dateCount===null){ &&
&&&&&&&&&&&&&&&&this.dateCount&=&new&Date(); &&
&&&&&&&&&&&&}else&{ &&
&&&&&&&&&&&&&&&&var&newd&=&new&Date(); &&
&&&&&&&&&&&&&&&&var&tc&=&newd-this.dateC &&
&&&&&&&&&&&&&&&&if(tc&sprite.firePerFrame){ &&
&&&&&&&&&&&&&&&&&&&&this.advance(); &&
&&&&&&&&&&&&&&&&&&&&this.dateCount&=& &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&var&cell&=&this.cells[this.cellIndex]; &&
&&&&&&&&&&&&ctx.drawImage(this.spritesheet&,&cell.x&,&cell.y&,&cell.w&,&cell.h&,&-planWidth/2&,&-planHeight/2&,&cell.w&,&cell.h); &&
&&&&&&&&} &&
&&&&W.planBehavior&=&[ &&
&&&&&&&&{execute:function(sprite,time){ &&
&&&&&&&&&&&&if(sprite.toTop){ &&
&&&&&&&&&&&&&&&&sprite.top&=&sprite.top&planHeight/2?&sprite.top&:&sprite.top-sprite.velocityY; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.toLeft){ &&
&&&&&&&&&&&&&&&&sprite.left&=&sprite.left&planWidth/2?&sprite.left&:&sprite.left-sprite.velocityX; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.toRight){ &&
&&&&&&&&&&&&&&&&sprite.left&=&sprite.left&canvas.width-planWidth/2?&sprite.left&:&sprite.left+sprite.velocityX; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.toBottom){ &&
&&&&&&&&&&&&&&&&sprite.top&=&sprite.top&canvas.height-planHeight/2?&sprite.top&:&sprite.top+sprite.velocityY; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.rotateLeft){ &&
&&&&&&&&&&&&&&&&sprite.rotateAngle&-=&sprite.rotateS &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.rotateRight){ &&
&&&&&&&&&&&&&&&&sprite.rotateAngle&+=&sprite.rotateS &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.fire&&!sprite.painter.isActive){ &&
&&&&&&&&&&&&&&&&sprite.painter.isActive&=&true; &&
&&&&&&&&&&&&&&&&this.shot(sprite); &&
&&&&&&&&&&&&} &&
&&&&&&&&}, &&
&&&&&&&&shot:function(sprite){ &&
&&&&&&&&&&&&this.addMissle(sprite&,&sprite.rotateAngle); &&
&&&&&&&&&&&&var&missleAngle&=&0.1 &&
&&&&&&&&&&&&for(var&i=1;i&sprite.fireLi++){ &&
&&&&&&&&&&&&&&&&this.addMissle(sprite&,&sprite.rotateAngle-i*missleAngle); &&
&&&&&&&&&&&&&&&&this.addMissle(sprite&,&sprite.rotateAngle+i*missleAngle); &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&var&audio&=&document.getElementsByTagName(&audio&); &&
&&&&&&&&&&&&for(var&i=0;i&audio.i++){ &&
&&&&&&&&&&&&&&&&console.log(audio[i].paused) &&
&&&&&&&&&&&&&&&&if(audio[i].src.indexOf(&shot&)&=0&&audio[i].paused){ &&
&&&&&&&&&&&&&&&&&&&&audio[i].play(); &&
&&&&&&&&&&&&&&&&&&&&break; &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&}, &&
&&&&&&&&addMissle:function(sprite&,&angle){ &&
&&&&&&&&&&&&&&&&for(var&j=0;j&missles.j++){ &&
&&&&&&&&&&&&&&&&&&&&if(!missles[j].visible){ &&
&&&&&&&&&&&&&&&&&&&&&&&&missles[j].left&=&sprite. &&
&&&&&&&&&&&&&&&&&&&&&&&&missles[j].top&=&sprite. &&
&&&&&&&&&&&&&&&&&&&&&&&&missles[j].rotateAngle&=& &&
&&&&&&&&&&&&&&&&&&&&&&&&var&missleSpeed&=&20; &&
&&&&&&&&&&&&&&&&&&&&&&&&missles[j].velocityX&=&missleSpeed*Math.sin(-missles[j].rotateAngle); &&
&&&&&&&&&&&&&&&&&&&&&&&&missles[j].velocityY&=&missleSpeed*Math.cos(-missles[j].rotateAngle); &&
&&&&&&&&&&&&&&&&&&&&&&&&missles[j].visible&=&true; &&
&&&&&&&&&&&&&&&&&&&&&&&&break; &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&W.starBehavior&=&[ &&
&&&&&&&&{execute:function(sprite,time){ &&
&&&&&&&&&&&&if(sprite.top&&&canvas.height){ &&
&&&&&&&&&&&&&&&&sprite.left&=&Math.random()*canvas. &&
&&&&&&&&&&&&&&&&sprite.top&=&Math.random()*canvas.height&-&canvas. &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&sprite.top&+=&sprite. &&
&&&&&&&&}} &&
&&&&W.starPainter&=&{ &&
&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&ctx.drawImage(sprite.cacheCanvas&,&sprite.left-sprite.width/2-sprite.lightLength&,&sprite.top-sprite.width/2-sprite.lightLength) &&
&&&&&&&&}, &&
&&&&&&&&cache:function(sprite){ &&
&&&&&&&&&&&&sprite.cacheCtx.save(); &&
&&&&&&&&&&&&var&opacity&=&0.5,addopa&=&1/sprite.lightL &&
&&&&&&&&&&&&sprite.cacheCtx.fillStyle&=&&rgba(255,255,255,0.8)&; &&
&&&&&&&&&&&&sprite.cacheCtx.beginPath(); &&
&&&&&&&&&&&&sprite.cacheCtx.arc(sprite.width/2+sprite.lightLength&,&sprite.width/2+sprite.lightLength&,&sprite.width/2&,&0&,&2*Math.PI); &&
&&&&&&&&&&&&sprite.cacheCtx.fill(); &&
&&&&&&&&&&&&for(var&i=1;i&=sprite.lightLi+=2){ &&
&&&&&&&&&&&&&&&&opacity-= &&
&&&&&&&&&&&&&&&&sprite.cacheCtx.fillStyle&=&&rgba(255,255,255,&+opacity+&)&; &&
&&&&&&&&&&&&&&&&sprite.cacheCtx.beginPath(); &&
&&&&&&&&&&&&&&&&sprite.cacheCtx.arc(sprite.width/2+sprite.lightLength&,&sprite.width/2+sprite.lightLength&,&sprite.width/2+i&,&0&,&2*Math.PI); &&
&&&&&&&&&&&&&&&&sprite.cacheCtx.fill(); &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&W.foodBehavior&=&[ &&
&&&&&&&&{execute:function(sprite,time){ &&
&&&&&&&&&&&&sprite.top&+=&sprite. &&
&&&&&&&&&&&&if(sprite.top&&&canvas.height+sprite.width){ &&
&&&&&&&&&&&&&&&&sprite.visible&=&false; &&
&&&&&&&&&&&&} &&
&&&&&&&&}} &&
&&&&W.foodPainter&=&{ &&
&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&ctx.fillStyle&=&&rgba(&+parseInt(Math.random()*255)+&,&+parseInt(Math.random()*255)+&,&+parseInt(Math.random()*255)+&,1)&&&
&&&&&&&&&&&&ctx.font=&15px&微软雅黑&&&
&&&&&&&&&&&&ctx.textAlign&=&&center&; &&
&&&&&&&&&&&&ctx.textBaseline&=&&middle&; &&
&&&&&&&&&&&&ctx.fillText(sprite.kind&,&sprite.left&,&sprite.top); &&
&&&&&&&&} &&
&&&&W.missleBehavior&=&[{ &&
&&&&&&&&execute:function(sprite,time){ &&
&&&&&&&&&&&&sprite.left&-=&sprite.velocityX; &&
&&&&&&&&&&&&sprite.top&-=&sprite.velocityY; &&
&&&&&&&&&&&&if(sprite.left&-missleWidth/2||sprite.top&-missleHeight/2||sprite.left&canvas.width+missleWidth/2||sprite.top&-missleHeight/2){ &&
&&&&&&&&&&&&&&&&sprite.visible&=&false; &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&}]; &&
&&&&W.misslePainter&=&{ &&
&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&var&img&=&new&Image(); &&
&&&&&&&&&&&&img.src=&../planGame/image/plasma.png&&&
&&&&&&&&&&&&ctx.drawImage(img&,&-missleWidth/2+1&,&-missleHeight/2+1&,&missleWidth&,&missleHeight); &&
&&&&&&&&} &&
&&&&W.badPlanBehavior&=&[{ &&
&&&&&&&&execute:function(sprite,time){ &&
&&&&&&&&&&&&if(sprite.top&&&canvas.height&||&!sprite.visible){ &&
&&&&&&&&&&&&&&&&var&random&=&Math.random(); &&
&&&&&&&&&&&&&&&&if(point&=200&&point&400){ &&
&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&150; &&
&&&&&&&&&&&&&&&&&&&&if(random&0.1){ &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.badKind&=&2; &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&250; &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&}else&if(point&=400&&point&600){ &&
&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&250; &&
&&&&&&&&&&&&&&&&&&&&if(random&0.2){ &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.badKind&=&2; &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&400; &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&&&&&if(random&0.1){ &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.badKind&=&3; &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&600; &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&}else&if(point&=600){ &&
&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&500; &&
&&&&&&&&&&&&&&&&&&&&if(random&0.4){ &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.badKind&=&2; &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&700; &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&&&&&if(random&0.2){ &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.badKind&=&3; &&
&&&&&&&&&&&&&&&&&&&&&&&&sprite.fullBlood&=&1000; &&
&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&sprite.visible&=&true; &&
&&&&&&&&&&&&&&&&sprite.blood&=&sprite.fullB &&
&&&&&&&&&&&&&&&&sprite.left&=&Math.random()*(canvas.width-2*planWidth)+planW &&
&&&&&&&&&&&&&&&&sprite.top&=&Math.random()*canvas.height&-&canvas. &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&sprite.top&+=&sprite. &&
&&&&&&&&}, &&
&&&&&&&&shot:function(sprite){ &&
&&&&&&&&&&&&this.addMissle(sprite&,&sprite.rotateAngle); &&
&&&&&&&&&&&&var&missleAngle&=&0.1 &&
&&&&&&&&&&&&for(var&i=1;i&sprite.fireLi++){ &&
&&&&&&&&&&&&&&&&this.addMissle(sprite&,&sprite.rotateAngle-i*missleAngle); &&
&&&&&&&&&&&&&&&&this.addMissle(sprite&,&sprite.rotateAngle+i*missleAngle); &&
&&&&&&&&&&&&} &&
&&&&&&&&}, &&
&&&&&&&&addMissle:function(sprite&,&angle){ &&
&&&&&&&&&&&&for(var&j=0;j&missles.j++){ &&
&&&&&&&&&&&&&&&&if(!missles[j].visible){ &&
&&&&&&&&&&&&&&&&&&&&missles[j].left&=&sprite. &&
&&&&&&&&&&&&&&&&&&&&missles[j].top&=&sprite. &&
&&&&&&&&&&&&&&&&&&&&missles[j].rotateAngle&=& &&
&&&&&&&&&&&&&&&&&&&&var&missleSpeed&=&20; &&
&&&&&&&&&&&&&&&&&&&&missles[j].velocityX&=&missleSpeed*Math.sin(-missles[j].rotateAngle); &&
&&&&&&&&&&&&&&&&&&&&missles[j].velocityY&=&missleSpeed*Math.cos(-missles[j].rotateAngle); &&
&&&&&&&&&&&&&&&&&&&&missles[j].visible&=&true; &&
&&&&&&&&&&&&&&&&&&&&break; &&
&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&}]; &&
&&&&W.badPlanPainter&=&{ &&
&&&&&&&&paint:function(sprite){ &&
&&&&&&&&&&&&var&img&=&new&Image(); &&
&&&&&&&&&&&&img.src=&../planGame/image/ship.png&&&
&&&&&&&&&&&&switch(sprite.badKind){ &&
&&&&&&&&&&&&&&&&case&1:ctx.drawImage(img&,&96&,&0&,&planWidth&,&planWidth&,&-planWidth/2&,&-planHeight/2&,&planWidth&,&planWidth); &&
&&&&&&&&&&&&&&&&break; &&
&&&&&&&&&&&&&&&&case&2:ctx.drawImage(img&,&120&,&0&,&planWidth&,&planWidth&,&-planWidth/2&,&-planHeight/2&,&planWidth&,&planWidth); &&
&&&&&&&&&&&&&&&&break; &&
&&&&&&&&&&&&&&&&case&3:ctx.drawImage(img&,&144&,&0&,&planWidth&,&planWidth&,&-planWidth/2&,&-planHeight/2&,&planWidth&,&planWidth); &&
&&&&&&&&&&&&&&&&break; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&ctx.strokeStyle&=&&#FFF&; &&
&&&&&&&&&&&&ctx.fillStyle&=&&#F00&; &&
&&&&&&&&&&&&var&bloodHeight&=&1; &&
&&&&&&&&&&&&ctx.strokeRect(-planWidth/2-1&,&planHeight+bloodHeight+3&,&planWidth+2&,&bloodHeight+2); &&
&&&&&&&&&&&&ctx.fillRect(planWidth/2-planWidth*sprite.blood/sprite.fullBlood&,&planHeight+bloodHeight+3&,&planWidth*sprite.blood/sprite.fullBlood&,&bloodHeight); &&
&&&&&&&&} &&
&&&&W.planSize&=&function(){ &&
&&&&&&&&return&{ &&
&&&&&&&&&&&&w:planWidth, &&
&&&&&&&&&&&&h:planHeight &&
&&&&&&&&}&&&& &&
})(window);&&&
这些绘制方法之类的都相对比较简单。
  主要说一下飞机的运动以及对象数量的控制,飞机怎么运动?毫无疑问,通过键盘控制它运动,可能很多人就会想到通过keydown这个方法按下的时候通过判断keyCode来让飞机持续运动。但是有个问题,keydown事件不支持多键按下,也就是说,当你按下X键时,keyCode是88,与此同时你按下方向键后,keyCode会瞬间变成37,也就是说,如果你单纯的想靠keydown来控制飞机运动,飞机就只能做一件事,要么只可以往某个方向移动,要么只会开枪。
  所以,我们要通过keydown和keyup来实现飞机的运动,原理很容易理解:当我们按下往左的方向键时,我们给飞机一个往左的状态,也就是让飞机的toLeft属性为true,而在动画循环中,判断飞机的状态,如果toLeft为true则飞机的x值不停地减少,飞机也就会不停地往左移动,然后当我们抬起手指时触发keyup事件,我们就再keyup事件中解除飞机往左的状态。飞机也就停止往左移动了。其他状态也一样的原理,这样写的话,就能够让飞机多种状态于一生了。可以同时开枪同时到处跑了。
实现的代码如下:
//keydown/keyup事件的绑定&& &&
&&window.onkeydown&=&function(event){ &&
&&&&&&&&&&&&switch(event.keyCode){ &&
&&&&&&&&&&&&&&&&case&88:myplan.fire&=&true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&90:myplan.rotateLeft=true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&67:myplan.rotateRight=true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&37:myplan.toLeft&=&true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&38:myplan.toTop&=&true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&39:myplan.toRight&=&true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&40:myplan.toBottom&=&true; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&} &&
&&&&&&&&} &&
&&&&&&&&window.onkeyup&=&function(event){ &&
&&&&&&&&&&&&switch(event.keyCode){ &&
&&&&&&&&&&&&&&&&case&88:myplan.fire&=&false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&90:myplan.rotateLeft=false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&67:myplan.rotateRight=false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&37:myplan.toLeft&=&false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&38:myplan.toTop&=&false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&39:myplan.toRight&=&false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&case&40:myplan.toBottom&=&false; &&
&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&} &&
&&&&&&&&}&&&& &&
//飞机每一帧的状态更新处理代码 &&
execute:function(sprite,time){ &&
&&&&&&&&&&&&if(sprite.toTop){ &&
&&&&&&&&&&&&&&&&spritesprite.top&=&sprite.top/2?&sprite.top&:&sprite.top-sprite.velocityY; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.toLeft){ &&
&&&&&&&&&&&&&&&&spritesprite.left&=&sprite.left/2?&sprite.left&:&sprite.left-sprite.velocityX; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.toRight){ &&
&&&&&&&&&&&&&&&&spritesprite.left&=&sprite.leftcanvas.width-planWidth/2?&sprite.left&:&sprite.left+sprite.velocityX; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.toBottom){ &&
&&&&&&&&&&&&&&&&spritesprite.top&=&sprite.topcanvas.height-planHeight/2?&sprite.top&:&sprite.top+sprite.velocityY; &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.rotateLeft){ &&
&&&&&&&&&&&&&&&&sprite.rotateAngle&-=&sprite.rotateS &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.rotateRight){ &&
&&&&&&&&&&&&&&&&sprite.rotateAngle&+=&sprite.rotateS &&
&&&&&&&&&&&&} &&
&&&&&&&&&&&&if(sprite.fire&&!sprite.painter.isActive){ &&
&&&&&&&&&&&&&&&&sprite.painter.isActive&=&true; &&
&&&&&&&&&&&&&&&&this.shot(sprite); &&
&&&&&&&&&&&&}&&&&&
就是如此简单。
  然后说下对象控制,打飞机游戏,会发射大量子弹,产生大量对象,包括爆炸啊,飞机啊,子弹等,如果不停地进行对象的生成和销毁,会让浏览器的负荷变得很大,运行了一段时间后就会卡出翔了。所以,我们要用可以循环利用的对象来解决这个问题,不进行对象的销毁,对所有对象进行保存,循环利用。
  我的做法就是,在游戏初始化的时候,直接生成一定数量的对象,存放在数组里面。当我们需要一个对象的时候,就从里面取,当用完后,再放回数组里面。数组里的所有对象都有一个属性,visible,代表对象当前是否可用。
  举个例子,当我的飞机发射一发炮弹,我需要一发炮弹,所以我就到炮弹数组里遍历,如果遍历到的炮弹visible为true,也就说明该对象正在使用着,不能拿来用,所以继续遍历,直到遍历到visible为false的炮弹对象,说明这个对象暂时没人用。然后就可以拿过来重新设置属性,投入使用了。当炮弹击中敌人或者打出画布外的时候,把炮弹的visible设成false,又成了一个没人用的炮弹在数组里存放起来等待下一次调用。
  所以,我们要预算算好页面大概要用到多少个对象,然后就预先准备好对象,这样,在游戏进行中,不会有对象进行生成和销毁,对游戏性能方面就有了提升了。
  最后再说下音频,游戏里面要用到多个同样的audio才能保证音效的不间断性:复制代码
var&audio&=&document.getElementsByTagName(&audio&); &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&for(var&i=0;i;i++){ &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&console.log(audio[i].paused) &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(audio[i].src.indexOf(&boom&)=0&&audio[i].paused){ &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&audio[i].play(); &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&} &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&
好吧,基本上就这样了。技术或许还不够好,纯碎做个记录,如果代码有不当正处,欢迎指出,共同学习。
源码地址:
大家感兴趣的内容
12345678910
最近更新的内容

我要回帖

更多关于 学canvas可以做什么 的文章

 

随机推荐