2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > html坦克游戏 HTML5+JS实现坦克大战小游戏

html坦克游戏 HTML5+JS实现坦克大战小游戏

时间:2019-09-25 15:05:33

相关推荐

html坦克游戏 HTML5+JS实现坦克大战小游戏

听了韩顺平老师的视频教程,学到了不少编程思想,原来看似简单的坦克大战小游戏写起来其实并不简单。这里总结一下这几天学到的东西。

首先是关于html5的知识了。这里我们基本上只用了画布canvas来画坦克,还有就是html5的第一行来说明这是一个使用html5写的页面,html5的特性之一就包括canvas,这是html中没有的标签。

另外一个就是js了,涉及到的语法都是最简单、最基本的用法,这在代码中进行解释。同时,韩老师在这个视频中代码有个bug就是敌人坦克在死后依然会发子弹,小弟在此进行了修正。

接下来最重要的就是我们要来分析一下坦克大战小游戏的设计思路:

1、要有作战区域,这有canvas 可以帮我们解决。

2、要有坦克,包括自己的、敌人的。

3、要能有子弹,包括自己的、敌人的。

4、要有炸弹。

5、我的坦克要能按键发射子弹,敌人的坦克要能连续自动发射子弹。

6、我的子弹打到敌人时子弹要消失,同时敌人爆炸并消失,不能再发子弹。

以上是游戏设计的简单思路,这是初步设计,接下来以代码来分析详细的设计过程:

步骤一:

组织代码,为了代码易读,而且我使用的是html5+js来实现,自不必多说,使用tankGame.js+tankGame.html来组织我的代码,js用于类以及方法的实现过程,html实现函数调用以及网页的显示。

步骤二:设计作战区域:

code 1 from tankeGame.html

//得到画布

varcanvas1=document.getElementById("tankMap");

//得到绘图上下文(你可以理解是画笔)

varcxt=canvas1.getContext("2d");

步骤三:画坦克,包括自己的和敌人的:

//基类,里面有基本的共有属性和方法

functionTank(x,y,direct,color){

this.x=x;

this.y=y;

this.speed=1;

this.isLive=true;

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和EnemyTanke继承自基类。注意继承的方法。

//定义一个Hero类

//x表示坦克的横坐标,y表示纵坐标,direct方向

functionHero(x,y,direct,color){

//继承的方法和格式,tank其实就是一个对象

this.tank=Tank;

this.tank(x,y,direct,color);

//增加一个私有函数,射击敌人坦克.

this.shotEnemy=function(){

//创建子弹,子弹的位置应该和hero有关系,并且和hero的方向有关

switch(this.direct){

case0:

heroBullet=newBullet(this.x+9,this.y,this.direct,3,"hero",this);

break;

case1:

heroBullet=newBullet(this.x+30,this.y+9,this.direct,3,"hero",this);

break;

case2:

heroBullet=newBullet(this.x+9,this.y+30,this.direct,3,"hero",this);

break;

case3://右

heroBullet=newBullet(this.x,this.y+9,this.direct,3,"hero",this);

break;

}

//把这个子弹对象放入到数组中->push函数

heroBullets.push(heroBullet);

//定时器.

vartimer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);

//把这个timer赋给这个子弹(js对象是引用传递!)

heroBullets[heroBullets.length-1].timer=timer;

}

//定义一个EnemyTank类

functionEnemyTank(x,y,direct,color){

//继承Tank

this.tank=Tank;

this.count=0;

this.bulletIsLive=true;

this.tank(x,y,direct,color);

this.qetBullet=null;

this.run=functionrun(){

//判断敌人的坦克当前方向

switch(this.direct){

case0:

if(this.y>0){

this.y-=this.speed;

}

break;

case1:

if(this.x+30<400){

this.x+=this.speed;

}

break;

case2:

if(this.y+30<300){

this.y+=this.speed;

}

break;

case3:

if(this.x>0){

this.x-=this.speed;

}

break;

}

//改变方向,走50次,再改变方向

if(this.count>50){

this.direct=Math.round(Math.random()*3);//随机生成0,1,2,3

this.count=0;

}

this.count++;

//判断敌人坦克是否还活着

//if(this.tank.isLive==true){

//判断子弹是否已经死亡,如果死亡,则增加新的一颗子弹

if(this.bulletIsLive==false){

//增子弹,这是需要考虑当前这个敌人坦克的方向,在增加子弹

switch(this.direct){

case0:

qetBullet=newBullet(this.x+9,this.y,this.direct,3,"enemy",this);

break;

case1:

qetBullet=newBullet(this.x+30,this.y+9,this.direct,3,"enemy",this);

break;

case2:

qetBullet=newBullet(this.x+9,this.y+30,this.direct,3,"enemy",this);

break;

case3://右

qetBullet=newBullet(this.x,this.y+9,this.direct,3,"enemy",this);

break;

}

//把子弹添加到敌人子弹数组中

enemyBullets.push(qetBullet);

//启动新子弹run

varmytimer=window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);

enemyBullets[enemyBullets.length-1].timer=mytimer;

this.bulletIsLive=true;

}

}

//绘制坦克(敌人坦克和自己的坦克)

functiondrawTank(tank){

//说明所有的坦克都要isLive这个属性

if(tank.isLive){

//考虑方向

switch(tank.direct){

case0://上

case2://下

//画出自己的坦克,使用前面的绘图技术

//设置颜色

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,360,true);

cxt.fill();

//画出炮筒(直线)

cxt.strokeStyle=tank.color[1];

//设置线条的宽度

cxt.lineWidth=1.5;

cxt.beginPath();

cxt.moveTo(tank.x+10,tank.y+15);

if(tank.direct==0){

cxt.lineTo(tank.x+10,tank.y);

}elseif(tank.direct==2){

cxt.lineTo(tank.x+10,tank.y+30);

}

cxt.closePath();

cxt.stroke();

break;

case1://右和左

case3:

//画出自己的坦克,使用前面的绘图技术

//设置颜色

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.arc(tank.x+15,tank.y+10,4,0,360,true);

cxt.fill();

//画出炮筒(直线)

cxt.strokeStyle=tank.color[1];

//设置线条的宽度

cxt.lineWidth=1.5;

cxt.beginPath();

cxt.moveTo(tank.x+15,tank.y+10);

//向右

if(tank.direct==1){

cxt.lineTo(tank.x+30,tank.y+10);

}elseif(tank.direct==3){//向左

cxt.lineTo(tank.x,tank.y+10);

}

cxt.closePath();

cxt.stroke();

break;

}

}

}

步骤四:画子弹:

type表示:这颗子弹是敌人的,还是自己的

//tank表示对象,说明这颗子弹,属于哪个坦克.

functionBullet(x,y,direct,speed,type,tank){

this.x=x;

this.y=y;

this.direct=direct;

this.speed=speed;

this.timer=null;

this.isLive=true;

this.type=type;

this.tank=tank;

this.run=functionrun(){

//在该表这个子弹的坐标时,我们先判断子弹是否已经到边界

//子弹不前进,有两个逻辑,1.碰到边界,2.碰到敌人坦克.

if(this.x<=0||this.x>=500||this.y<=0||this.y>=500||this.isLive==false){

//子弹要停止.

window.clearInterval(this.timer);

//子弹死亡

this.isLive=false;

if(this.type=="enemy"){

this.tank.bulletIsLive=false;

}

}else{

//坐标的移动代表子弹位置变化

switch(this.direct){

case0:

this.y-=this.speed;

break;

case1:

this.x+=this.speed;

break;

case2:

this.y+=this.speed;

break;

case3:

this.x-=this.speed;

break;

}

}

}

}

//Bullet只是一个类,并没有画坦克的方法,需要我们自己设计,draw一个

//画出自己的子弹

functiondrawHeroBullet(){

//现在要画出所有子弹

for(vari=0;i

varheroBullet=heroBullets[i];

if(heroBullet!=null&&heroBullet.isLive){

cxt.fillStyle="#FEF26E";

cxt.fillRect(heroBullet.x,heroBullet.y,2,2);

}

}

}

//这里我们还需要添加一个函数,用于画出敌人的子弹

functiondrawEnemyBullet(){

//检查坦克是否还活着

for(varj=0;j

varenemyTank=enemyTanks[j];

if(enemyTank.isLive==true){

for(vari=0;i

varetBullet=enemyBullets[i];

if(etBullet!=null&&etBullet.isLive){

cxt.fillStyle="#00FEFE";

cxt.fillRect(etBullet.x,etBullet.y,2,2);

}

}

}

}

}

步骤五:检测判断自己的坦克是否击中敌人坦克。

//编写一个函数,专门用于判断我的子弹,是否击中了某个敌人坦克

functionisHitEnemyTank(){

//取出子弹

for(vari=0;i

//取出一颗子弹

varheroBullet=heroBullets[i];

if(heroBullet.isLive){//子弹是活的,才去判断

//让这颗子弹去和遍历每个敌人坦克判断

for(varj=0;j

varenemyTank=enemyTanks[j];

if(enemyTank.isLive){

//(看看这颗子弹,是否进入坦克所在矩形)

//根据当时敌人坦克的方向来决定

switch(enemyTank.direct){

case0://敌人坦克向上

case2://敌人坦克向下

if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+20

&&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+30){

//把坦克isLive设为false,表示死亡

enemyTank.isLive=false;

//该子弹也死亡

heroBullet.isLive=false;

//创建一颗炸弹

varbomb=newBomb(enemyTank.x,enemyTank.y);

//然后把该炸弹放入到bombs数组中

bombs.push(bomb);

}

break;

case1://敌人坦克向右

case3://敌人坦克向左

if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+30

&&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+20){

//把坦克isLive设为false,表示死亡

enemyTank.isLive=false;

heroBullet.isLive=false;

//创建一颗炸弹

varbomb=newBomb(enemyTank.x,enemyTank.y);

//然后把该炸弹放入到bombs数组中

bombs.push(bomb);

}

break;

}

}

}//for

}

}

步骤六:设计爆炸效果

//定义一个炸弹类

functionBomb(x,y){

this.x=x;

this.y=y;

this.isLive=true;//炸弹是否活的,默认true;

//炸弹有一个生命值

this.blood=9;

//减生命值

this.bloodDown=function(){

if(this.blood>0){

this.blood--;

}else{

//说明炸弹死亡

this.isLive=false;

}

}

}

//画出敌人炸弹

functiondrawEnemyBomb(){

for(vari=0;i

//取出一颗炸弹

varbomb=bombs[i];

if(bomb.isLive){

//更据当前这个炸弹的生命值,来画出不同的炸弹图片

if(bomb.blood>6){//显示最大炸弹图

varimg1=newImage();

img1.src="picture/bomb_1.gif";

varx=bomb.x;

vary=bomb.y;

img1.οnlοad=function(){

cxt.drawImage(img1,x,y,30,30);

}

}elseif(bomb.blood>3){

varimg2=newImage();

img2.src="picture/bomb_2.gif";

varx=bomb.x;

vary=bomb.y;

img2.οnlοad=function(){

cxt.drawImage(img2,x,y,30,30);

}

}else{

varimg3=newImage();

img3.src="picture/bomb_3.gif";

varx=bomb.x;

vary=bomb.y;

img3.οnlοad=function(){

cxt.drawImage(img3,x,y,30,30);

}

}

//减血

bomb.bloodDown();

if(bomb.blood<=0){

//怎么办?把这个炸弹从数组中去掉

bombs.splice(i,1);

}

}

}

}

步骤七:响应键盘事件

functiongetCommand(){

//我怎么知道,玩家按下的是什么键

//说明当按下键后事件--->event对象----->事件处理函数()

varcode=event.keyCode;//对应字母的ascii码->我们看码表

switch(code){

case87://上

hero.moveUp();

break;

case68:

hero.moveRight();

break;

case83:

hero.moveDown();

break;

case65:

hero.moveLeft();

break;

case74:

hero.shotEnemy();

break;

}

步骤八:页面刷新:

//专门写一个函数,用于定时刷新我们的作战区,把要在作战区出现的元素(自己坦克,敌人坦克,子弹,炸弹,

//障碍物...)->游戏思想

functionflashTankMap(){

//把画布清理

cxt.clearRect(0,0,500,500);

//我的坦克

drawTank(hero);

//画出自己的子弹

//子弹飞效果是怎么出现的?[答:首先我们应该每隔一定时间(setInterval)就去刷新作战区,如果在刷新的时候,子弹坐标变换了,给人的感觉就是子弹在飞!]

drawHeroBullet();

//敌人的坦克

//判断一下敌人坦克是否击中

isHitEnemyTank();

drawEnemyBomb();

drawEnemyBullet();

//画出所有敌人坦克

for(vari=0;i<3;i++){

drawTank(enemyTanks[i]);

}

}

总结:坦克大战小游戏虽小但是涉及到的内容和思想却不少,在学习编程的过程中慢慢的体会编程思想非常重要。在此非常感谢韩顺平老师的视频!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。