空战游戏做到这里,己方运动,己方发射子弹,敌方运动,敌方发射子弹,子弹与飞机碰撞,飞机与飞机碰撞都已经具备了,换言之已经可以玩了。

还需要一个奖励升级系统,在上面显示击落敌机数量等,还有己方不幸被击落显示GG等功能。

请点此下载源码,并用Chrome打开玩赏。

图例:

源码:

<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head><title>飞越河谷的战机1.13 19.3.16 13:36 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></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;        // 上次时间,用以计算FPS
var fps=0;            // Frame per second
var myPlane;        // 己方飞机
var myShellMng;        // 己方子弹管理类
var enemyPlaneMng;    // 敌方飞机管理者
var explosionMng;    // 爆炸管理者
var enemyShellMng;  // 敌方子弹管理类// 初始化,被onload调用
function init(){// 创建背景对象
    bg=new Background();// 初始化CTXvar canvas=document.getElementById('canvas');canvas.width=bg.width*6;canvas.height=bg.height*4;ctx=canvas.getContext('2d');// +new Date=new Date().getTime();
    lastTime=+new Date;// 创建本机对象
    myPlane=new MyPlane(ctx.canvas.width/2,canvas.height-100);// 本机子弹管理者
    myShellMng=new MyShellMng();// 敌机管理者
    enemyPlaneMng=new EnemyPlaneMng();// 爆炸管理者
    explosionMng=new ExplosionMng();// 敌方子弹管理者
    enemyShellMng=new EnemyShellMng();// 响应键盘按下事件
    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.shoot();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// 按下和弹起必须成对出现,否则画面会僵
        e.preventDefault();}
}// 更新各对象状态
function update(){myPlane.move();myShellMng.move();// 判断敌机和本机是否相撞
    enemyPlaneMng.isCrashed(myPlane);// 敌机移动
    enemyPlaneMng.move();// 判断本方子弹是否与敌机相撞
    myShellMng.probeCrashedEnemyPlane();// 补充敌机
    enemyPlaneMng.reload();// 移动敌方子弹
    enemyShellMng.move();// 判断敌方子弹是否与本机相撞
    enemyShellMng.probeCrashedMyPlane();
}// 在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);// 画己方子弹
    myShellMng.paint(ctx);// 画敌机
    enemyPlaneMng.paint(ctx);// 画爆炸
    explosionMng.paint(ctx);// 画敌方子弹
    enemyShellMng.paint(ctx);
}// 计算FPS
function calculateFps(now){var retval=1000/(now-lastTime);
    lastTime=now;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={width: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=[{width:56,height:41,file:'m1.png',shellCount:1,shellSpeed:4,},{width:56,height:41,file:'m2.png',shellCount:2,shellSpeed:4.5,},{width:80,height:54,file:'m3.png',shellCount:3,shellSpeed:5,},{width:109,height:83,file:'m4.png',shellCount:4,shellSpeed:5.5,},{width:109,height:81,file:'m5.png',shellCount:5,shellSpeed:6,},{width:109,height:91,file:'m6.png',shellCount:6,shellSpeed:6.5,},];
}MyPlane.prototype={files:[],           // 存储图片的数组
    step:4,                // 每次移动多远
    toLeft:false,        // 是否向左移动
    toRight:false,        // 是否向右移动
    toUp:false,            // 是否向上移动
    toDown:false,        // 是否向下移动
    level:5,            // 等级
    destroyed:false,    // 是否被击毁或撞毁
    paint:function(ctx){  if(this.destroyed==false){            var index=this.level;if(index>this.types.length-1){console.log("非法的本机level值="+this.level);index=this.types.length-1;}var img=new Image();img.src=this.types[index].file;            ctx.drawImage(img,this.x-this.types[index].width/2,this.y-this.types[index].height/2);// 标出this,x,this.y所在位置//var img2=new Image();//img2.src="shoot.png";//ctx.drawImage(img2,this.x-5.5,this.y-5.5);
        }},// 得到飞机的左上角
    getLeftUpPoint:function(){var index=this.level;var p=new Point(this.x-this.types[index].width/2,this.y-this.types[index].height/2);return p;},// 得到飞机的右上角
    getRightUpPoint:function(){var index=this.level;var p=new Point(this.x+this.types[index].width/2,this.y-this.types[index].height/2);return p;},// 得到飞机的左下角
    getLeftDownPoint:function(){var index=this.level;var p=new Point(this.x-this.types[index].width/2,this.y+this.types[index].height/2);return p;},// 得到飞机的右下角
    getRightDownPoint:function(){var index=this.level;var p=new Point(this.x+this.types[index].width/2,this.y+this.types[index].height/2);return p;},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.destroyed==false){this.x-=this.step;}if(this.toRight==true && this.destroyed==false){this.x+=this.step;}if(this.toUp==true && this.destroyed==false){this.y-=this.step;}if(this.toDown==true && this.destroyed==false){this.y+=this.step;}    },//  本机开炮
    shoot:function(){if(this.destroyed==false){var index=this.level;// 得到炮弹var shellCount=this.types[index].shellCount;            var shells=myShellMng.fetch(shellCount);// 用来控制炮弹发射位置var xLeft=this.x-this.types[index].width/2;var offset=this.types[index].width/(shellCount+1);for(var i=0;i<shellCount;i++){var s=shells[i];s.x=xLeft+(i+1)*offset;s.y=this.y;s.speed=this.types[index].shellSpeed;}}},// 根据等级取得炮弹数量/*getShellNum:function(){if(this.level==0){return 1;}else if(this.level==1){return 2;}else if(this.level==2){return 3;}else if(this.level==3){return 4;}else if(this.level==4){return 5;}else if(this.level==5){return 6;}else if(this.level==6){return 7;}else if(this.level==7){return 8;}else{return 9;}},*/// 根据等级取得炮弹速度/*getShellSpeed:function(){if(this.level==0){return 2;}else if(this.level==1){return 2;}else if(this.level==2){return 4;}else if(this.level==3){return 4;}else if(this.level==4){return 5;}else if(this.level==5){return 5;}else if(this.level==6){return 6;}else if(this.level==7){return 7;}else{return 8;}},*/// 判断以x,y为坐标的点是否进入本机机四角范围内
    isWithinLimits:function(x,y){var index=this.level;var left=this.x-this.types[index].width/2;var top=this.y-this.types[index].height/2;var width=this.types[index].width;var height=this.types[index].height;if(left<x && x<left+width && top<y && y<top+height){return true;}else{return false;}},// 看地方炮弹是否命中本机
    isShooted:function(shell){if(shell.destroyed==true){return false;}// 如果炮弹打中本机范围if(this.isWithinLimits(shell.x,shell.y)){this.destroyed=true;shell.destroyed=true;// 制造爆炸
            explosionMng.fire(this.x,this.y);// 游戏结束return true;}return false;},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<我方战机类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我方炮弹类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MyShell=function(x,y){Point.apply(this,arguments);this.types=[{width:11,height:11,file:'shell0.png'},{width:11,height:11,file:'shell1.png'},{width:11,height:11,file:'shell2.png'},{width:11,height:11,file:'shell3.png'},{width:11,height:11,file:'shell4.png'},{width:11,height:11,file:'shell5.png'},{width:11,height:11,file:'shell6.png'},{width:18,height:18,file:'shell7.png'},];}
MyShell.prototype={types:[],        // 炮弹型号
    destroyed:false,// 是否被敌机撞毁
    visible:true,    // 是否在CTX显示范围内
    level:3,        // 等级,用以决定炮弹型号
    speed:4,        // 炮弹速度(己方炮弹向上飞行)
    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);}},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.destroyed==false){this.y-=this.speed;}},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<我方炮弹类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我方炮弹管理者类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>19.3.16
MyShellMng=function(){shells=new Array();
}
MyShellMng.prototype={shells:[],        // 己方炮弹对象数组
    paint:function(ctx){for(var i=0;i<this.shells.length;i++){var s=this.shells[i];s.paint(ctx);}},// 取出子弹,count为个数
    fetch:function(count){var retval=new Array();console.log("原有己方炮弹数量=",this.shells.length);// 先取原有的炮弹for(var i=0;i<this.shells.length;i++){var s=this.shells[i];if(s.visible==false || s.destroyed==true){s.destroyed=false;s.visible=true;if(retval.length<count){retval.push(s);}}}// 不足再创建新的炮弹while(retval.length<count){var s=new MyShell(0,0);this.shells.push(s);retval.push(s);}console.log("现有己方炮弹数量=",this.shells.length);return retval;},// 移动炮弹
    move:function(){for(var i=0;i<this.shells.length;i++){var s=this.shells[i];s.move();}},// 判断炮弹是否撞到敌机
    probeCrashedEnemyPlane:function(){for(var i=0;i<this.shells.length;i++){var s=this.shells[i];if(s.visible==true && s.destroyed==false){if(enemyPlaneMng.isShooted(s)==true){s.destroyed=true;return;}}}},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<我方炮弹管理者类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//  常规函数:角度得到弧度
function getRad(degree){return degree/180*Math.PI;
}//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>敌方飞机类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EnemyPlane=function(x,y,level){Point.apply(this,arguments);this.level=level;this.types=[{width:117,height:64,file:'e0.png',shellCount:1,shootInterval:300,shellSpeed:3 ,reciprocatingRadius:0},{width:117,height:64,file:'e1.png',shellCount:2,shootInterval:270,shellSpeed:4 ,reciprocatingRadius:0.5},{width:100,height:77,file:'e2.png',shellCount:3,shootInterval:240,shellSpeed:5 ,reciprocatingRadius:1},{width:117,height:85,file:'e3.png',shellCount:4,shootInterval:210,shellSpeed:6 ,reciprocatingRadius:1.5},{width:117,height:93,file:'e4.png',shellCount:5,shootInterval:180,shellSpeed:7 ,reciprocatingRadius:2},{width:117,height:93,file:'e5.png',shellCount:6,shootInterval:150,shellSpeed:8 ,reciprocatingRadius:2.25},{width:117,height:96,file:'e6.png',shellCount:7,shootInterval:120,shellSpeed:9 ,reciprocatingRadius:2.5},{width:117,height:99,file:'e7.png',shellCount:8,shootInterval:90 ,shellSpeed:10,reciprocatingRadius:2.75},];
}
EnemyPlane.prototype={types:[],            // 飞机型号数组
    destroyed:false,    // 是否被击毁
    level:7,            // 等级,用此取飞机型号
    visible:true,        // 是否在ctx显示范围内
    speed:2,            // 敌机向下飞行的速度
    paint:function(ctx){  // 不可见则不显示if(this.visible==false){return;}if(this.destroyed==false){// 没被击毁显示飞机型号var img=new Image();var index=this.level;if(index>this.types.length-1){console.log("非法的敌机level值="+this.level);index=this.types.length-1;}img.src=this.types[index].file;ctx.drawImage(img,this.x-this.types[index].width/2,this.y-this.types[index].height/2);// 标出本机下x,y坐标//var img2=new Image();//img2.src="shoot.png";//ctx.drawImage(img2,this.x-5.5,this.y-5.5);
        }},// 判断以x,y为坐标的点是否进入敌机四角范围内
    isWithinLimits:function(x,y){var index=this.level;var left=this.x-this.types[index].width/2;var top=this.y-this.types[index].height/2;var width=this.types[index].width;var height=this.types[index].height;if(left<x && x<left+width && top<y && y<top+height){return true;}else{return false;}},// 敌机飞行
    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){var index=this.level;this.y+=this.speed;this.x+=this.types[index].reciprocatingRadius*Math.sin(getRad(this.y));//  行动中随机开枪var rnd=this.getRndBetween(0,this.types[index].shootInterval);// 上限越大打得越慢,这个值可以叫ShootIntervalif(rnd<1){this.shoot();}}},// 得到随机数
    getRndBetween:function (lowerLimit,upperLimit){return Math.floor(Math.random()*(upperLimit-lowerLimit+1))+lowerLimit;},//  敌机开炮
    shoot:function(){if(this.destroyed==false){var index=this.level;// 得到炮弹var shellCount=this.types[index].shellCount;var shells=enemyShellMng.fetch(shellCount);// 用来控制炮弹发射位置var xLeft=this.x-this.types[index].width/2;var offset=this.types[index].width/(shellCount+1);for(var i=0;i<shellCount;i++){var s=shells[i];s.x=xLeft+(i+1)*offset;s.y=this.y;s.speed=this.types[index].shellSpeed;}}},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<敌方飞机类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>敌方飞机管理类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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:[],// 得到lowerLimit到upperlimit(包括端点值)的随机整数
    getRndBetween:function (lowerLimit,upperLimit){return Math.floor(Math.random()*(upperLimit-lowerLimit+1))+lowerLimit;},// 重新装载飞机
    reload:function(){var count=this.getAlivePlaneCount();if(count==0){var i=this.getRndBetween(0,this.planes.length-1);var plane=this.planes[i];plane.visible=true;plane.destroyed=falseplane.x=ctx.canvas.width/2+this.getRndBetween(-100,100);
            plane.y=this.getRndBetween(20,30);plane.level=this.getRndBetween(0,7);}},// 得到屏幕上飞机活着的飞机数目
    getAlivePlaneCount:function(){var retval=0;for(var i=0;i<this.planes.length;i++){var plane=this.planes[i];if(plane.visible==true && plane.destroyed==false){retval++;}}return retval;},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(shell){if(shell.destroyed==true){return false;}for(var i=0;i<this.planes.length;i++){var plane=this.planes[i];if(plane.visible==true && plane.destroyed==false){if(plane.isWithinLimits(shell.x,shell.y)){plane.destroyed=true;shell.destroyed=true;// 制造爆炸
                    explosionMng.fire(shell.x,shell.y);// 敌机重载
                    enemyPlaneMng.reload();return true;}}            }return false;},// 看主角飞机是否与敌机相撞
    isCrashed:function(rolePlane){if(rolePlane.destroyed==true){return false;}// 得到本机四角坐标var p1=rolePlane.getLeftUpPoint();var p2=rolePlane.getRightUpPoint();var p3=rolePlane.getLeftDownPoint();var p4=rolePlane.getRightDownPoint();for(var i=0;i<this.planes.length;i++){var ep=this.planes[i];if(ep.visible==true && ep.destroyed==false){if(ep.isWithinLimits(p1.x,p1.y) || ep.isWithinLimits(p2.x,p2.y) || ep.isWithinLimits(p3.x,p3.y) || ep.isWithinLimits(p4.x,p4.y)){ep.destroyed=true;// 敌机撞毁
                    explosionMng.fire(ep.x,ep.y);// 制造爆炸// 本机撞毁后不用敌机重载//enemyPlaneMng.reload();
                    rolePlane.destroyed=true;// 本机撞毁
                    explosionMng.fire(rolePlane.x,rolePlane.y);// 制造爆炸// 游戏结束return true;}}            }return false;},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<敌方飞机管理类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>爆炸类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Explosion=function(x,y){Point.apply(this,arguments);this.types=[{width:105,height:100,file:'explosion0.png'},{width:105,height:100,file:'explosion1.png'},{width:105,height:100,file:'explosion2.png'},{width:105,height:100,file:'explosion3.png'},{width:105,height:100,file:'explosion4.png'},{width:105,height:100,file:'explosion5.png'},];
}
Explosion.prototype={types:[],        // 爆炸图片
    destroyTime:0,    // 被摧毁时间
    paint:function(ctx){var index=Math.floor(this.destroyTime);if(index<this.types.length){this.destroyTime+=0.05;var img=new Image();            img.src=this.types[index].file;            ctx.drawImage(img,this.x-this.types[index].width/2,this.y-this.types[index].height/2);}},// 看这个爆炸对象是否使用过
    isUsed:function(){return this.destroyTime>=this.types.length;},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<爆炸类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>爆炸管理类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ExplosionMng=function(x,y){exps=new Array();
}
ExplosionMng.prototype={exps:[],        // 爆炸数组
    paint:function(ctx){for(var i=0;i<exps.length;i++){var e=exps[i];e.paint(ctx);}},// 制作一次爆炸,使用这种方式,可最大程度利用现有对象,而不是创建一堆用不上的变量
    fire:function(x,y){var exp=null;for(var i=0;i<exps.length;i++){var e=exps[i];//console.log('e.isUsed=',e.isUsed())if(e.isUsed()==true){exp=e;exp.x=x;exp.y=y;exp.destroyTime=0;//console.log('使用一个原有对象',exp)break;}}if(exp==null){exp=new Explosion(x,y);exps.push(exp);//console.log('创建一个新对象',exp)
        }//console.log('爆炸对象个数=',exps.length)
    },
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<爆炸管理类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>敌方炮弹类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 19.3.16
EnemyShell=function(x,y){Point.apply(this,arguments);this.types=[{width:11,height:11,file:'shell0.png'},{width:11,height:11,file:'shell1.png'},{width:11,height:11,file:'shell2.png'},{width:11,height:11,file:'shell3.png'},{width:11,height:11,file:'shell4.png'},{width:11,height:11,file:'shell5.png'},{width:11,height:11,file:'shell6.png'},{width:18,height:18,file:'shell7.png'},];}
EnemyShell.prototype={types:[],        // 炮弹型号
    destroyed:false,// 是否被敌机撞毁
    visible:true,    // 是否在CTX显示范围内
    level:0,        // 等级,用以决定炮弹型号
    speed:4,        // 炮弹速度(敌方炮弹向下飞行)
    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);}},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.destroyed==false){this.y+=this.speed;}},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<敌方炮弹类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>敌方炮弹管理者类定义开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>19.3.16
EnemyShellMng=function(){shells=new Array();
}
EnemyShellMng.prototype={shells:[],        // 己方炮弹对象数组
    paint:function(ctx){for(var i=0;i<this.shells.length;i++){var s=this.shells[i];s.paint(ctx);}},// 取出子弹,count为个数
    fetch:function(count){var retval=new Array();console.log("原有敌方炮弹数量=",this.shells.length);// 先取原有的炮弹for(var i=0;i<this.shells.length;i++){var s=this.shells[i];if(s.visible==false || s.destroyed==true){s.destroyed=false;s.visible=true;if(retval.length<count){retval.push(s);}}}// 不足再创建新的炮弹while(retval.length<count){var s=new EnemyShell(0,0);this.shells.push(s);retval.push(s);}console.log("现有敌方炮弹数量=",this.shells.length);return retval;},// 移动炮弹
    move:function(){for(var i=0;i<this.shells.length;i++){var s=this.shells[i];s.move();}},// 判断炮弹是否撞到本机
    probeCrashedMyPlane:function(){for(var i=0;i<this.shells.length;i++){var s=this.shells[i];if(s.visible==true && s.destroyed==false && myPlane.destroyed==false){if(myPlane.isShooted(s)==true){s.destroyed=true;return;}}}},
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<敌方炮弹管理者类定义结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//-->
</script>

2019年3月16日15点45分

转载于:https://www.cnblogs.com/xiandedanteng/p/10542577.html

[Canvas]空战游戏 已经可以玩了 1.13Playable相关推荐

  1. [canvas]空战游戏1.18

    空战游戏到今天可以玩了,玩法还是方向键(或AWSD)控制飞机位置,空格键开炮,吃五星升级,被敌机打中降级直到击落,与敌机相撞则GG. 点此下载程序1.16版,用CHrome打开index.html试玩 ...

  2. 做游戏,学编程(C语言) 6 数组之空战游戏

    利用数组,我们可以在空战游戏中实现多台敌机.发射闪弹等效果.大家可以用之前教程的思路,尝试分步骤实现:飞机的显示.单个敌机.多个敌机.发射常规子弹.发射闪弹,以下是完整的代码. #include &l ...

  3. c语言easyx输出文字_做游戏,学编程(C语言) 6 数组之空战游戏

    利用数组,我们可以在空战游戏中实现多台敌机.发射闪弹等效果.大家可以用之前教程的思路,尝试分步骤实现:飞机的显示.单个敌机.多个敌机.发射常规子弹.发射闪弹,以下是完整的代码. #include &l ...

  4. 大家都在发圣诞树,我偏偏要发一个圣诞小游戏给大家玩【内附源码】

    ​大家好,我是辣条. 前言 圣诞节快来了,热榜都被一堆圣诞树攻占了,这样的流量密码我怎么会错过,大家都发圣诞树,我就不发啦,直接分享一个圣诞小游戏给大家玩,代码太长一定要先赞和收藏. 领取福利 300 ...

  5. 开发一个Canvas小游戏 实现一个游戏“引擎”

    前言 这个游戏其实在三四年前就写了,中间还重构过好几次,之前都是用简单的面向对象和函数式编程来写,游戏中的元素关系到还是分的挺开,但是游戏的渲染,运算等逻辑分的不够清晰,整个逻辑基本都是自顶向下的流水 ...

  6. HTML5 2D Canvas手机游戏开发经验谈

    HTML5 2D Canvas手机游戏开发经验谈 临渊羡鱼,不如退而结网-HTML5 2DCanvas手机游戏开发经验谈 现在什么技术最火?HTML5!现在什么技术最时尚!还是HTML5!也许有泡沫和 ...

  7. 免费也可以很好玩,40款开源游戏任你玩(三)

    竞技游戏 1.Critical Mass 敌人无处不在,你必须小心发射导弹!                              Critical Mass是一个射击游戏.包含了三种不同的模式, ...

  8. 核爆rpg手机版_好嗨游戏:不玩吃亏 ,20款全世界最佳移动RPG角色扮演游戏(上)...

    文章首发于:好嗨游戏 RPG(角色扮演游戏)毫无疑问是有史以来最好的游戏类型了,它也是兼容性最好的游戏类型,可以和其他各种类型结合形成新的有趣的游戏,比如在MOBA游戏中融入RPG的元素,同时它也比其 ...

  9. 构建一个react项目_您想要了解更多有关React的内容吗? 让我们构建一个游戏,然后玩。...

    构建一个react项目 by Samer Buna 通过Samer Buna 您想要了解更多有关React的内容吗? 让我们构建一个游戏,然后玩. (Do you want to learn more ...

最新文章

  1. OpenCV3.3中K-Means聚类接口简介及使用
  2. 微服务常见安全认证方案Session token cookie跨域
  3. 为何要fork()两次来避免产生僵尸进程?
  4. 遍历二叉树的神级方法(Morris遍历)
  5. linux的 su 错误 Permission denied 和 Incorrect pa...
  6. P7044-[MCOI-03]括号【组合数学】
  7. CocosCreator中TiledMap简单使用
  8. 缺少msvcr100.dll,小编教你丢失msvcr100.dll真正解决方法
  9. 网页颜色搭配,网站设计,Google logo配色 Google官方配色表
  10. BAT面试经验分享(机器学习算法岗)
  11. [论文解析] Diffusion Models Beat GANs on Image Synthesis
  12. Byte的数值范围为何是-128到127
  13. HDLBits刷题全记录(五)
  14. CANoe和CANoe.DiVa关于通信测试的简略汇总
  15. 关于SSD寿命问题的探讨
  16. 对地球生命的来源持有怀疑
  17. 基于ARM处理器的LCD控制及触摸屏接口设计
  18. Thinkphp里面设置url伪静态
  19. 2021-08-28
  20. 日本地图选择插件、日本地区选择插件

热门文章

  1. 开源分布式量化交易系统——架构设计
  2. 点对点专线接入方式,下面哪种接入方式适用于点对点专线接入?
  3. AI产品经理从业指南
  4. Visual Studio 2019 设置透明背景图(傻瓜式教学)
  5. 织梦主动提交_织梦CMS发表文章自动实现百度链接主动推送教程
  6. linux下c 上传图片到mysql_linux c做服务端使用多线程接收图片并且将图片写入数据库...
  7. STL常用操作:deque
  8. 小厨餐饮加盟有什么优势
  9. 2019人工智能生存指南
  10. Seq2Seq那些事