基于HTML5开发小坦克大战
坦克运行全景图,因为是html5,所以要在支持html5的浏览器下运行.Chrome,Safari,Firefox 3.6,Opera 10.5.几乎所有的移动终端的设备的浏览器都支持html5.所以说html5是必然的趋势.
1. 增加 <canvas> 标签
2. 增加 <header> 和 <footer> 标签
3. 增加音频和视频嵌入功能 <video>和 <audio>
case 2:
if(tank.type==0){
cxt.fillStyle="#C69952";
}else if(tank.type==1){
cxt.fillStyle="#009DBE";
}
cxt.fillRect(tank.x,tank.y,5,30);
cxt.fillRect(tank.x+25,tank.y,5,30);
cxt.fillRect(tank.x+6,tank.y+5,18,20);
//坦克盖子
if(tank.type==0){
cxt.fillStyle="#FEF377";
}else if(tank.type==1){
cxt.fillStyle="#00FEFE";
}
cxt.arc(tank.x+15,tank.y+15,6,0,360,true);
cxt.fill();
cxt.lineWidth=2;
if(tank.type==0){
cxt.strokeStyle="#FEF377";
}else if(tank.type==1){
cxt.strokeStyle="#00FEFE";
}
cxt.beginPath();
cxt.moveTo(tank.x+15,tank.y+15);
if(tank.direct==0){
cxt.lineTo(tank.x+15,tank.y);
}else if(tank.direct==2){
cxt.lineTo(tank.x+15,tank.y+30);
}
cxt.closePath();
cxt.stroke();
break;
case 3:
if(tank.type==0){
cxt.fillStyle="#C69952";
}else if(tank.type==1){
cxt.fillStyle="#009DBE";
}
cxt.fillRect(tank.x,tank.y,30,5);
cxt.fillRect(tank.x,tank.y+25,30,5);
cxt.fillRect(tank.x+5,tank.y+6,20,18);
//坦克盖子
if(tank.type==0){
cxt.fillStyle="#FEF377";
}else if(tank.type==1){
cxt.fillStyle="#00FEFE";
}
cxt.arc(tank.x+15,tank.y+15,6,0,360,true);
cxt.fill();
cxt.lineWidth=2;
if(tank.type==0){
cxt.strokeStyle="#FEF377";
}else if(tank.type==1){
cxt.strokeStyle="#00FEFE";
}
cxt.beginPath();
cxt.moveTo(tank.x+15,tank.y+15);
if(tank.direct==1){
cxt.lineTo(tank.x+30,tank.y+15);
}else if(tank.direct==3){
cxt.lineTo(tank.x,tank.y+15);
}
cxt.closePath();
cxt.stroke();
break;
这段
代码就是画坦克并且分别对敌我坦克进行颜色的分配.
坦克画完后,接下来就是控制坦克的移动.通过键盘不同的控制坦克移动.坦克的移动,首先确定其方向,就是上面的那个方向direct.这个是很重要的.而坦克的移动都是通过相对的坐标的改变,而做出改变.
var keyCode=event.keyCode;
switch(keyCode){
case 87:
hero.moveUp();
break;
case 68:
hero.moveRight();
break;
case 83:
hero.moveDown();
break;
case 65:
hero.moveLeft();
break;
case 74:
hero.shotEnemy();
break;
}
这段代码就是获得键码的值.然后分别对移动函数进行编写.此处有一个问题要注意,就是坦克不能出界,所以在考虑坦克的移动的过程中,坦克不能出界.所以在移动前要进行判断.是否出界.
function Tank(x,y,direct,type){
this.x=x;
this.y=y;
this.direct=direct;
this.type=type;//0 表示自己坦克, 1表示敌人坦克
this.moveUp=function(){
this.direct=0;
if(this.y>0){
this.y--;}else{
this.y=0;
}
}
this.moveRight=function(){
this.direct=1;
if(this.x<370){
this.x++;}else{
this.x=370;
}
}
this.moveDown=function(){
this.direct=2;
if(this.y<270){
this.y++;}else{
this.y=270;
}
}
this.moveLeft=function(){
this.direct=3;
if(this.x>0){this.x--;}else{
this.x=0;
}
}
有了坦克,接下来应该定义子弹,对子弹进行定义.画子弹.所以子弹也是通过键盘控制.由上面的一样,然后对子弹进行定义.子弹必然包括类型,方向,和生命周期.
function Bullet(x,y,direct,speed,tank,type){
this.x=x;
this.y=y;
this.direct=direct;
this.speed=speed;
this.tank=tank;
this.type=type;
this.timer=null;
this.isLive=true;
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;
}
定义子弹后,然后就是子弹遇到坦克时候,要摧毁坦克.对坦克进行摧毁.而且子弹自己的生命周期在遭遇敌军坦克的时候,就结束.所以此处要做的就是对子弹生命周期判断.
for(var i=0;i<heroBullets.length;i++){
//取出一颗子弹
//heroBullet=heroBullets[i];
for( var j=0;j<enemyTanks.length;j++){
if(enemyTanks[j].isLive){
//判断,需要先判断敌人坦克的方向
switch(enemyTanks[j].direct){
case 0:
case 2:
if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
enemyTanks[j].isLive=false;
heroBullets[i].isLive=false;
bomb=new Bomb(enemyTanks[j].x,enemyTanks[j].y);
bombs.push(bomb);
}
break;
case 1:
case 3:
if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
enemyTanks[j].isLive=false;
heroBullets[i].isLive=false;
bomb=new Bomb(enemyTanks[j].x,enemyTanks[j].y);
bombs.push(bomb);
}
break;
}
}
}
}
子弹摧毁坦克后,坦克就要消失.并且从画布上清除.所以此时要用到一个新的函数.window.setInterval("flashCanvas()",100);就是这个定时器.定时对画布进行管理.管理就是判断坦克存在与否.
function flashCanvas(){
cxt.clearRect(0,0,400,300);
//画出自己坦克
drawTank(hero);
//画出自己的子弹
drawHeroBullet();
//画出敌人的子弹;
drawEnemyBullet();
//判断是否击中坦克.
isHitEnemyTank(heroBullets,enemyTanks);
//判断自己是否被击中
//isHitHero(enemyBullets,hero);
//画出敌人坦克
for(var i=0;i<3;i++){
if(enemyTanks[i].isLive){
drawTank(enemyTanks[i]);
}
}
然后是让地方坦克进行随意的移动.即调用rand函数生成随机的方向标值即可.
if(this.count>=30){
//随机的改变方向
this.direct=Math.round(Math.random()*3);
this.count=0;
}
此外对敌军坦克分配子弹.并且启动子弹.
if(this.bulletIsLive==false){
switch(this.direct){
case 0:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x+14,this.y,this.direct,1.2,this,"enemy"));
break;
case 1:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x+30,this.y+14,this.direct,1.2,this,"enemy"));
break;
case 2:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x+14,this.y+30,this.direct,1.2,this,"enemy"));
break;
case 3:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x,this.y+14,this.direct,1.2,this,"enemy"));
break;
}
//启动这颗子弹
enemyBullets[enemyBullets.length-1].timer=window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);
this.bulletIsLive=true;
}
然后做坦克的爆炸效果.
if(enemyTanks[j].isLive){
//判断,需要先判断敌人坦克的方向
switch(enemyTanks[j].direct){
case 0:
case 2:
if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
enemyTanks[j].isLive=false;
heroBullets[i].isLive=false;
bomb=new Bomb(enemyTanks[j].x,enemyTanks[j].y);
bombs.push(bomb);
}
break;
case 1:
case 3:
if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
enemyTanks[j].isLive=false;
heroBullets[i].isLive=false;
bomb=new Bomb(enemyTanks[j].x,enemyTanks[j].y);
bombs.push(bomb);
}
break;
}
所以要定义炸弹类.并且设定炸弹爆炸效果生命周期.
function Bomb(x,y){
this.x=x;
this.y=y;
this.life=9;
this.isLive=true;
this.lifeDown=function(){
if(this.life>0){
this.life--;
}else {
this.isLive=false;
}
}
}
总体上坦克大战,可以运行了.但是还有很多问题没有解决.要对坦克不能相互重叠.所以要对坐标进行判断的.然后还有声音功效问题.在html5中已经有支持强大的媒体.所以这个一定要加上去..正在完善中...先把这个贴出来..已验证前面自己要写一个坦克大战游戏.呵呵..
说明自己没有食言和偷懒..嘿嘿..有兴趣可以交流哦..嘿嘿..
附上图片跟源代码还有素材:
源代码:
tankgame.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body onkeydown="sendCommand()">
<h1>经典的坦克大战</h1>
<table border=1px width=400px height=200px>
<tr ><td colspan="2" align="center">方向按键已经子弹按键</td></tr>
<tr><td align="center">向上</td><td>W</td></tr>
<tr><td align="center">向右</td><td>D</td></tr>
<tr><td align="center">向下</td><td>S</td></tr>
<tr><td align="center">向左</td><td>A</td></tr>
<tr><td align="center">子弹</td><td>J</td></tr>
</table>
<canvas id="tankmap" width="400px" height="300px" style="background-color:#000000">
</canvas>
<span id="data1">数据<span>
<script type="text/javascript" src="tankGame9.js"></script>
<script type="text/javascript">
var canvas1=document.getElementById("tankmap");
var cxt=canvas1.getContext("2d");
var bombs=new Array();
var hero=new Hero(240,240,0,0);
var heroBullets=new Array();
var enemyBullets=new Array();
var enemyTanks=new Array();
for(var i=0;i<3;i++){
enemyTanks[i]=new EnemyTank((i+1)*50,0,2,1);
//drawTank(enemyTanks[i]);
//启动敌人坦克运动
var timer=window.setInterval("enemyTanks["+i+"].run()",50);
enemyTanks[i].timer=timer;
//给敌人坦克分配子弹
enemyBullets[i]=new Bullet(enemyTanks[i].x+14,enemyTanks[i].y+30,enemyTanks[i].direct,1.2,enemyTanks[i],"enemy");
//启动这颗子弹
enemyBullets[i].timer=window.setInterval("enemyBullets["+i+"].run()",50);
}
//判断是否击中敌人的坦克.
function isHitEnemyTank(heroBullets,enemyTanks){
for(var i=0;i<heroBullets.length;i++){
//取出一颗子弹
//heroBullet=heroBullets[i];
for( var j=0;j<enemyTanks.length;j++){
if(enemyTanks[j].isLive){
//判断,需要先判断敌人坦克的方向
switch(enemyTanks[j].direct){
case 0:
case 2:
if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
enemyTanks[j].isLive=false;
heroBullets[i].isLive=false;
bomb=new Bomb(enemyTanks[j].x,enemyTanks[j].y);
bombs.push(bomb);
}
break;
case 1:
case 3:
if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
enemyTanks[j].isLive=false;
heroBullets[i].isLive=false;
bomb=new Bomb(enemyTanks[j].x,enemyTanks[j].y);
bombs.push(bomb);
}
break;
}
}
}
}
}
function flashCanvas(){
cxt.clearRect(0,0,400,300);
//画出自己坦克
drawTank(hero);
//画出自己的子弹
drawHeroBullet();
//画出敌人的子弹;
drawEnemyBullet();
//判断是否击中坦克.
isHitEnemyTank(heroBullets,enemyTanks);
//判断自己是否被击中
//isHitHero(enemyBullets,hero);
//画出敌人坦克
for(var i=0;i<3;i++){
if(enemyTanks[i].isLive){
drawTank(enemyTanks[i]);
}
}
//画出炸弹
for(var k=0;k<bombs.length;k++){
if(bombs[k].isLive){
if(bombs[k].life>6){
var img1=new Image();
img1.src="bomb_1.gif";
var x=bombs[k].x;
var y=bombs[k].y;
img1.onload=function(){
cxt.drawImage(img1,x,y,30,30);
}
}else if(bombs[k].life>3){
var img2=new Image();
img2.src="bomb_2.gif";
var x=bombs[k].x;
var y=bombs[k].y;
img2.onload=function(){
cxt.drawImage(img2,x,y,30,30);
}
}else{
var img3=new Image();
img3.src="bomb_3.gif";
var x=bombs[k].x;
var y=bombs[k].y;
img3.onload=function(){
cxt.drawImage(img3,x,y,30,30);
}
}
bombs[k].lifeDown();
if(bombs[k].life<=0){
bombs.splice(k,1);
}
}
}
}
// flashCanvas();
function sendCommand(){
var keyCode=event.keyCode;
switch(keyCode){
case 87:
hero.moveUp();
break;
case 68:
hero.moveRight();
break;
case 83:
hero.moveDown();
break;
case 65:
hero.moveLeft();
break;
case 74:
hero.shotEnemy();
break;
}
//drawTank(hero);
flashCanvas();
}
window.setInterval("flashCanvas()",100);
</script>
</body>
</html>
tankgame.js:
tankGame9.js
//定义几个常用的颜色
var heroColors=new Array("#C69952","#FEF377");
function Bomb(x,y){
this.x=x;
this.y=y;
this.life=9;
this.isLive=true;
this.lifeDown=function(){
if(this.life>0){
this.life--;
}else {
this.isLive=false;
}
}
}
function Tank(x,y,direct,type){
this.x=x;
this.y=y;
this.direct=direct;
this.type=type;//0 表示自己坦克, 1表示敌人坦克
this.moveUp=function(){
this.direct=0;
if(this.y>0){
this.y--;}else{
this.y=0;
}
}
this.moveRight=function(){
this.direct=1;
if(this.x<370){
this.x++;}else{
this.x=370;
}
}
this.moveDown=function(){
this.direct=2;
if(this.y<270){
this.y++;}else{
this.y=270;
}
}
this.moveLeft=function(){
this.direct=3;
if(this.x>0){this.x--;}else{
this.x=0;
}
}
}
//定义一个坦克类
function Hero(x,y,direct,type,colors){
this.isLive=true;
this.tank=Tank;
this.tank(x,y,direct,type,colors);
this.shotEnemy=function(){
switch(this.direct){
case 0:
heroBullet=new Bullet(this.x+14,this.y,this.direct,2,this,"hero");
break;
case 1:
heroBullet=new Bullet(this.x+30,this.y+14,this.direct,2,this,"hero");
break;
case 2:
heroBullet=new Bullet(this.x+14,this.y+30,this.direct,2,this,"hero");
break;
case 3:
heroBullet=new Bullet(this.x,this.y+14,this.direct,2,this,"hero");
break;
}
heroBullets.push(heroBullet);
//放入数组统一管理
var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);
heroBullets[heroBullets.length-1].timer=timer;
}
}
function EnemyTank(x,y,direct,type,colors){
this.isLive=true;
this.tank=Tank;
this.speed=1;
this.count=0;
this.bulletIsLive=true;
this.tank(x,y,direct,type);
this.timer=null;
this.run=function(){
//判断敌人坦克方向
switch(this.direct){
case 0:
if(this.y>0){
this.y-=this.speed;
}
break;
case 1:
if(this.x+30<400){
this.x+=this.speed;
}
break;
case 2:
if(this.y+30<300){
this.y+=this.speed;
}
break;
case 3:
if(this.x>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:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x+14,this.y,this.direct,1.2,this,"enemy"));
break;
case 1:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x+30,this.y+14,this.direct,1.2,this,"enemy"));
break;
case 2:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x+14,this.y+30,this.direct,1.2,this,"enemy"));
break;
case 3:
//添加一颗新子弹
//给敌人坦克分配子弹
enemyBullets.push(new Bullet(this.x,this.y+14,this.direct,1.2,this,"enemy"));
break;
}
//启动这颗子弹
enemyBullets[enemyBullets.length-1].timer=window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);
this.bulletIsLive=true;
}
}
}
//画出坦克
function drawTank(tank){
if(tank.isLive==true){
switch(tank.direct){
case 0:
case 2:
if(tank.type==0){
cxt.fillStyle="#C69952";
}else if(tank.type==1){
cxt.fillStyle="#009DBE";
}
cxt.fillRect(tank.x,tank.y,5,30);
cxt.fillRect(tank.x+25,tank.y,5,30);
cxt.fillRect(tank.x+6,tank.y+5,18,20);
//坦克盖子
if(tank.type==0){
cxt.fillStyle="#FEF377";
}else if(tank.type==1){
cxt.fillStyle="#00FEFE";
}
cxt.arc(tank.x+15,tank.y+15,6,0,360,true);
cxt.fill();
cxt.lineWidth=2;
if(tank.type==0){
cxt.strokeStyle="#FEF377";
}else if(tank.type==1){
cxt.strokeStyle="#00FEFE";
}
cxt.beginPath();
cxt.moveTo(tank.x+15,tank.y+15);
if(tank.direct==0){
cxt.lineTo(tank.x+15,tank.y);
}else if(tank.direct==2){
cxt.lineTo(tank.x+15,tank.y+30);
}
cxt.closePath();
cxt.stroke();
break;
case 1:
case 3:
if(tank.type==0){
cxt.fillStyle="#C69952";
}else if(tank.type==1){
cxt.fillStyle="#009DBE";
}
cxt.fillRect(tank.x,tank.y,30,5);
cxt.fillRect(tank.x,tank.y+25,30,5);
cxt.fillRect(tank.x+5,tank.y+6,20,18);
//坦克盖子
if(tank.type==0){
cxt.fillStyle="#FEF377";
}else if(tank.type==1){
cxt.fillStyle="#00FEFE";
}
cxt.arc(tank.x+15,tank.y+15,6,0,360,true);
cxt.fill();
cxt.lineWidth=2;
if(tank.type==0){
cxt.strokeStyle="#FEF377";
}else if(tank.type==1){
cxt.strokeStyle="#00FEFE";
}
cxt.beginPath();
cxt.moveTo(tank.x+15,tank.y+15);
if(tank.direct==1){
cxt.lineTo(tank.x+30,tank.y+15);
}else if(tank.direct==3){
cxt.lineTo(tank.x,tank.y+15);
}
cxt.closePath();
cxt.stroke();
break;
}
}
}
function Bullet(x,y,direct,speed,tank,type){
this.x=x;
this.y=y;
this.direct=direct;
this.speed=speed;
this.tank=tank;
this.type=type;
this.timer=null;
this.isLive=true;
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;
}
//判断是否已经需要停止
if(this.x<0||this.x>400||this.y<0||this.y>300 ||this.isLive==false){
this.isLive=false;
//停止这个定时器
window.clearInterval(this.timer);
if(this.type=="enemy"){
this.tank.bulletIsLive=false;
}
}
document.getElementById("data1").innerText="子弹x="+this.x+" 子弹y="+this.y;
}
}
function drawHeroBullet(){
for(var i=0;i<heroBullets.length;i++){
if(heroBullets[i].isLive){
cxt.fillRect(heroBullets[i].x,heroBullets[i].y,2,2);
}
}
}
function drawEnemyBullet(){
for(var i=0;i<enemyBullets.length;i++){
if(enemyBullets[i].isLive){
cxt.fillRect(enemyBullets[i].x,enemyBullets[i].y,2,2);
}
}
}