练习实现效果:敌人tank不动,自己tank上下左右移动并且连续发射子弹
实现工具:html5画布及js;运行环境:ie,在chrome下不行,暂未找到原因
效果截图:
核心思想:
1.创建画布,坦克对象Tank,敌人坦克(Enemys)和自己的坦克(Hero)均继承坦克对象。
创建自己的子弹对象(Bullet,包含自身相关信息以及向前运动的函数run()),创建子弹数组(heroBullets)。
2.给body的onkeydown绑定事件(获取每次键盘输入,上右下左分别为wdxa,子弹发射为j)
3.每次按键上右下左,调用坦克(Hero)自身moveUp/moveRight/moveDown/moveLeft函数,改变坐标,然后定期刷新(使用window.setInterval()函数)
每次按键发射子弹,调用对象(Hero)的shotBullet()函数,shotBullet中根据不同方向实例化子弹(bullet),把子弹通过heroBullets.push(bullet)进入子弹数组,
定期刷新(window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);),实现子弹的不断往前运动。
4.刷新方法简介:第一步清屏,然后画出敌人坦克和自己坦克,如果子弹对象此时不是null,代表已经创建了子弹,画出子弹,反之则不画。
让子弹飞的过程:按下j后子弹的run函数循环被调用,50ms为周期。页面刷新则以100ms为周期,此时每50ms改变子弹的坐标,再50ms后刷新页面,显示子弹,再50ms后改变子弹
坐标,如此循环往复,则看到子弹飞起来了。
我的代码:
1 <!DOCTYPE html> 2 <html> 3 <header>网页的头部</header> 4 <head><script type="text/javascript" src="js/tank.js"></script></head> 5 <body onkeydown="getCommand()"> 6 <h1>经典的坦克大战</h1> 7 <canvas id="tankMap" width="400px" height="300px" style="background-color:black"> 8 </canvas> 9 <script type="text/javascript"> 10 var canvas=document.getElementById("tankMap"); 11 var cxt=canvas.getContext("2d"); 12 var heroColor=new Array("#fa3e54","#FF6F00","yellow"); 13 var enemyColor=new Array("#00AE68","#057D9F","#62E200"); 14 //定义一个子弹 15 var bullet=null; 16 //定义一个子弹数组 17 var heroBullets=new Array(); 18 //创建自己的tank 19 var hero1=new Hero(60,50,2,1); 20 var enemys=new Array(); 21 //创建敌人的tank 22 for (var i=0;i<3;i++) 23 { 24 enemys[i]=new Enemy(50+i*50,0,2,1); 25 } 26 flashTankMap(); 27 window.setInterval("flashTankMap()",100); 28 //***********画tank********** 29 function Tank(x,y,direction,speed,color) 30 { 31 this.x=x; 32 this.y=y; 33 this.speed=speed; 34 this.color=color; 35 //0代表上,1代表右,2代表下,3代表左;分别用wdxa代表上右下左,其ascii码分别为87,68,88,65 36 this.direction=direction; 37 this.moveUp=function() 38 { 39 this.direction=0; 40 this.y-=this.speed; 41 }; 42 this.moveDown=function() 43 { 44 this.direction=2; 45 this.y+=this.speed; 46 }; 47 this.moveLeft=function(){ 48 this.direction=3; 49 this.x-=this.speed; 50 }; 51 this.moveRight=function(){ 52 this.direction=1; 53 this.x+=this.speed; 54 }; 55 } 56 function drawBullet() 57 { 58 59 //画一个子弹 60 61 if(bullet!=null&&bullet.isLive) 62 { 63 cxt.fillStyle=="yellow"; 64 cxt.lineWidth=3; 65 cxt.beginPath(); 66 cxt.fillRect(bullet.x-2,bullet.y-2,3,3); 67 cxt.closePath(); 68 } 69 document.getElementById("bb").innerText="drawBullet 中x="+bullet.x+"y="+bullet.y; 70 } 71 72 function drawBullets() 73 { 74 //原来画一个子弹,现在画出所有子弹 75 for (var i=0;i<heroBullets.length;i++) 76 { 77 var heroBullet=heroBullets[i]; 78 if(heroBullet!=null&&heroBullet.isLive) 79 { 80 cxt.fillStyle=="yellow"; 81 cxt.lineWidth=3; 82 cxt.beginPath(); 83 cxt.fillRect(heroBullet.x-2,heroBullet.y-2,3,3); 84 cxt.closePath(); 85 } 86 document.getElementById("bb").innerText="drawBullet 中x="+bullet.x+"y="+bullet.y; 87 } 88 } 89 90 function Bullet(x,y,direction,speed) 91 { 92 this.x=x; 93 this.y=y; 94 this.direction=direction; 95 this.speed=speed; 96 var d=this.direction; 97 this.timer=null; 98 this.isLive=true; 99 this.run=function run() 100 { 101 //在改变这个子弹的坐标时,先判断子弹是否已经到边界了 102 if(this.x<=0||this.x>=400||this.y<=0||this.y>=300) 103 { 104 //子弹要停止 105 window.clearInterval(this.timer); 106 this.isLive=false; 107 }else 108 { 109 if(d==0)//上 110 { 111 this.y-=this.speed; 112 } 113 else if(d==1)//右 114 { 115 this.x+=this.speed; 116 } 117 else if(d==2)//下 118 { 119 this.y+=this.speed; 120 } 121 else if(d==3)//左 122 { 123 this.x-=this.speed; 124 } 125 document.getElementById("aa").innerText="子弹x="+bullet.x+"子弹y="+bullet.y; 126 } 127 }; 128 129 } 130 131 function Hero(x,y,direction,speed) 132 { 133 //继承Tank的内容 134 this.hero=Tank; 135 this.hero(x,y,direction,speed,this.color); 136 this.color=heroColor; 137 //shot 138 this.shotBullet=function() 139 { 140 //创建一个子弹 141 if(this.direction==0)//上 142 { 143 bullet=new Bullet(this.x+8+30/2,this.y-10,this.direction,this.speed); 144 } 145 else if(this.direction==1)//右 146 { 147 bullet=new Bullet(this.x+40/2+25,this.y+8+20/2,this.direction,this.speed); 148 } 149 else if(this.direction==2)//下 150 { 151 bullet=new Bullet(this.x+15+8,this.y+15+25,this.direction,this.speed); 152 } 153 else if(this.direction==3)//左 154 { 155 bullet=new Bullet(this.x+40/2-25,this.y+8+20/2,this.direction,this.speed); 156 } 157 158 /*单个子弹的时候的timer计时器*/ 159 //var timer=window.setInterval("bullet.run()",50); 160 //把该子弹装入到子弹数组中 161 heroBullets.push(bullet); 162 163 /*多子弹的时候的timer计时器; 164 此处是点了几下j,就有几个timer,每个子弹定时器是独立的。 165 如果按照上面的 方法,则所有子弹共享一个定时器,故速度会越来越快 166 */ 167 var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50); 168 //把timer赋值给子弹(js对象是引用传递) 169 heroBullets[heroBullets.length-1].timer=timer; 170 }; 171 } 172 function Enemy(x,y,direction,speed) 173 { 174 this.enemy=Tank; 175 this.color=enemyColor; 176 this.enemy(x,y,direction,speed,this.color); 177 } 178 179 //***********获取按键上右下左方向,并且清屏,常见坦克 180 function flashTankMap() 181 { 182 183 cxt.clearRect(0, 0, 400, 300); 184 //画自己的tank 185 drawTank(hero1); 186 //画敌人的坦克 187 for(var i=0;i<3;i++) 188 { 189 drawTank(enemys[i]); 190 } 191 //如果子弹不是空的,画出子弹 192 if(bullet!=null) 193 { 194 drawBullets(); 195 } ; 196 } 197 function getCommand(){ 198 199 if(event.keyCode==87)//上 200 { 201 hero1.moveUp(); 202 } 203 else if(event.keyCode==65)//左 204 { 205 hero1.moveLeft(); 206 } 207 else if(event.keyCode==68)//右 208 { 209 hero1.moveRight(); 210 } 211 else if(event.keyCode==88)//下 212 { 213 hero1.moveDown(); 214 } 215 else if(event.keyCode==74)//发射子弹 216 { 217 hero1.shotBullet(); 218 } 219 flashTankMap(); 220 } ; 221 222 </script> 223 <input type="text" id="aa"></input> 224 <input type="text" id="bb"></input> 225 </body> 226 <footer>网页的尾部</footer> 227 </html>