跟着韩老师学HTML5的tank大战一些问题和代码
2015-12-18 14:03
591 查看
说明:
1.韩老师讲的画tank盖子从0到360,会出现一个bug,就是所有tank的盖子连到一起了,看了下函数的API,应该写成从0到2*Math.PI,0到360并不是一个完整的圆。
2.代码实现的有:己方坦克按键控制,子弹连发,被击中时消失爆炸;敌方坦克自由移动,子弹消失后才可以发第二颗子弹,被击中时消失爆炸。所有坦克都不可以跑出画布范围。
3.未解决:坦克重叠的问题,自己的想法是,把坦克都看成是一个矩形,坐标为(tank.x , tank.y,tank.width , tnak.height),判断如果两个矩形接触,就把坦克的方向反转,或者,让其从新随机生成方向。
4.出现的问题和解决:
1.运行时,有时坦克会无缘故爆炸,后来我发现是因为,敌方坦克被我击中后,虽敌方坦克和敌方的子弹,以及我的子弹都消失了,但是敌方坦克子弹并没有死亡,只是没有被画出来,依然在跑。—解决–>让被我击中的坦克的子弹死亡
2.我被击中后爆炸消失后,依然可以移动和发子弹,也只是坦克没有被画出来而已。—解决–>我把画子弹和坦克的函数都增加判断,只有当hero.isLive为真是才能执行。
5.拓展:可以加上音效和场景。
6.效果图:再一次下方,是一个滚动提示
![](https://img-blog.csdn.net/20151218135610893)
7.代码:
drawtank.html
002tank.css
001tank.js
1.韩老师讲的画tank盖子从0到360,会出现一个bug,就是所有tank的盖子连到一起了,看了下函数的API,应该写成从0到2*Math.PI,0到360并不是一个完整的圆。
2.代码实现的有:己方坦克按键控制,子弹连发,被击中时消失爆炸;敌方坦克自由移动,子弹消失后才可以发第二颗子弹,被击中时消失爆炸。所有坦克都不可以跑出画布范围。
3.未解决:坦克重叠的问题,自己的想法是,把坦克都看成是一个矩形,坐标为(tank.x , tank.y,tank.width , tnak.height),判断如果两个矩形接触,就把坦克的方向反转,或者,让其从新随机生成方向。
4.出现的问题和解决:
1.运行时,有时坦克会无缘故爆炸,后来我发现是因为,敌方坦克被我击中后,虽敌方坦克和敌方的子弹,以及我的子弹都消失了,但是敌方坦克子弹并没有死亡,只是没有被画出来,依然在跑。—解决–>让被我击中的坦克的子弹死亡
2.我被击中后爆炸消失后,依然可以移动和发子弹,也只是坦克没有被画出来而已。—解决–>我把画子弹和坦克的函数都增加判断,只有当hero.isLive为真是才能执行。
5.拓展:可以加上音效和场景。
6.效果图:再一次下方,是一个滚动提示
<marquee>,初始值是“操作真6”,被击中后是“你真菜!”
7.代码:
drawtank.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>画坦克</title> <link rel="stylesheet" type="text/css" href="002tank.css"> <script type="text/javascript" src="001tank.js"></script> </head> <body onkeydown="getCommend();"> <canvas id="tankMap" width="500px" height="400px" style="background-color: black"></canvas> <div class="hint" > <p>A--左<br/><br/><br/>S--下<br/><br/><br/>D--右<br/><br/><br/>W--上<br/><br/><br/>J--子弹</p><br/> <a type="button" href="drawtank.html"><p>再来一次</p></a><br/> <marquee direction="left" > <span id="aa">操作真6</span> </marquee> </div> <script type="text/javascript"> var canvas1 = document.getElementById("tankMap"); var cxt = canvas1.getContext("2d"); //draw Tank var enemyTankSum = 9; //敌方坦克数量 var tankMapWidth = 500; var tankMapHeight = 400;//更画布的大小一致 var hero = new Hero((tankMapWidth/2)-20,tankMapHeight-30,0,heroColor); var enemyTanks = new Array(); for (var i=0;i<enemyTankSum;i++){ var enemyTank = new EnamyTank((i+1)*50,0,2,enemyColor); enemyTanks[i] = enemyTank; window.setInterval("enemyTanks["+i+"].run()",50); var eb=new Bullet(enemyTanks[i].x+9,enemyTanks[i].y+30,2,3,"enemy",enemyTanks[i]); enemyBullets[i]=eb; var ettimer=window.setInterval("enemyBullets["+i+"].run()",50); enemyBullets[i].timer=ettimer; } flashTankMap(); function flashTankMap(){ cxt.clearRect(0,0,tankMapWidth,tankMapHeight); drawHeroBullet(); isHitEnemyTank(); isHitHero(); drawEnemyBomb(); drawEnemyBullet(); for (var i=0;i<enemyTankSum;i++){ drawTank(enemyTanks[i]); } drawTank(hero); } //获取键盘的命令 function getCommend(){ var code = event.keyCode; switch (code){ case 87://W hero.moveUP(); break; case 68://D hero.moveRight(); break; case 83://S hero.moveDown(); break; case 12330 65://A hero.moveLeft(); break; case 74://J hero.shootEnemy(); break; } flashTankMap(); } window.setInterval("flashTankMap()",100); </script> </body> </html>
002tank.css
#tankMap{ background-color: black; float: left; border: 2px solid #FF0000; border-radius: 25px; box-shadow: 10px 10px 5px #FF5500; } .hint{ background-color: #C0C0C0; float: left; width: 200px; height: 400px; border: 2px solid #FF0000; border-radius: 25px; box-shadow: 10px 10px 5px #FF5500; margin-left: 20px; text-align:center; } .hint a{ display: block; color: black; background-color: red; text-decoration: none; }
001tank.js
/** * Created by Administrator on 2015/12/10. */ var heroColor = new Array("#FFFF00" , "#FFCC00"); var enemyColor = new Array("#00A2B5" , "#0000FF"); var heroBullets = new Array(); var enemyBullets = new Array(); var bombs = new Array(); function Bomb(x,y){ this.x=x; this.y=y; this.isLive=true; this.blood=9; this.bloodDown=function(){ if(this.blood>0){ this.blood--; }else{ this.isLive=false; } } } function Tank(x,y,direct,color){ this.x = x; this.y = y; this.speed=2; this.isLive=true; this.direct = direct; this.color = color; this.moveUP=function(){ if (this.y>0) { this.y-=this.speed; this.direct=0; } } this.moveRight=function(){ if (this.x<tankMapWidth-30) { this.x+=this.speed; this.direct=1; } } this.moveDown=function(){ if (this.y<tankMapHeight-30){ this.y+=this.speed; this.direct=2; } } this.moveLeft=function(){ if (this.x>0) { this.x-=this.speed; this.direct=3; } } } function Hero(x,y,direct,color){//xy is the tank's position ,direct is the tank's face this.tank = Tank; this.tank(x,y,direct,color); this.shootEnemy = function(){ switch (this.direct){ case 0: heroBullet = new Bullet(this.x+9,this.y,this.direct,4); break; case 1: heroBullet = new Bullet(this.x+30,this.y+9,this.direct,4); break; case 2: heroBullet = new Bullet(this.x+9,this.y+30,this.direct,4); break; case 3: heroBullet = new Bullet(this.x,this.y+9,this.direct,4); break; } heroBullets.push(heroBullet); var timer = window.setInterval("heroBullets["+(heroBullets.length-1) +"].run()",50); heroBullets[heroBullets.length-1].timer = timer; } } function EnamyTank(x,y,direct,color){//xy is the tank's position ,direct is the tank's face this.tank = Tank; this.tank(x,y,direct,color); this.count=0; this.bulletIsLive=true; this.run=function run(){ switch(this.direct){ case 0: if(this.y-this.speed>0) { this.y-=this.speed;} break; case 1: if(this.x+this.speed+30<tankMapWidth) {this.x+=this.speed;} break; case 2: if(this.y+this.speed+30<tankMapHeight) { this.y+=this.speed;break;} case 3: if(this.x-this.speed>0) {this.x-=this.speed;} break; } if(this.count>30){ this.direct=Math.round(Math.random()*3); this.count=0; } this.count++; if(this.bulletIsLive==false){//增子弹,这是需要考虑当前这个敌人坦克的方向 switch(this.direct){ case 0: etBullet=new Bullet(this.x+9,this.y,this.direct,3,"enemy",this); break; case 1: etBullet=new Bullet(this.x+30,this.y+9,this.direct,3,"enemy",this); break; case 2: etBullet=new Bullet(this.x+9,this.y+30,this.direct,3,"enemy",this); break; case 3: etBullet=new Bullet(this.x,this.y+9,this.direct,3,"enemy",this); break; } this.bulletIsLive=true; enemyBullets.push(etBullet); var mytimer=window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);//启动 enemyBullets[enemyBullets.length-1].timer=mytimer; } } } function drawHeroBullet(){ if(hero.isLive){ for(var i=0;i<heroBullets.length;i++){ var heroBullet = heroBullets[i]; if(heroBullet !=null && heroBullet.isLive){ cxt.fillStyle = "#FFFF00"; cxt.fillRect(heroBullet.x,heroBullet.y,2,2); } } } } function drawEnemyBullet(){ for(var i=0;i<enemyBullets.length;i++){ var etBullet = enemyBullets[i]; if(etBullet.isLive&&etBullet.tank.isLive){ cxt.fillStyle = "#FFFFFF"; cxt.fillRect(etBullet.x,etBullet.y,2,2); } } } function drawTank(tank) {//tank is an Object if (tank.isLive) { switch (tank.direct) { case 0: case 2: cxt.fillStyle = tank.color[0]; cxt.fillRect(tank.x, tank.y, 5, 30); cxt.fillRect(tank.x + 15, tank.y, 5, 30); cxt.fillRect(tank.x + 6, tank.y + 5, 8, 20); cxt.fillStyle = tank.color[1]; cxt.arc(tank.x + 10, tank.y + 15, 4, 0, 2*Math.PI, true); cxt.fill(); cxt.strokeStyle = tank.color[1]; cxt.lineWidth = 2; cxt.beginPath(); cxt.moveTo(tank.x + 10, tank.y + 15); if (tank.direct == 0) { cxt.lineTo(tank.x + 10, tank.y); } else if (tank.direct == 2) { cxt.lineTo(tank.x + 10, tank.y + 30); } cxt.closePath(); cxt.stroke(); break; case 1: case 3: cxt.fillStyle = tank.color[0]; cxt.fillRect(tank.x, tank.y, 30, 5); cxt.fillRect(tank.x , tank.y+ 15, 30, 5); cxt.fillRect(tank.x + 5, tank.y + 6, 20, 8); cxt.fillStyle = tank.color[1]; cxt.beginPath(); cxt.arc(tank.x + 15, tank.y + 10, 4, 0, 2*Math.PI, true); cxt.fill(); cxt.closePath(); cxt.strokeStyle = tank.color[1]; cxt.lineWidth = 2; cxt.beginPath(); cxt.moveTo(tank.x + 15, tank.y + 10); if (tank.direct == 1) { cxt.lineTo(tank.x + 30, tank.y + 10); } else if (tank.direct == 3) { cxt.lineTo(tank.x , tank.y + 10); } cxt.closePath(); cxt.stroke(); break; } } } function Bullet(x,y,direct,speed,type,tank){ this.x = x; this.y = y; this.direct = direct; this.speed = speed; this.type = type; this.tank = tank; this.timer = null; this.isLive = true; this.run = function run(){ if (this.x<=0||this.x>=tankMapWidth||this.y<=0||this.y>=tankMapHeight||this.isLive==false){ window.clearInterval(this.timer); this.isLive = false; if(this.type=="enemy"){ this.tank.bulletIsLive=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; } } } } function isHitEnemyTank(){ for(var i=0;i<heroBullets.length;i++){ var heroBullet=heroBullets[i]; if(heroBullet.isLive){ for(var j=0;j<enemyTanks.length;j++){ var enemyTank=enemyTanks[j]; if(enemyTank.isLive){ switch(enemyTank.direct){ case 0: case 2: if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+20 &&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+30){ enemyTank.isLive=false; heroBullet.isLive=false; var bomb=new Bomb(enemyTank.x,enemyTank.y); bombs.push(bomb); } break; case 1: case 3: if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+30 &&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+20){ enemyTank.isLive=false; heroBullet.isLive=false; var bomb=new Bomb(enemyTank.x,enemyTank.y); bombs.push(bomb); } break; } } } } } } function isHitHero(){ for(var i=0;i<enemyTanks.length;i++){ var enemyTank=enemyTanks[i]; if(enemyTank.isLive){ for(var j=0;j<enemyBullets.length;j++){ var enemyBullet=enemyBullets[j]; if(hero.isLive){ switch(hero.direct){ case 0: case 2: if(enemyBullet.x>=hero.x&&enemyBullet.x<=hero.x+20 &&enemyBullet.y>=hero.y&&enemyBullet.y<=hero.y+30){ hero.isLive=false; enemyBullet.isLive=false; var bomb=new Bomb(hero.x,hero.y); bombs.push(bomb); document.getElementById("aa").innerText = "你真菜!"; } break; case 1: case 3: if(enemyBullet.x>=hero.x&&enemyBullet.x<=hero.x+30 &&enemyBullet.y>=hero.y&&enemyBullet.y<=hero.y+20){ hero.isLive=false; enemyBullet.isLive=false; var bomb=new Bomb(hero.x,hero.y); bombs.push(bomb); document.getElementById("aa").innerText = "你真菜!"; } break; } } } } } } function drawEnemyBomb(){ for(var i=0;i<bombs.length;i++){ var bomb=bombs[i]; if(bomb.isLive){ //更据当前这个炸弹的生命值,来画出不同的炸弹图片 if(bomb.blood>6){ var img1=new Image(); img1.src="bomb_1.gif"; var x=bomb.x; var y=bomb.y; img1.onload=function(){ cxt.drawImage(img1,x,y,30,30); } }else if(bomb.blood>3){ var img2=new Image(); img2.src="bomb_2.gif"; var x=bomb.x; var y=bomb.y; img2.onload=function(){ cxt.drawImage(img2,x,y,30,30); } }else { var img3=new Image(); img3.src="bomb_3.gif"; var x=bomb.x; var y=bomb.y; img3.onload=function(){ cxt.drawImage(img3,x,y,30,30); } } bomb.bloodDown(); if(bomb.blood<=0){ bombs.splice(i,1); } } } }
相关文章推荐
- HTML5中在客户端验证文件上传的大小
- Canvas 在高清屏下绘制图片变模糊的解决方法
- 原生js结合html5制作小飞龙的简易跳球
- 三个不常见的 HTML5 实用新特性简介
- 低版本IE正常运行HTML5+CSS3网站的3种解决方案
- js+HTML5实现canvas多种颜色渐变效果的方法
- javascript+HTML5的Canvas实现Lab单车动画效果
- javascript+html5实现绘制圆环的方法
- HTML5实现微信拍摄上传照片功能
- jQuery+HTML5加入购物车代码分享
- 基于Jquery和html5的7款个性化地图插件
- 实现音乐播放器的代码(html5+css3+jquery)
- 2014 HTML5/CSS3热门动画特效TOP10
- jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码
- HTML5使用DeviceOrientation实现摇一摇功能
- 使用HTML5中postMessage知识点解决Ajax中POST跨域问题
- MVC中基于Ajax和HTML5实现文件上传功能
- jquery+html5烂漫爱心表白动画代码分享
- spring+html5实现安全传输随机数字密码键盘