Dans le dernier article, nous avons créé le char ennemi et notre propre char. Ensuite, nous devrions laisser le char tirer des balles. Voyons comment faire en sorte que notre char tire des balles.
Plus tôt, nous avons utilisé la pensée orientée objet pour encapsuler Tank, et utilisé l'usurpation d'identité d'objet pour implémenter notre tank et le tank ennemi. En suivant cette méthode, devrions-nous également encapsuler une Bullet ? D'accord, réfléchissons alors à ce que cette « classe » Bullet devrait encapsuler ? La position doit être là, la direction du vol de la balle doit être là, la vitesse de vol doit être là et l'action de s'envoler par elle-même doit être là. D'accord, c'est tout. La "classe t" encapsulée de Bulle est la suivante :
//子弹类 function Bullet(x,y,direct,speed){ this.x=x; this.y=y; this.speed=speed; this.direct=direct; this.timer=null; this.run=function(){ switch(this.direct){ case 0: this.y-=this.speed; break; case 1: this.x+=this.speed; break; case 2: this.y+=this.speed; break; case 3: this.x-=this.speed; break; } } }
Nous avons créé le modèle de balle, nous allons maintenant utiliser notre tank pour créer la balle et envoyer la balle, dans Hero Ajoutez la méthode shotEnemy à la classe.
//定义一个Hero类 function Hero(x,y,direct,color){ //下面两句话的作用是通过对象冒充达到继承的效果 this.tank=Tank; this.tank(x,y,direct,color); //射击敌人函数 this.shotEnemy=function(){ switch(this.direct){ case 0: heroBullet=new Bullet(this.x+10,this.y,this.direct,1); break; case 1: heroBullet=new Bullet(this.x+30-4,this.y+10+4,this.direct,1); break; case 2: heroBullet=new Bullet(this.x+10,this.y+30,this.direct,1); break; case 3: heroBullet=new Bullet(this.x-4,this.y+10+4,this.direct,1); break; } //把这个子弹放入数组中——》push函数 //调用我们子弹的run //var timer=window.setInterval("heroBullet.run()",50); //heroBullet.timer=timer; heroBullets.push(heroBullet); var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50); heroBullets[heroBullets.length-1].timer=timer; } }
Ajoutez une touche "J" pour écouter les tirs de balles dans la fonction d'écoute des touches
case 74: //J :发子弹 hero.shotEnemy(); break;
D'accord, essayons de tirer des balles ! Pourquoi une seule balle peut-elle être tirée, et cela devient de plus en plus rapide ? En regardant le code que nous avons écrit ci-dessus, il s'avère qu'une fois que nos balles sont tirées, elles ne peuvent pas s'arrêter. Même si elles ont quitté notre "champ de bataille", elles courent toujours dans une direction une fois que la deuxième balle est tirée, la première. bullet disparaîtra car la puce n'est pas redessinée lorsque l'interface est actualisée. Bon, maintenant que nous connaissons la raison, déterminons si la balle est hors limites, puis donnons à la balle l'état isLive (cet état indique si la balle existe, si elle n'existe pas, elle ne sera pas redessinée lorsque le la puce est redessinée). Le code modifié est le suivant :
//子弹类 unction Bullet(x,y,direct,speed){ this.x=x; this.y=y; this.speed=speed; this.direct=direct; this.timer=null; this.isLive=true; this.run=function(){ //判断子弹是否已经到边界了 if(this.x<=0||this.x>=400||this.y<=0||this.y>=300){ //子弹要停止 window.clearInterval(this.timer); //子弹死亡 this.isLive=false; }else{ //可以去修改坐标 switch(this.direct){ case 0: this.y-=this.speed; break; case 1: this.x+=this.speed; break; case 2: break; } } }
Si la puce dépasse la portée du canevas, définissez l'attribut isLive sur false
Ensuite, nous ajoutons un rafraîchissement dans la fonction d'interface de rafraîchissement précédente Fonction Bullet
//定时刷新我们的作战区(定时重绘) //自己的坦克,敌人坦克,子弹,炸弹,障碍物 function flashTankMap(){ //把画布清理 cxt.clearRect(0,0,400,300); //我的坦克 drawTank(hero); //我的子弹 drawHeroBullet(); //敌人的坦克 for(var i=0;i<3;i++){ drawTank(enemyTanks[i]); } }
//画出自己的子弹 function drawHeroBullet(){ for(var i=0;i<heroBullets.length;i++){ var heroBullet=heroBullets[i]; if(heroBullet!=null&&heroBullet.isLive){ cxt.fillStyle="#FEF26E"; cxt.fillRect(heroBullet.x,heroBullet.y,2,2); } } }
Vous pouvez voir que l'attribut isLive de la puce est jugé dans le drawHeroBullet ci-dessus.
Jetons un coup d'œil aux résultats en cours
Le code source complet est le suivant :
tankGame06.js
//为了编程方便,我们定义两个颜色数组 var heroColor=new Array("#BA9658","#FEF26E"); var enemyColor=new Array("#00A2B5","#00FEFE"); //子弹类 function Bullet(x,y,direct,speed){ this.x=x; this.y=y; this.speed=speed; this.direct=direct; this.timer=null; this.isLive=true; this.run=function(){ //判断子弹是否已经到边界了 if(this.x<=0||this.x>=400||this.y<=0||this.y>=300){ //子弹要停止 window.clearInterval(this.timer); //子弹死亡 this.isLive=false; }else{ //可以去修改坐标 switch(this.direct){ case 0: this.y-=this.speed; break; case 1: this.x+=this.speed; break; case 2: this.y+=this.speed; break; case 3: this.x-=this.speed; break; } } } } //定义一个Tank类(基类) function Tank(x,y,direct,color){ this.x=x; this.y=y; this.speed=1; this.direct=direct; this.color=color; //上移 this.moveUp=function(){ this.y-=this.speed; this.direct=0; } //右移 this.moveRight=function(){ this.x+=this.speed; this.direct=1; } //下移 this.moveDown=function(){ this.y+=this.speed; this.direct=2; } //左移 this.moveLeft=function(){ this.x-=this.speed; this.direct=3; } } //定义一个Hero类 function Hero(x,y,direct,color){ //下面两句话的作用是通过对象冒充达到继承的效果 this.tank=Tank; this.tank(x,y,direct,color); //设计敌人函数 this.shotEnemy=function(){ switch(this.direct){ case 0: heroBullet=new Bullet(this.x+10,this.y,this.direct,1); break; case 1: heroBullet=new Bullet(this.x+30-4,this.y+10+4,this.direct,1); break; case 2: heroBullet=new Bullet(this.x+10,this.y+30,this.direct,1); break; case 3: heroBullet=new Bullet(this.x-4,this.y+10+4,this.direct,1); break; } //把这个子弹放入数组中——》push函数 //调用我们子弹的run //var timer=window.setInterval("heroBullet.run()",50); //heroBullet.timer=timer; heroBullets.push(heroBullet); var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50); heroBullets[heroBullets.length-1].timer=timer; } } //定义一个EnemyTank类 function EnemyTank(x,y,direct,color){ this.tank=Tank; this.tank(x,y,direct,color); } //绘制坦克 function drawTank(tank){ //考虑方向 switch(tank.direct){ case 0: //向上 case 2: //向下 //设置颜色 cxt.fillStyle=tank.color[0]; //左边的矩形 cxt.fillRect(tank.x,tank.y,5,30); //右边的矩形 cxt.fillRect(tank.x+17,tank.y,5,30); //画中间的矩形 cxt.fillRect(tank.x+6,tank.y+5,10,20); //画出坦克的盖子 cxt.fillStyle=tank.color[1]; cxt.arc(tank.x+11,tank.y+15,5,0,Math.PI*2,true); cxt.fill(); //画出炮筒 cxt.strokeStyle=tank.color[1]; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+11,tank.y+15); if(tank.direct==0){ //只是炮筒的方向不同 cxt.lineTo(tank.x+11,tank.y); }else{ cxt.lineTo(tank.x+11,tank.y+30); } cxt.closePath(); cxt.stroke(); break; case 1: case 3: //设置颜色 cxt.fillStyle="#BA9658"; //上边的矩形 cxt.fillRect(tank.x-4,tank.y+4,30,5); //下边的矩形 cxt.fillRect(tank.x-4,tank.y+17+4,30,5); //画中间的矩形 cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+15-4,tank.y+11+4,5,0,Math.PI*2,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+15-4,tank.y+11+4); if(tank.direct==1){ //只是炮筒的方向不同 cxt.lineTo(tank.x+30-4,tank.y+11+4); }else{ cxt.lineTo(tank.x-4,tank.y+11+4); } cxt.closePath(); cxt.stroke(); break; } }
Tank Battle.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body onkeydown="getCommand();"> <h1>html5-坦克大战</h1> <!--坦克大战的战场--> <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas> <!--将tankGame04.js引入--> <script type="text/javascript" src="tankGame06.js"></script> <script type="text/javascript"> //得到画布 var canvas1=document.getElementById("tankMap"); //得到绘图上下文 var cxt=canvas1.getContext("2d"); //我的tank //规定0向上、1向右、2向下、3向左 var hero=new Hero(40,40,0,heroColor); //定义子弹数组 var heroBullets=new Array(); //敌人的tank var enemyTanks=new Array(); for(var i=0;i<3;i++){ var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor); enemyTanks[i]=enemyTank; } //画出自己的子弹 function drawHeroBullet(){ for(var i=0;i<heroBullets.length;i++){ var heroBullet=heroBullets[i]; if(heroBullet!=null&&heroBullet.isLive){ cxt.fillStyle="#FEF26E"; cxt.fillRect(heroBullet.x,heroBullet.y,2,2); } } } //定时刷新我们的作战区(定时重绘) //自己的坦克,敌人坦克,子弹,炸弹,障碍物 function flashTankMap(){ //把画布清理 cxt.clearRect(0,0,400,300); //我的坦克 drawTank(hero); //我的子弹 drawHeroBullet(); //敌人的坦克 for(var i=0;i<3;i++){ drawTank(enemyTanks[i]); } } flashTankMap(); //接收用户按键的函数 function getCommand(){ var code = event.keyCode; //键盘上字幕的ASCII码 switch(code){ case 87: //W :上 hero.moveUp(); break; case 68: //D :右 hero.moveRight(); break; case 83: //S :下 hero.moveDown(); break; case 65: //A :左 hero.moveLeft(); break; case 74: //J :发子弹 hero.shotEnemy(); break; } flashTankMap(); } //每隔100毫秒去刷新一次作战区 window.setInterval("flashTankMap()",100); </script> </body> </html>
Ce qui précède est le contenu de la route de développement mobile HTML5 de Xiaoqiang (9) - Tank Battle Game 3. Pour en savoir plus contenu, veuillez faire attention à PHP Chinese Net (www.php.cn) !