点此下载源码。
图例:
源码:
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <head> <title>飞越河谷的战机1.06 19.3.14 9:45 by:逆火狂飙 horn19782016@163.com</title> <style> *{ margin:1px; padding:1px; } #canvas{ background:#ffffff; } #controls{ float:left; } </style> </head> <body onload="init()"> <table border="0px"> <tr> <td width="50px"valign="top"> <div id="controls"> <input id='animateBtn' type='button' value='运动'/> </div> </td> <td width="100%" align="center"> <canvas id="canvas" width="1200px" height="562px" > 出现文字表示你的浏览器不支持HTML5 </canvas> </td> </tr> </table> <div> </div> </body> </html> <script type="text/javascript"> <!-- var paused=true; animateBtn.onclick=function(e){ paused=! paused; if(paused){ animateBtn.value="运动"; }else{ animateBtn.value="暂停"; window.requestAnimationFrame(animate); } } var ctx; // 绘图环境 var bg; // 背景 var lastTime=0; var fps=0; var myPlane; var myShells; var enemyPlaneMng; function init(){ // 创建背景对象 bg=new Background(); // 初始化CTX var canvas=document.getElementById('canvas'); canvas.width=bg.width*6; canvas.height=bg.height*4; ctx=canvas.getContext('2d'); lastTime=+new Date; // 创建本机对象 myPlane=new MyPlane(ctx.canvas.width/2,canvas.height-100); myShells=new Array(); enemyPlaneMng=new EnemyPlaneMng(); // 响应键盘按下事件 canvas.addEventListener('keydown', doKeyDown, true); window.addEventListener('keydown', doKeyDown, true); // 响应键盘弹起事件 canvas.addEventListener('keyup', doKeyUp, true); window.addEventListener('keyup', doKeyUp, true); canvas.focus(); }; //------------------------------------ // 响应键盘按下事件 //------------------------------------ function doKeyDown(e) { var keyID = e.keyCode ? e.keyCode :e.which; if(keyID === 38 || keyID === 87) { // up arrow and W myPlane.toUp=true; e.preventDefault(); } if(keyID === 40 || keyID === 83) { // down arrow and S myPlane.toDown=true; e.preventDefault(); } if(keyID === 39 || keyID === 68) { // right arrow and D myPlane.toRight=true; e.preventDefault(); } if(keyID === 37 || keyID === 65) { // left arrow and A myPlane.toLeft=true; e.preventDefault(); } if(keyID === 32 ) { // SpaceBar myPlane.isShoot=true; e.preventDefault(); } } //------------------------------------ // 响应键盘弹起事件 //------------------------------------ function doKeyUp(e) { var keyID = e.keyCode ? e.keyCode :e.which; if(keyID === 38 || keyID === 87) { // up arrow and W myPlane.toUp=false; e.preventDefault(); } if(keyID === 40 || keyID === 83) { // down arrow and S myPlane.toDown=false; e.preventDefault(); } if(keyID === 39 || keyID === 68) { // right arrow and D myPlane.toRight=false; e.preventDefault(); } if(keyID === 37 || keyID === 65) { // left arrow and A myPlane.toLeft=false; e.preventDefault(); } if(keyID === 32 ) { // SpaceBar myPlane.isShoot=false; e.preventDefault(); } } // 更新各对象状态 function update(){ myPlane.move(); for(var i=0;i<myShells.length;i++){ var myShell=myShells[i]; if(myShell.destroyed==false){ if(enemyPlaneMng.isShooted(myShell.x,myShell.y)==true){ myShell.destroyed=true; } } myShell.move(); } enemyPlaneMng.move(); } // 在CTX画出各个对象 function draw(){ ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); fps=calculateFps(new Date); bg.setOffset(fps); var bgImg=bg.getImage(); ctx.drawImage(bgImg,0,bg.height-bg.Offset,bg.width,bg.Offset,0,0,ctx.canvas.width,4*bg.Offset); ctx.drawImage(bgImg,0,0,bg.width,bg.height-bg.Offset,0,4*bg.Offset,canvas.width,canvas.height-4*bg.Offset); myPlane.paint(ctx); for(var i=0;i<myShells.length;i++){ var myShell=myShells[i]; myShell.paint(ctx); } enemyPlaneMng.paint(ctx); } function calculateFps(now){ var retval=1000/(now-lastTime); lastTime=now; // console.log("fps",retval) return retval; } function animate(){ if(!paused){ update(); draw(); } window.requestAnimationFrame(animate); } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>点类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Point=function(x,y){ this.x=x; this.y=y; } Point.prototype={ x:0, // 横坐标 y:0, // 纵坐标 } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<点类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>背景类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Background=function(){ this.width=104; this.height=156; this.files=['bgBlue.jpg','bgRiver.jpg','bgSky.jpg','bgVolcano.jpg']; this.Offset=0; this.velocity=40; } Background.prototype={ 104, // 背景图片原始宽度 height:156, // 背景图片原始高度 files:[], // 图片数组 Offset:0, // 偏移值 velocity:40, // 背景移动速度 loopValue:0, // 循环累加值,用来确定时哪一张图片 getImage:function(){ this.loopValue++; if(this.loopValue>=3999){ this.loopValue=0; } var index=Math.floor(this.loopValue/1000); var img=new Image(); img.src=this.files[index]; return img; }, setOffset:function(fps){ this.Offset=this.Offset<this.height?this.Offset+this.velocity/fps:0; }, } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<背景类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我方战机类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MyPlane=function(x,y){ Point.apply(this,arguments); this.types=[ {56,height:41,file:'m1.png'}, {56,height:41,file:'m2.png'}, {80,height:54,file:'m3.png'}, {109,height:83,file:'m4.png'}, {109,height:81,file:'m5.png'}, {109,height:91,file:'m6.png'}, ]; } MyPlane.prototype={ files:[], // 存储图片的数组 step:4, // 每次移动多远 toLeft:false, // 是否向左移动 toRight:false, // 是否向右移动 toUp:false, // 是否向上移动 toDown:false, // 是否向下移动 level:3, // 等级 isShoot:false, // 是否开炮 paint:function(ctx){ var img=new Image(); var index=this.level; img.src=this.types[index].file; ctx.drawImage(img,this.x-this.types[index].width/2,this.y-this.types[index].height/2); var img2=new Image(); img2.src="shoot.png"; ctx.drawImage(img2,this.x-5.5,this.y-5.5); }, move:function(){ // 加入边界判断 2019年3月13日19点16分 var type=this.types[this.level].file; if(this.x<0){ this.x=0; this.toLeft=false; } if(this.x>ctx.canvas.width){ this.x=ctx.canvas.width; this.toRight=false; } if(this.y<0){ this.y=0; this.toUp=false; } if(this.y>ctx.canvas.height){ this.y=ctx.canvas.height; this.toDown=false; } // 运动 if(this.toLeft==true){ this.x-=this.step; } if(this.toRight==true){ this.x+=this.step; } if(this.toUp==true){ this.y-=this.step; } if(this.toDown==true){ this.y+=this.step; } // 开炮 if(this.isShoot==true){ var myShell=new MyShell(this.x,this.y); myShells.push(myShell); } }, } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<我方战机类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我方炮弹类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MyShell=function(x,y){ Point.apply(this,arguments); //this.files=['shell0.png','shell1.png','shell2.png','shell3.png','shell4.png','shell5.png','shell6.png','shell7.png',]; this.types=[ {11,height:11,file:'shell0.png'}, {11,height:11,file:'shell1.png'}, {11,height:11,file:'shell2.png'}, {11,height:11,file:'shell3.png'}, {11,height:11,file:'shell4.png'}, {11,height:11,file:'shell5.png'}, {11,height:11,file:'shell6.png'}, {18,height:18,file:'shell7.png'}, ]; } MyShell.prototype={ types:[], // 炮弹型号 destroyed:false,// 是否被敌机撞毁 visible:true, // 是否在CTX显示范围内 level:3, // 等级,用以决定炮弹型号 paint:function(ctx){ if(this.visible==false){ return; } if(this.destroyed==false){ //var img2=new Image(); //img2.src=this.files[0]; //ctx.drawImage(img2,this.x-5.5,this.y-5.5); // 没被击毁显示飞机型号 var img=new Image(); var index=this.level; img.src=this.types[index].file; ctx.drawImage(img,this.x-this.types[index].width/2,this.y-this.types[index].height/2); } }, move:function(){ // 设置越界不可见 if(this.x<0){ this.visible=false; } if(this.x>ctx.canvas.width){ this.visible=false; } if(this.y<0){ this.visible=false; } if(this.y>ctx.canvas.height){ this.visible=false; } if(this.visible==true){ this.y-=18; } }, } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<我方炮弹类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>敌方飞机类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EnemyPlane=function(x,y,level){ Point.apply(this,arguments); this.level=level; this.types=[ {117,height:64,file:'e0.png'}, {117,height:64,file:'e1.png'}, {100,height:77,file:'e2.png'}, {117,height:85,file:'e3.png'}, {117,height:93,file:'e4.png'}, {117,height:93,file:'e5.png'}, {117,height:96,file:'e6.png'}, {117,height:99,file:'e7.png'}, ]; this.explosions=[ {105,height:100,file:'explosion0.png'}, {105,height:100,file:'explosion1.png'}, {105,height:100,file:'explosion2.png'}, {105,height:100,file:'explosion3.png'}, {105,height:100,file:'explosion4.png'}, {105,height:100,file:'explosion5.png'}, ]; } EnemyPlane.prototype={ types:[], // 飞机型号数组 destroyed:false, // 是否被击毁 level:7, // 等级,用此取飞机型号 visible:true, // 是否在ctx显示范围内 explosions:[], // 爆炸图片 destroyTime:0, // 被摧毁时间 paint:function(ctx){ // 不可见则不显示 if(this.visible==false){ return; } if(this.destroyed==false){ // 没被击毁显示飞机型号 var img=new Image(); var index=this.level; img.src=this.types[index].file; ctx.drawImage(img,this.x-this.types[index].width/2,this.y-this.types[index].height/2); var img2=new Image(); img2.src="shoot.png"; ctx.drawImage(img2,this.x-5.5,this.y-5.5); }else{ var index=Math.floor(this.destroyTime); if(index<this.explosions.length){ this.destroyTime+=0.05; var img=new Image(); img.src=this.explosions[index].file; ctx.drawImage(img,this.x-this.explosions[index].width/2,this.y-this.explosions[index].height/2); } } }, move:function(){ // 设置越界不可见 if(this.x<0){ this.visible=false; } if(this.x>ctx.canvas.width){ this.visible=false; } if(this.y<0){ this.visible=false; } if(this.y>ctx.canvas.height){ this.visible=false; } if(this.visible){ this.y+=1; } }, } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<敌方飞机类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>敌方飞机管理类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EnemyPlaneMng=function(x,y){ Point.apply(this,arguments); this.planes=new Array(); this.planes.push(new EnemyPlane(ctx.canvas.width/2,20,0)); this.planes.push(new EnemyPlane(ctx.canvas.width/2-80,20,1)); this.planes.push(new EnemyPlane(ctx.canvas.width/2+80,20,3)); } EnemyPlaneMng.prototype={ planes:[], paint:function(ctx){ for(var i=0;i<this.planes.length;i++){ var plane=this.planes[i]; plane.paint(ctx); } }, move:function(){ for(var i=0;i<this.planes.length;i++){ var plane=this.planes[i]; plane.move(); } }, isShooted:function(x,y){ for(var i=0;i<this.planes.length;i++){ var plane=this.planes[i]; if(plane.visible==true && plane.destroyed==false){ var xDiff=x-plane.x; var yDiff=y-plane.y; var distance=Math.sqrt(Math.pow(xDiff,2)+Math.pow(yDiff,2)); console.log(distance); if(distance<5){ plane.destroyed=true; return true; } } } return false; }, } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<敌方飞机管理类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //--> </script>
2019年3月14日19点54分