您的位置:首页 > Web前端 > HTML5

跟着韩老师学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.效果图:再一次下方,是一个滚动提示
<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 tank