Html5游戏开发案例
Html游戏开发案例(一)
拼图游戏
游戏规则介绍:
拼图游戏将一幅图片分割成若干拼块并将它们随机打乱顺序。当将所有拼块都放回原位置时,就完成了拼图(游戏结束)。
在“游戏”中,单击滑块选择游戏难易,“容易”为3行3列拼图游戏,中间为一个4行4列拼图游戏,“难”为5行5列拼图游戏。拼块以随机顺序排列,玩家用鼠标单击空白块的四周来交换它们的位置,直到所有拼块都回到原位置。
拼图游戏运行结果如图所示。

参考代码
html代码
1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"> 5 <title>拼图游戏</title> 6 <style>.picture{border: 1px solid black;} 7 </style> 8 </head> 9 <body> 10 <div id = "title"> 11 <h2> 拼图游戏 </h2> 12 </div> 13 <div id = "slider"> 14 <form> 15 <label> 低 </label> 16 <input type = "range" id = "scale" value = "4" min = "3" max = "5" step = "1"> 17 <label> 高 </label> 18 </form> 19 <br> 20 </div> 21 <div id = "main" class = "main"> 22 <canvas id = "puzzle" width ="480px"height="480px"></canvas> 23 </div> 24 <script src = "sliding.js"></script> 25 </body> 26</html> 27
js代码:
1var context = document.getElementById('puzzle').getContext('2d'); 2var img = new Image (); 3img.src = 'defa.jpg'; 4img.addEventListener('load',drawTiles,false); 5var boardSize = document.getElementById('puzzle').width; 6var tileCount = document.getElementById('scale').value; 7var tileSize = boardSize/tileCount; 8var clickLoc = new Object; 9clickLoc.x = 0; 10clickLoc.y = 0; 11var emptyLoc = new Object; 12emptyLoc. x = 0; 13emptyLoc. y = 0; 14var solved = false; 15var boardParts = new Object; 16setBoard (); 17document.getElementById('scale').onchange = function(){ 18 tileCount = this.value; 19 tileSize = boardSize/tileCount; 20 setBoard(); 21 drawTiles(); 22}; 23 24document.getElementById('puzzle').onmousemove = function(e){ 25 clickLoc.x = Math.floor((e.pageX - this.offsetLeft)/tileSize); 26 clickLoc.y = Math.floor((e.pageY - this.offsetTop)/tileSize); 27}; 28 29document.getElementById('puzzle').onclick = function(){ 30 if(distance(clickLoc.x,clickLoc.y,emptyLoc.x,emptyLoc.y)== 1){ 31 slideTile(emptyLoc,clickLoc); 32 drawTiles(); 33 } 34 if(solved){ 35 setTimeout(function(){alert( "You solved it!");},500); 36 } 37}; 38 39function setBoard(){ 40 boardParts = new Array(tileCount); 41 for(var i = 0;i < tileCount;++ i){ 42 boardParts[i] = new Array(tileCount); 43 for(var j = 0;j < tileCount; ++ j){ 44 boardParts[ i ][ j ]= new Object ; 45 boardParts[ i ][ j ].x =(tileCount - 1 )- i; 46 boardParts[ i ][ j ].y =(tileCount - 1 )- j; 47 } 48 } 49 emptyLoc.x = boardParts[tileCount - 1][tileCount - 1].x; 50 emptyLoc.y = boardParts[tileCount - 1][tileCount - 1].y; 51 solved = false; 52} 53 54function drawTiles(){ 55 context.clearRect (0,0,boardSize,boardSize); 56 for(var i = 0;i < tileCount;++ i){ 57 for (var j = 0;j < tileCount;++ j){ 58 var x = boardParts[ i ][ j ].x; 59 var y = boardParts[ i ][ j ].y; 60 if (i != emptyLoc.x || j != emptyLoc.y || solved == true ){ 61 context.drawImage(img,x * tileSize,y * tileSize,tileSize,tileSize, 62 i * tileSize,j * tileSize,tileSize,tileSize); 63 } 64 } 65 } 66} 67 68function distance (x1 , y1 , x2 , y2){ 69 return Math.abs(x1 - x2)+ Math.abs(y1 - y2); 70} 71 72function slideTile(toLoc ,fromLoc){ 73 if(! solved ){ 74 boardParts[toLoc.x][toLoc.y].x = boardParts[ fromLoc.x][fromLoc.y].x; 75 boardParts[toLoc.x][toLoc.y].y = boardParts[ fromLoc.x][fromLoc.y].y; 76 boardParts[fromLoc.x][fromLoc.y].x = tileCount - 1; 77 boardParts[fromLoc.x][fromLoc.y].y = tileCount - 1; 78 toLoc.x = fromLoc.x; 79 toLoc.y = fromLoc.y; 80 checkSolved(); 81 } 82} 83 84function checkSolved(){ 85 var flag = true; 86 for(var i = 0 ;i < tileCount;++ i){ 87 for(var j = 0;j < tileCount;++ j){ 88 if(boardParts[ i ][ j ].x != i || boardParts[ i ][ j ].y != j){ 89 flag = false; 90 } 91 } 92 } 93 solved = flag; 94}
Html游戏开发案例(二)
雷电飞机大战
游戏规则介绍:
键盘上下左右控制飞机的移动,空格键控制飞机发射子弹,敌机也会随机出现,每消灭一架敌机加二十分,碰到敌机则游戏结束。
雷电飞机大战游戏运行如图所示

参考代码
1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>飞机大战</title> 6 </head> 7 <body> 8 <canvas id="myCanvas" width="320" height="480" style="border: solid;"> 9 你的浏览器不支持canvas画布元素,更新浏览器获得演示效果。</canvas> 10 <div id="message_txt" style="display: block;">飞机大战</div> 11 <div id="score_txt" style="display: block;">分数:0分</div> 12 <script type="text/javascript"> 13 var canvas=document.getElementById("myCanvas"); 14 var context=canvas.getContext("2d"); 15 document.addEventListener("keydown",onkeydown); 16 var Plan=function(image,x,y,n){ 17 this.image=image; 18 this.x=x; 19 this.y=y; 20 this.originX=x; 21 this.originY=y; 22 this.width=image.width/n; 23 this.height=image.height; 24 this.isCaught=false; 25 this.frm=0; 26 this.dis=0; 27 this.n=n; 28 }; 29 Plan.prototype.getCaught=function(bool){ 30 this.isCaught=bool; 31 if(bool==false){ 32 this.originX=0; 33 this.originY=this.y; 34 } 35 }; 36 Plan.prototype.testPoint=function(x,y){ 37 var betweenX=(x>=this.x)&&(x<=this.x+this.width); 38 var betweenY=(y>=this.y)&&(y<=this.y+this.height); 39 return betweenX && betweenY; 40 }; 41 Plan.prototype.move=function(dx,dy){ 42 this.x +=dx; 43 this.y +=dy; 44 }; 45 Plan.prototype.Y=function(){ 46 return this.y; 47 }; 48 //不断下移的画飞机 49 Plan.prototype.draw=function(ctx){ 50 ctx.save(); 51 ctx.translate(this.x,this.y); 52 ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height); 53 ctx.restore(); 54 this.y++; 55 this.x=this.originX+20*Math.sin(Math.PI/100*this.y); 56 this.dis++; 57 if(this.dis>=3){//3帧换图 58 this.dis=0; 59 this.frm++; 60 if(this.frm>=this.n) this.frm=0; 61 } 62 }; 63 //原地不动画飞机 64 Plan.prototype.draw2=function(ctx){ 65 ctx.save(); 66 ctx.translate(this.x,this.y); 67 ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height); 68 ctx.restore(); 69 this.dis++; 70 if(this.dis>=3){//3帧换图 71 this.dis=0; 72 this.frm++; 73 if(this.frm>=this.n) this.frm=0; 74 } 75 }; 76 //飞机碰撞检测 77 //将所有子弹对象的矩形区域与敌机对象的矩形区域逐一检测,如果重叠说明子弹与敌机的碰撞。 78 Plan.prototype.hitTestObject=function(planobj){ 79 if(isColliding(this.x,this.y,this.width,this.height,planobj.x,planobj.y,planobj.width,planobj.height)) 80 //发生碰撞 81 return true; 82 else 83 return false; 84 } 85 86 function isColliding(ax,ay,aw,ah,bx,by,bw,bh) 87 { 88 if(ay>by+bh || by>ay+ah || ax>bx+bw || bx>ax+aw) 89 return false; 90 else 91 return true; 92 } 93 94 //子弹类 95 var Bullet=function(image,x,y){ 96 this.image=image; 97 this.x=x; 98 this.y=y; 99 this.originX=x; 100 this.originY=y; 101 this.width=image.width/4; 102 this.height=image.height; 103 this.isCaught=false; 104 this.frm=0; 105 this.dis=0; 106 }; 107 Bullet.prototype.testPoint=function(x,y){ 108 var betweenX=(x>=this.x)&&(x<=this.x+this.width); 109 var betweenY=(y>=this.y)&&(y<=this.y+this.height); 110 return betweenX && betweenY; 111 }; 112 Bullet.prototype.move=function(dx,dy){ 113 this.x +=dx; 114 this.y +=dy; 115 }; 116 Bullet.prototype.Y=function(){ 117 return this.y; 118 }; 119 Bullet.prototype.draw=function(ctx){ 120 ctx.save(); 121 ctx.translate(this.x,this.y); 122 ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height); 123 ctx.restore(); 124 this.y--; 125 this.dis++; 126 if(this.dis>=10){//10帧换图 127 this.dis=0; 128 this.frm++; 129 if(this.frm>=4) this.frm=0; 130 } 131 }; 132 Bullet.prototype.hitTestObject=function(planobj){ 133 if(isColliding(this.x,this.y,this.width,this.height,planobj.x,planobj.y,planobj.width,planobj.height)) 134 //发生碰撞 135 return true; 136 else 137 return false; 138 } 139 //爆炸动画 140 var Bomb=function(image,x,y){ 141 this.image=image; 142 this.x=x; 143 this.y=y; 144 this.width=image.width/6; 145 this.height=image.height; 146 this.frm=0; 147 this.dis=0; 148 }; 149 Bomb.prototype.draw2=function(ctx){ 150 ctx.save(); 151 ctx.translate(this.x,this.y); 152 if(this.frm>=6) return; 153 ctx.drawImage(this.image,this.frm*this.width,0,this.width,this.height,0,0,this.width,this.height); 154 ctx.restore(); 155 this.dis++; 156 if(this.dis>=10){//10帧换图 157 this.dis=0; 158 this.frm++; 159 } 160 }; 161 var plan1,plan2,plan3,plan4,caughtplan=null; 162 var isClicked=false; 163 var mouseX,mouseY,preX,preY; 164 var plans=[]; 165 var bullets=[]; 166 var bombs=[]; 167 var score=0; 168 var overflag=false;//游戏是否结束,true为结束 169 var myplane;//乙方飞机 170 var image=new Image(); 171 var image2=new Image(); 172 var image3=new Image(); 173 var image4=new Image(); 174 var image5=new Image(); 175 var background=new Image(); 176 background.src="img/map_0.png"; 177 image.src="img/plan.png";//自己飞机图片 178 image.onload=function(){ 179 180 }; 181 image2.src="img/bomb.png";//爆炸图片 182 image2.onload=function(){ 183 184 }; 185 image3.src="img/enemy.png";//敌机图片 186 image3.onload=function(){ 187 myplane=new Plan(image,300*Math.random(),400,6); 188 189 plan_interval=setInterval(function(){ 190 plans.push(new Plan(image3,300*Math.random(),20*Math.random(),2)); 191 },3000);//3秒产生1架飞机 192 setInterval(function(){ 193 context.clearRect(0,0,320,480); 194 context.drawImage(background,0,0); 195 //画自己方飞机 196 if(!overflag)//游戏没有结束 197 myplane.draw2(context);//原地不动 198 //画敌人飞机 199 for(var i=plans.length-1;i>=0;i--){ 200 if(plans[i].Y()>400) 201 plans.splice(i,1); 202 else 203 plans[i].draw(context); 204 } 205 206 //画子弹 207 for(var i=bullets.length-1;i>=0;i--){ 208 if(bullets[i].Y()<100) 209 bullets.splice(i,1);//删除子弹 210 else 211 bullets[i].draw(context); 212 } 213 //碰撞检测 214 //判断敌机碰到玩家自己飞机 215 for(var i=plans.length-1;i>=0;i--){ 216 e1=plans[i]; 217 if(e1!=null && myplane!=null && myplane.hitTestObject(e1)) 218 { 219 clearInterval(plan_interval);//清除定时器,不在产生敌机 220 plans.splice(i,1);//删除敌机 221 bombs.push(new Bomb(image2,myplane.x,myplane.y)); 222 223 message_txt.innerHTML="敌机碰到玩家自己飞机,游戏结束"; 224 overflag=true; 225 } 226 } 227 228 //判断子弹碰到敌机 229 for(var j=bullets.length-1;j>=0;j--){ 230 var b1=bullets[j]; 231 for(var i=plans.length-1;i>=0;i--){ 232 e1=plans[i]; 233 if(e1!=null && b1!=null && b1.hitTestObject(e1))//击中敌机 234 { 235 plans.splice(i,1);//删除敌机 236 bullets.splice(i,1);//删除此颗子弹 237 bombs.push(new Bomb(image2,b1.x,b1.y-36)); 238 239 message_txt.innerHTML="敌机被击中,加20分"; 240 score+=20; 241 score_txt.innerHTML="分数:"+score+"分"; 242 } 243 } 244 } 245 //画炸弹 246 for(var i=bombs.length-1;i>=0;i--){ 247 if(bombs[i].frm>=6) 248 bombs.splice(i,1);//删除子弹 249 else 250 bombs[i].draw2(context); 251 } 252 },1000/60); 253 }; 254 image4.src="img/bullet.png";//子弹图片 255 image4.onload=function(){ 256 257 }; 258 259 function onkeydown(e){ 260 if(e.keyCode==32){//空格 261 //发射子弹 262 bullets.push(new Bullet(image4,myplane.x,myplane.y-36)); 263 }else if(e.keyCode==37){//向左 264 myplane.move(-10,0); 265 }else if(e.keyCode==39){//向右 266 myplane.move(10,0); 267 }else if(e.keyCode==38){//向上 268 myplane.move(0,-10); 269 }else if(e.keyCode==40){//向下 270 myplane.move(0,10); 271 } 272 } 273 </script> 274 </body> 275</html>
Html5游戏开发案例(三)
愤怒的小鸟
游戏规则介绍:
-
将弹弓上的小鸟弹出去,将猪全部砸到就能过关。
-
上次的弹射会留下轨迹
愤怒的小鸟游戏运行如图所示

参考代码
html代码
1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>Flappy Bird</title> 6 </head> 7 <body> 8 <canvas id="canvas" width="340" height="453" style="border: 2px solid #000;background: #fff;"></canvas> 9 <script src="bird.js" stype="text/javascript"> 10 </body> 11</html> 12
js代码
1var canvas=document.getElementById("canvas"); 2var c=canvas.getContext("2d"); 3//三个类,Bird类,Obstacle类,FlappyBird类(游戏主函数) 4function Bird(x,y,image){ 5 this.x=x; 6 this.y=y; 7 this.width=image.width/2, 8 this.height=image.height, 9 this.image=image; 10 this.draw=function(context,state){ 11 if(state==="up") 12 context.drawImage(image,0,0,this.width,this.height,this.x,this.y,this.width,this.height); 13 else 14 { 15 context.drawImage(image,this.width,0,this.width,this.height,this.x,this.y,this.width,this.height); 16 } 17 } 18}; 19 20function Obstacle(x,y,h,image){ 21 this.x=x; 22 this.y=y; 23 this.width=image.width/2, 24 this.height=h, 25 this.flypast=false;//没被飞过 26 this.draw=function(context,state){ 27 if(state==="up"){ 28 context.drawImage(image,0,0,this.width,this.height,this.x,this.y,this.width,this.height); 29 }else{ 30 context.drawImage(image,this.width,image.height-this.height,this.width,this.height,this.x,this.y,this.width,this.height); 31 } 32 } 33}; 34 35//FlappyBird类包括了游戏主要参数即运行需要的函数。 36function FlappyBird(){} 37FlappyBird.prototype={ 38 bird:null, 39 bg:null, 40 obs:null, 41 obsList:[], 42 43 mapWidth:340, 44 mapHeight:453, 45 startX:90, 46 startY:225, 47 obsDistance:150, 48 obsSpeed:2, 49 obsInterval:2000, 50 upSpeed:8, 51 downSpeed:3, 52 line:56, 53 score:0, 54 touch:false, 55 gameOver:false, 56 57 CreateMap:function(){ 58 //背景 59 this.bg=new Image(); 60 this.bg.src="img/bg.png"; 61 var startBg=new Image(); 62 startBg.src="img/start.jpg"; 63 //由于Image异步加载,在加载完成时在绘制图像 64 startBg.onload=function(){ 65 c.drawImage(startBg,0,0); 66 }; 67 68 //小鸟 69 var image=new Image(); 70 image.src="img/bird.png"; 71 image.onload=function(){ 72 this.bird=new Bird(this.startX,this.startY,image); 73 //this.bird.draw(c,"down") 74 }.bind(this); 75 76 //障碍物 77 this.obs=new Image(); 78 this.obs.src="img/obs.png"; 79 this.obs.onload=function(){ 80 var h=100;//默认第一障碍物上管道高度为100 81 var h2=this.mapHeight-h-this.obsDistance; 82 var obs1=new Obstacle(this.mapWidth,0,h,this.obs); 83 var obs2=new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs); 84 this.obsList.push(obs1); 85 this.obsList.push(obs2); 86 }.bind(this); 87 }, 88 89 CreateObs:function(){ 90 //随机产生障碍物上边管道高度 91 var h=Math.floor(Math.random()*(this.mapHeight-this.obsDistance-this.line)); 92 var h2=this.mapHeight-h-this.obsDistance; 93 var obs1=new Obstacle(this.mapWidth,0,h,this.obs); 94 var obs2=new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs); 95 this.obsList.push(obs1); 96 this.obsList.push(obs2); 97 98 //移除越界障碍物 99 if(this.obsList[0].x<-this.obsList[0].width) 100 this.obsList.splice(0,2); 101 }, 102 103 DrawObs:function(){ 104 c.fillStyle="#00ff00"; 105 for(var i=0;i<this.obsList.length;i++){ 106 this.obsList[i].x-=this.obsSpeed; 107 if(i%2) 108 this.obsList[i].draw(c,"up"); 109 else 110 this.obsList[i].draw(c,"down"); 111 } 112 }, 113 114 CountScore:function(){//计分 115 if(this.obsList[0].x+this.obsList[0].width<this.startX && this.obsList[0].flypast==false){ 116 //小鸟坐标超过障碍物 117 this.score+=1; 118 this.obsList[0].flypast=true; 119 } 120 }, 121 122 ShowScore:function(){ 123 //显示分数 124 c.strokeStyle="#000"; 125 c.lineWidth=1; 126 c.fillStyle="#fff" 127 c.fillText(this.score,10,50); 128 c.strokeText(this.score,10,50); 129 }, 130 131 CanMove:function(){ 132 //碰撞检测 133 if(this.bird.y<0 || this.bird.y>this.mapHeight-this.bird.height-this.line){ 134 this.gameOver=true; 135 } 136 else{ 137 var boundary=[{ 138 x:this.bird.x, 139 y:this.bird.y 140 },{ 141 x:this.bird.x+this.bird.width, 142 y:this.bird.y 143 },{ 144 x:this.bird.x, 145 y:this.bird.y+this.bird.height 146 },{ 147 x:this.bird.x+this.bird.width, 148 y:this.bird.y+this.bird.height 149 }]; 150 for(var i=0;i<this.obsList.length;i++){ 151 for(var j=0;j<4;j++) 152 if(boundary[j].x>=this.obsList[i].x && boundary[j].x<=this.obsList[i].x+this.obsList[i].width 153 && boundary[j].y>=this.obsList[i].y && boundary[j].y<=this.obsList[i].y+this.obsList[i].height) 154 { 155 this.gameOver=true; 156 break; 157 } 158 if(this.gameOver) 159 break; 160 } 161 } 162 }, 163 CheckTouch:function () {//检测触碰 164 if (this.touch) { 165 this.bird.y-=this.upSpeed; 166 this.bird.draw(c,"up"); 167 } else{ 168 this.bird.y+=this.downSpeed; 169 this.bird.draw(c,"down"); 170 } 171 }, 172 ClearScreen:function () {//清屏 173 c.drawImage(this.bg,0,0); 174 }, 175 ShowOver:function () { 176 var overImg=new Image(); 177 overImg.src="img/over.png"; 178 overImg.onload=function(){ 179 c.drawImage(overImg,(this.mapWidth-overImg.width)/2,(this.mapHeight-overImg.height)/2-50); 180 }.bind(this); 181 return; 182 } 183 }; 184 185var game=new FlappyBird(); 186var Speed=20; 187var IsPlay=false; 188var GameTime=null; 189var btn_start; 190window.onload=InitGame; 191 192function InitGame(){ 193 c.font="3em 微软雅黑"; 194 game.CreateMap(); 195 canvas.onmousedown=function(){ 196 game.touch=true; 197 } 198 canvas.onmouseup=function(){ 199 game.touch=false; 200 } 201 canvas.onclick=function(){ 202 if(!Isplay){ 203 Isplay=true; 204 GameTime=RunGame(Speed); 205 } 206 } 207} 208//游戏运行函数 209function RunGame(speed){ 210 var updateTimer=setInterval(function(){ 211 //若小鸟通过第一个障碍物启动计分器 212 game.CanMove(); 213 if(game.gameOver){ 214 game.ShowOver(); 215 clearInterval(updateTimer); 216 return; 217 } 218 game.ClearScreen(); 219 game.DrawObs(); 220 game.CheckTouch(); 221 game.CountScore(); 222 game.ShowScore(); 223 },speed); 224 var obsTimer=setInterval(function(){ 225 if(game.gameOver){ 226 clearInterval(obsTimer); 227 return; 228 } 229 game.CreateObs(); 230 },game.obsInterval); 231}