js代码:
//定义颜色的全局变量
var heroColors = new Array("#BA9658", "#FEF26E");
var enemyColors = new Array("#00A2B5", "#00FEFE");
//其他的坦克,这里的拓展性还可以
//子弹类
function Bullet(x, y, direct) {
this.x = x;
this.y = y;
this.speed = 1;
this.direct = direct;
this.timer = null;
this.live = true;
this.run = function run() {
//先判断子弹是否已经到边界
if (this.x <= 0 || this.x >= 400 || this.y <= 0 || this.y >= 300) {
//子弹停止
window.clearInterval(this.timer);
this.live = 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;
}
}
document.getElementById("tankMap").innerText = "子弹x=" + this.x + "子弹=y" + this.y;
}
}
function Tank(x, y, direct, color) {
this.x = x;
this.y = y;
this.speed = 8;
this.direct = direct;
this.color = color;
//up
this.moveUp = function () {
if (2 != this.direct) {
if (this.y - this.speed < 0)
this.y = 0;
else
this.y -= this.speed;
}
this.direct = 0;
}
//right
this.moveRight = function () {
if (3 != this.direct) {
if (this.x + this.speed > 400 - 30)
this.x = 400 - 30;
else
this.x += this.speed;
}
this.direct = 1;
}
//down
this.moveDown = function () {
if (0 != this.direct) {
if (this.y + this.speed >= 300 - 30)
this.y = 300 - 30;
else
this.y += this.speed;
}
this.direct = 2;
}
//left
this.moveLeft = function () {
if (1 != this.direct) {
if (this.x - this.speed < 0)
this.x = 0;
else
this.x -= this.speed;
}
this.direct = 3;
}
}
//画出自己的子弹,你也尅一把该函数封装到HeroTank类中
function drawHeroBullet() {
//要画出所有子弹
for (var i = 0; i < heroBullets.length; i++) {
var heroBullet = heroBullets[i];
if (null != heroBullet && true == heroBullet.live) {
cxt.fillStyle = "#FEF26E";
cxt.fillRect(heroBullet.x, heroBullet.y, 2, 2);
}
}
}
//把绘制坦克封装成一个函数,将来可以作为成员函数
function drawTank(tank) {
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.beginPath();
cxt.fillStyle = tank.color[1];
cxt.arc(tank.x + 10, tank.y + 15, 4, -30, 360, true);
cxt.closePath();
cxt.fill();
//画出炮筒
cxt.strokeStyle = tank.color[1];
cxt.lineWidth = 1.5;
cxt.moveTo(tank.x + 10, tank.y + 15);
if (0 == tank.direct)
cxt.lineTo(tank.x + 10, tank.y);
else if (2 == tank.direct)
cxt.lineTo(tank.x + 10, tank.y + 30);
cxt.stroke();
break
case 1:
case 3:
//画出自己的坦克,使用前面的绘图技术
//设置颜色
cxt.fillStyle = "#BA9658";
//使用先死--》后活(初学者最好使用这个方法)
//先画出矩形
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.beginPath();
cxt.fillStyle = "#FEF26E";
cxt.arc(tank.x + 15, tank.y + 10, 4, -30, 360, true);
cxt.closePath();
cxt.fill();
//画出炮筒
cxt.strokeStyle = "#FEF26E";
cxt.lineWidth = 1.5;
cxt.moveTo(tank.x + 15, tank.y + 10);
if (1 == tank.direct)
cxt.lineTo(tank.x + 30, tank.y + 10);
else if (3 == tank.direct)
cxt.lineTo(tank.x, tank.y + 10);
cxt.stroke();
break
}
}
//定义一个hero类
//x:横坐标 y:纵坐标
function HeroTank(x, y, direct, color) {
//下面两句话的作用是:通过对象冒充达到继承的效果
this.tank = Tank;
this.tank(x, y, direct, color);
//增加一个函数射击敌人坦克
this.shotEnemy = function () {
//创建子弹,子弹的位置应该和坦克的方向有关,并且与坦克的方向是一致的
//this.x就是当前hero的横坐标
switch (this.direct) {
case 0:
//alert("0");
heroBullet = new Bullet(this.x + 9, this.y, this.direct);
break;
case 1:
//alert("1");
heroBullet = new Bullet(this.x + 30, this.y + 9, this.direct);
break;
case 2:
//alert("2");
heroBullet = new Bullet(this.x + 9, this.y + 30, this.direct);
break;
case 3:
//alert("3");
heroBullet = new Bullet(this.x, this.y + 9, this.direct);
break
}
//把这个子弹放入到数组中-->push函数
heroBullets.push(heroBullet);
//调用我们的子弹run
//这里有一个技术难度比较大:如果按下面的方法,则所有的子弹共享一个定时器
//var timer = window.setInterval("heroBullet.run()", 50);
//heroBullet.timer = timer;
//按这个方法,所有的子弹都有独立的定时器
var timer = window.setInterval("heroBullets[" + (heroBullets.length - 1) + "].run()", 50);
heroBullets[heroBullets.length - 1].timer = timer;
}
}
//定义一个敌人的坦克
function EnemyTank(x, y, direct, color) {
this.tank = Tank;
this.tank(x, y, direct, color);
}
html代码:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8"/>
<title></title>
</head>
<body οnkeydοwn="getCommand()">
<h1>html5-经典的坦克大战</h1>
<canvas id ="tankMap" width="400px" height="300px"
style="background-color:black">
</canvas>
<!--把tankGams.js引入到本页面-->
<script type="text/javascript" src="..\\js\\tankGame3.js"></script>
<script type="text/javascript">
var canvas1 = document.getElementById("tankMap");
var cxt = canvas1.getContext("2d");
//我的坦克hero
var hero = new HeroTank(40, 40, 0, heroColors);
//定义个子弹数组
var heroBullets = new Array();
//定义敌人的坦克(敌人的坦克有多少?思路:是单个单个的定义,还是放在数组中)
var enemyTanks = new Array();
//先死后活,定义3个,后面我们打敌人坦克的数量,做出变量
for (var i = 0; i < 3; i++)
{
//创建一个坦克
var enemyTank = new EnemyTank((i + 1) * 50, 0, 2, enemyColors);
//把坦克放进数组中
enemyTanks[i] = enemyTank;
}
//打开页面先刷新一次
flashTankMap();
//专门写一个函数,用于定时刷新我们的作战区,把要在作战区出现的元素(自己的坦克、
//敌人的坦克、子弹、炸弹,障碍物)
function flashTankMap() {
cxt.clearRect(0, 0, 400, 300);
//我的坦克
drawTank(hero);
//画出自己的子弹
//子弹飞效果是怎么出现的:首先我们应该每隔一定时间就去刷新作战区,如果在书信的时候,子弹坐标
//变换了,给人的感觉就是子弹在飞
drawHeroBullet();
//敌人所有的坦克
for (var i = 0; i < 3; i++) {
drawTank(enemyTanks[i]);
}
}
//这是一个接收用户按键的函数
function getCommand() {
var code = event.keyCode;
switch (code) {
case 87://up
hero.moveUp();
break;
case 68://right
hero.moveRight();
break;
case 83://down
hero.moveDown();
break;
case 65://left
hero.moveLeft();
break;
case 74://Bullet
hero.shotEnemy();
break;
}
//出发这个函数flashTankMap();
flashTankMap();
//重新绘制所有的敌人的坦克,你可以在这里写代码()
}
//每隔100毫秒去刷新一次作战区
window.setInterval("flashTankMap()", 100);
</script>
</body>
</html>