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

HTML5+JavaScript制作坦克大战游戏——学习笔记二

2016-03-14 17:04 696 查看
1.在JavaScript通过对象冒充来实现集成。

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>对象冒充练习</title>
</head>
<body>
<script type="text/javascript">
function Animal(name,age){
this.name=name;
this.age=age;
this.hair=function haircolor(){
alert("white");
}
}
function Dog(name,age){
//把Animal构造函数赋给this.dg
this.dg=Animal;
//调用
this.dg(name,age);
}
var dog=new Dog("拉布拉多",1);
alert(dog.name);
dog.hair();       //调用Animal中的方法
</script>
</body>
</html>

2.画出敌人的坦克,通过代码整合

实现敌人的坦克颜色跟用户的不一样;用户移动位置敌人的坦克不会消失等功能。

示例代码:(TankBattle.js)

//用数组的方式定义坦克上面两种不同的颜色
var myColor=new Array("#DED284","#FFFA7E");
var enemyColor=new Array("#00A2B5","#00FEFE");

//x表示坦克的横坐标,y表示坦克的纵坐标,dirc表示移动方向
function Tank(x,y,direc,color){
this.x=x;
this.y=y;
this.speed=1;
this.direc=direc;
this.color=color;
//向上移动
this.moveUp=function(){
this.y-=this.speed;
this.direc=0
}
//向右移动
this.moveRight=function(){
this.x+=this.speed;
this.direc=1;
}
//向下移动
this.moveDown=function(){
this.y+=this.speed;
[b]this.direc=2;
}
//向左移动
this.moveLeft=function(){
this.x-=this.speed;
this.direc=3;
}
}
function MyTank(x,y,direc,color){
//下面两句话实现对象冒充效果
this.tank=Tank;
this.tank(x,y,direc,color);

}
//敌人的坦克也是通过对象冒充继承Tank类
function EnemyTank(x,y,direc,color){
this.tank=Tank;
this.tank(x,y,direc,color);
}
//      画坦克
function drawTank(tank){
//考虑方向
switch (tank.direc){
case 0:
case 2:

ctx.fillStyle=tank.color[0];   //给定矩形的颜色
ctx.fillRect(tank.x,tank.y,5,30);        //画出左边的矩形
ctx.fillRect(tank.x+15,tank.y,5,30);       //画出右侧的矩形
//画出中间的矩形(中间的矩形宽高为10*20,为了让中间的矩形和两侧的矩形之间有空隙,将左右两边都空出一个像素,所以x轴的位置
// 向右移动了一个像素,左边就空出1px,宽度减少了2px,这样右边就又空出了1px)

ctx.fillRect(tank.x+6,tank.y+5,8,20);
ctx.fillStyle=tank.color[1];       //圆的填充颜色
ctx.arc(tank.x+10,tank.y+15,4,0,360);  //画出坦克的盖(30+10=30+5+1+8/2)(30+15=30+5+20/2)
ctx.fill();      //填充圆
//      画出炮筒的线条
ctx.beginPath();
ctx.moveTo(tank.x+10,tank.y+15);       //线条的起始位置为圆心的位置
if(tank.direc==0){
ctx.lineTo(tank.x+10,tank.y);         //线条的结束位置
}else if(tank.direc==2){
ctx.lineTo(tank.x+10,tank.y+30);
}

ctx.strokeStyle=tank.color[1];
ctx.lineWidth=2;       //设置线条的宽度(粗细)
ctx.closePath();
ctx.stroke();
break;
case 1:   //右
case 3:    //左
//      画出自己的坦克
ctx.fillStyle=tank.color[0];   //给定矩形的颜色
ctx.fillRect(tank.x,tank.y,30,5);       //画出左边的矩形

ctx.fillRect(tank.x,tank.y+15,30,5);       //画出右侧的矩形
//画出中间的矩形(中间的矩形宽高为10*20,为了让中间的矩形和两侧的矩形之间有空隙,将左右两边都空出一个像素,所以x轴的位置
// 向右移动了一个像素,左边就空出1px,宽度减少了2px,这样右边就又空出了1px)

ctx.fillRect(tank.x+5,tank.y+6,20,8);
ctx.fillStyle=tank.color[1];       //圆的填充颜色
ctx.arc(tank.x+15,tank.y+10,4,0,360); //画出坦克的盖(30+10=30+5+1+8/2)(30+15=30+5+20/2)
ctx.fill();      //填充圆
//      画出炮筒的线条
ctx.beginPath();
ctx.moveTo(tank.x+15,tank.y+10);
//向右
if(tank.direc==1){
ctx.lineTo(tank.x+30,tank.y+10);
}else if(tank.direc==3){ //向左
ctx.lineTo(tank.x,tank.y+10);
}
ctx.strokeStyle=tank.color[1];
ctx.lineWidth=2;       //设置线条的宽度(粗细)
ctx.closePath();
ctx.stroke();
break;
}

}

HTML5代码(TankBattle.html)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>坦克大战游戏</title>
</head>
<body onkeydown="getCommand();">
<h1>坦克大战练习 </h1>
<canvas id="tankBg" width="400px" height="400px" style="background-color: black;"></canvas>
<!--把js文件引入-->
<script type="text/javascript" src="js/TankBattle.js"></script>
<script type="text/javascript">

var canvas=document.getElementById("tankBg");    //得到画布
var ctx=canvas.getContext("2d");    //得到上下文,相当于画笔

//定义用户自己的坦克
var myTank=new MyTank(130,130,0,myColor);  //用0,1,2,3,4分别表示上、右、下、左,此处的0位向上

//定义敌人的坦克,考虑到敌人可能有很多,考虑用数组定义
var enemyTanks=new Array();
//先按照3个敌人来处理,之后再替换成变量
for(var i=0;i<3;i++){
//创建一个敌人的坦克
var enemyTank=new EnemyTank((i+1)*50,0,2,enemyColor);        //0表示纵坐标,2表示炮筒方向朝下
//把这个坦克放入数组
enemyTanks[i]=enemyTank;
}

//游戏一加载,我们就做一次刷新并画出内容的操作
refreshTankCanvas();

//刷新作战区域(里面包括画自己的坦克、敌人的坦克、子弹、炸弹、障碍物等一系列相关的内容)
function refreshTankCanvas(){
//注意是ctx,而不是cxt,千万别写错了
ctx.clearRect(0,0,400,400);     //清空画布,这一步是不能少的
drawTank(myTank);      //画布清空后重新绘制坦克的位置
for(var i=0;i<3;i++){
drawTank(enemyTanks[i]);      //调用drawTank画坦克的方法,画出enemyTanks[i]这个数组里的坦克
}

}

//接受用户的键盘输入
function  getCommand(){
var code=event.keyCode;    //通过event.KeyCode来判断键盘的ASCII值

switch (code){
case 87:    //W键
myTank.moveUp();
break;
case 68:   //D键
myTank.moveRight();
break;
case 83:    //S键
myTank.moveDown();
break;
case 65:     //A键
myTank.moveLeft();
break;
}
refreshTankCanvas();    //获取到键盘的命令之后,再刷新一次战场
}

</script>
</body>
</html>

运行效果:



3.对象是引用传递,非面向对象的是值传递

4. 1)在上面版本的基础上实现发子弹

   2)子弹不会飞出画布

  3)子弹到达画布之后就不再再边缘处画子弹了

示例代码: (TankBattle.html)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>坦克大战游戏</title>
</head>
<body onkeydown="getCommand();">
<h1>坦克大战练习 </h1>
<canvas id="tankBg" width="400px" height="400px" style="background-color: black;"></canvas>
<!--把js文件引入-->
<script type="text/javascript" src="js/TankBattle.js"></script>
<script type="text/javascript">

var canvas=document.getElementById("tankBg");    //得到画布
var ctx=canvas.getContext("2d");    //得到上下文,相当于画笔

//定义用户自己的坦克
var myTank=new MyTank(130,130,0,myColor);  //用0,1,2,3,4分别表示上、右、下、左,此处的0位向上
var myBullet=null;           //先定义一颗空子弹

//定义敌人的坦克,考虑到敌人可能有很多,考虑用数组定义
var enemyTanks=new Array();
//先按照3个敌人来处理,之后再替换成变量
for(var i=0;i<3;i++){
//创建一个敌人的坦克
var enemyTank=new EnemyTank((i+1)*50,0,2,enemyColor);        //0表示纵坐标,2表示炮筒方向朝下
//把这个坦克放入数组
enemyTanks[i]=enemyTank;
}

//游戏一加载,我们就做一次刷新并画出内容的操作
refreshTankCanvas();

//刷新作战区域(里面包括画自己的坦克、敌人的坦克、子弹、炸弹、障碍物等一系列相关的内容)
function refreshTankCanvas(){
//注意是ctx,而不是cxt,千万别写错了
ctx.clearRect(0,0,400,400);     //清空画布,这一步是不能少的
drawTank(myTank);      //画布清空后重新绘制坦克的位置
drawMyBullet();        //画出用户自己的子弹

//画出所有敌人的子弹
for(var i=0;i<3;i++){
drawTank(enemyTanks[i]);      //调用drawTank画坦克的方法,画出enemyTanks[i]这个数组里的坦克
}

}

//接受用户的键盘输入,通过键盘上的W、D、S、A键来控制坦克的上右下左的移动,J键控制发子弹
function  getCommand(){
var code=event.keyCode;    //通过event.KeyCode来判断键盘的ASCII值

switch (code){
case 87:    //W键
myTank.moveUp();
break;
case 68:   //D键
myTank.moveRight();
break;
case 83:    //S键
myTank.moveDown();
break;
case 65:     //A键
myTank.moveLeft();
break;
case 74:     //J键
myTank.shotEnemy();
break;
}
refreshTankCanvas();    //获取到键盘的命令之后,再刷新一次战场
//          setInterval()方法的作用就是每间隔一段时间,调用某段代码
//此处的100ms是根据老师多次测试的结果直接拿来使用的,不是随便写上去的
window.setInterval("refreshTankCanvas()",100);       //每隔100ms,调用一次refreshTankCanvas方法

}

</script>
</body>
</html>

TankBattle.js

//用数组的方式定义坦克上面两种不同的颜色
var myColor=new Array("#DED284","#FFFA7E");
var enemyColor=new Array("#00A2B5","#00FEFE");
//定义子弹类
function Bullet(x,y,direc,speed){
this.x=x;
this.y=y;
this.direc=direc;
this.speed=speed;
this.timer=null;
this.isLive=true;     //子弹刚刚创建的时候,它是活的
//定义一个让子弹飞的方法
this.bulletFly= function(){
//这行代码的意思是:如果子弹飞出画布canvas的边界了,我们就要clear timer 了
if(this.x<=0||this.x>=400||this.y<=0||this.y>=400){
window.clearInterval(this.timer);   //子弹停止
this.isLive=false;
}else {
switch (this.direc){
case 0:   //子弹方向朝上的时候
this.y-=this.speed;    //子弹不断朝上,y坐标不断--
break;
case 1:
this.x+=this.speed;
break;
case 2:
this.y+=this.speed;
break;
case 3:
this.x-=this.speed;
break;
}
}

}

}
//x表示坦克的横坐标,y表示坦克的纵坐标,dirc表示移动方向
function Tank(x,y,direc,color){
this.x=x;
this.y=y;
this.speed=1;
this.direc=direc;
this.color=color;
//向上移动
this.moveUp=function(){
this.y-=this.speed;
this.direc=0
}
//向右移动
this.moveRight=function(){
this.x+=this.speed;
this.direc=1;
}
//向下移动
this.moveDown=function(){
this.y+=this.speed;
this.direc=2;
}
//向左移动
this.moveLeft=function(){
this.x-=this.speed;
this.direc=3;
}
}
function MyTank(x,y,direc,color){
//下面两句话实现对象冒充效果
this.tank=Tank;
this.tank(x,y,direc,color);
//添加一个射击敌人的方法(射击这个行为是坦克的行为,所以放在这个函数里面)
this.shotEnemy=function(){
//这里用坦克的方向来switch,因为this下hi先弄个当前的坦克,而子弹的方向是跟坦克的方向保持一致的
switch (this.direc){
case 0:
//创建一颗子弹
myBullet=new Bullet(this.x+9,this.y,this.direc,1);   //此处的1代表的是Bullet类中的speed参数
break;
case 1:   //向右
myBullet=new Bullet(this.x+30,this.y+9,this.direc,1);   //在方向direc处不要漏写了this
break;
case 2:
//之所以+9,是因为子弹给了2px的大小,如果+10,子弹就会相对于炮筒稍稍有点跑偏了
myBullet=new Bullet(this.x+9,this.y+30,this.direc,1);
break;
case 3:    //向左
myBullet=new Bullet(this.x,this.y+9,this.direc,1);
break;
}
//每隔50ms,调用myBullet对象的bulletFly()方法
var timer= window.setInterval("myBullet.bulletFly()",50);   //此处的50ms是根据老师多次试验得来的结果直接拿来用的
myBullet.timer=timer;
}

}
//敌人的坦克也是通过对象冒充继承Tank类
function EnemyTank(x,y,direc,color){
this.tank=Tank;
this.tank(x,y,direc,color);
}
//画出当前用户的子弹
function drawMyBullet(){
//如果这个子弹的timer还没有被清空,也就是这个子弹isLive=ture(默认就为true)是活的,就执行画自带的操作
if(myBullet!=null&&myBullet.isLive){    //如果子弹不为空,也就是Bullet这个类创建了,就画出子弹
ctx.fillStyle="#FFFA7E";
ctx.fillRect(myBullet.x,myBullet.y,2,2);
}

}

//      画坦克
function drawTank(tank){
//考虑方向
switch (tank.direc){
case 0:
case 2:

ctx.fillStyle=tank.color[0];   //给定矩形的颜色
ctx.fillRect(tank.x,tank.y,5,30);        //画出左边的矩形
ctx.fillRect(tank.x+15,tank.y,5,30);       //画出右侧的矩形
//画出中间的矩形(中间的矩形宽高为10*20,为了让中间的矩形和两侧的矩形之间有空隙,将左右两边都空出一个像素,所以x轴的位置
// 向右移动了一个像素,左边就空出1px,宽度减少了2px,这样右边就又空出了1px)

ctx.fillRect(tank.x+6,tank.y+5,8,20);
ctx.fillStyle=tank.color[1];       //圆的填充颜色
ctx.arc(tank.x+10,tank.y+15,4,0,360);  //画出坦克的盖(30+10=30+5+1+8/2)(30+15=30+5+20/2)
ctx.fill();      //填充圆
//      画出炮筒的线条
ctx.beginPath();
ctx.moveTo(tank.x+10,tank.y+15);       //线条的起始位置为圆心的位置
if(tank.direc==0){
ctx.lineTo(tank.x+10,tank.y);         //线条的结束位置
}else if(tank.direc==2){
ctx.lineTo(tank.x+10,tank.y+30);
}

ctx.strokeStyle=tank.color[1];
ctx.lineWidth=2;       //设置线条的宽度(粗细)
ctx.closePath();
ctx.stroke();
break;
case 1:   //右
case 3:    //左
//      画出自己的坦克
ctx.fillStyle=tank.color[0];   //给定矩形的颜色
ctx.fillRect(tank.x,tank.y,30,5);       //画出左边的矩形

ctx.fillRect(tank.x,tank.y+15,30,5);       //画出右侧的矩形
//画出中间的矩形(中间的矩形宽高为10*20,为了让中间的矩形和两侧的矩形之间有空隙,将左右两边都空出一个像素,所以x轴的位置
// 向右移动了一个像素,左边就空出1px,宽度减少了2px,这样右边就又空出了1px)

ctx.fillRect(tank.x+5,tank.y+6,20,8);
ctx.fillStyle=tank.color[1];       //圆的填充颜色
ctx.arc(tank.x+15,tank.y+10,4,0,360); //画出坦克的盖(30+10=30+5+1+8/2)(30+15=30+5+20/2)
ctx.fill();      //填充圆
//      画出炮筒的线条
ctx.beginPath();
ctx.moveTo(tank.x+15,tank.y+10);
//向右
if(tank.direc==1){
ctx.lineTo(tank.x+30,tank.y+10);
}else if(tank.direc==3){ //向左
ctx.lineTo(tank.x,tank.y+10);
}
ctx.strokeStyle=tank.color[1];
ctx.lineWidth=2;       //设置线条的宽度(粗细)
ctx.closePath();
ctx.stroke();
break;
}

}

运行效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息