目录

1、项目背景

2、项目展示

3、设计思路

3.1、坦克移动

3.2、坦克开火

3.3、击中坦克

4、实现代码

5、总结


1、项目背景

2021年春节期间在家无聊,正好又学过一些前端的知识,因此就捣鼓了一款基于html5的小游戏——《坦克大战》。这款小游戏是参照了一个“移动的女孩”的demo(如下图)可以通过方向键移动女孩。

demo代码: https://gitee.com/wulinchun/front-end/tree/master/    html移动的女孩

2、项目展示

绿色坦克为玩家坦克,方向键控制玩家坦克移动,空格发射子弹。如果被击中就会在左上角重生。

黄色坦克为敌方坦克,会随机出现在画布中,会自己移动+发射子弹。如果被击中就会在随机位置重生。

3、设计思路

3.1、坦克移动

坦克移动就是根据坐标x,y在canvas画布相应位置上画出坦克。坦克一共有四个坐标(x,y,imageX,imageY),坦克设计的图片如下所示:包括上下左右四个方向为一张坦克设计图。(x,y)对应的是一整张坦克图片在canvas画布中的坐标位置。而(imageX,imageY)对应的是在一整张包含上下左右四个方向的坦克设计图中,选取哪块图片。简单来说(x,y)控制出现的位置,(imageX,imageY)控制呈现的方向。

3.1.1、玩家坦克

玩家坦克的移动是用了js的键盘事件+setInterval方法。使用setInterval方法每隔指定时间会在画布上绘制坦克的最新位置。然后再将之前的位置清除掉。就是将坦克图像一帧一帧地绘制在画布上。

3.1.2、敌方坦克

敌方坦克的移动原理和玩家坦克的移动原理一样,只不过将玩家坦克通过键盘控制坦克移动变成了由随机数确立一个move数组,在这个move数组中会存放坦克移动信息,然后直接读取这个数组获取坦克该怎么移动就行了

3.2、坦克开火

首先,子弹飞行的原理和坦克移动的原理一样,都是使用了setInterval方法一帧一帧的绘制在画布上,然后根据坦克的炮口方向不同,子弹飞行也有不同的方向。因此子弹也有四个坐标(x,y,imageX,imageY)

3.3、击中坦克

如何确定子弹是否击中了坦克?通过比较子弹飞行时的坐标与每辆坦克的坐标,来确定子弹是否击中了坦克,如果击中坦克,就会触发一个“bomb!!!”的效果。我这里做掉比较简陋,就是放一张爆炸效果图,把这张效果图的坐标设置成被击中坦克的坐标就行了。然后被击中的坦克会在其他地方复活(通过改变坦克坐标x,y实现)

4、实现代码

代码下载地址:https://gitee.com/wulinchun/front-end/tree/master/      使用jquery—Canvas实现html5小游戏——《坦克大战》

tank.js

$(document).ready(function() {
// canvas
var canvas = document.getElementById('demo');
var ctx = canvas.getContext('2d'); //画布上的绘图环境为“2D” //绘制Canvas画布大小
function drawCanvas() {
canvas.width = 1400;
canvas.height = 700;
}
//判断玩家坦克目前的方向
var directUp = 1; //初始状态为"Up"
var directDown = 0;
var directLeft = 0;
var directRight = 0; //判断敌方坦克目前的方向(有两辆敌方坦克,所以是一个数组)
var enemydirectUp = [1, 1]; //初始状态为"Up"
var enemydirectDown = [0, 0];
var enemydirectLeft = [0, 0];
var enemydirectRight = [0, 0]; //玩家坦克信息
var playerImage = new Image();
playerImage.src = 'img/tank.png';
var player = {
x: 0, // 在canvas中的坐标
y: 0,
imageX: 150, // 图像定位坐标
imageY: 0,
width: 120, // 图像显示区域大小
height: 100,
stop: true // 是否停止
}; //敌方坦克信息
var enemyImage = new Image();
enemyImage.src = 'img/enemy.png';
var enemy = [{
x: Math.round(Math.random() * 1300), // 在canvas中的坐标(随机)
y: Math.round(Math.random() * 600),
imageX: 150, // 图像定位坐标
imageY: 0,
width: 120, // 图像显示区域大小
height: 100,
stop: true // 是否停止
},
{
x: Math.round(Math.random() * 1400), // 在canvas中的坐标(随机)
y: Math.round(Math.random() * 700),
imageX: 150, // 图像定位坐标
imageY: 0,
width: 120, // 图像显示区域大小
height: 100,
stop: true // 是否停止
}
]; //击中的爆炸效果信息(三辆坦克分别对应一个爆炸效果)
var bombImage = new Image();
bombImage.src = 'img/bomb.png';
var bomb = [{
x: -200, // 在canvas中的坐标(隐藏)
y: -200,
imageX: 0, // 图像定位坐标
imageY: 0,
width: 150, // 图像显示区域大小
height: 120,
stop: true // 是否停止
},
{
x: -100, // 在canvas中的坐标(隐藏)
y: -100,
imageX: 0, // 图像定位坐标
imageY: 0,
width: 150, // 图像显示区域大小
height: 120,
stop: true // 是否停止
},
{
x: -100, // 在canvas中的坐标(隐藏)
y: -100,
imageX: 0, // 图像定位坐标
imageY: 0,
width: 150, // 图像显示区域大小
height: 120,
stop: true // 是否停止
}
]; //移动数组(负责控制坦克的前进方向)
var moveArray_enemy = new Array();
for (var i = 0; i < 2; i++) {
moveArray_enemy[i] = new Array();
for (var j = 0; j < 500; j++) {
moveArray_enemy[i][j] = '';
}
} //子弹信息(因为是三辆坦克,所以是子弹数组)
var bulletImage = new Image();
bulletImage.src = 'img/bullet.png';
var bullet = [{
x: 0, // 在canvas中的坐标
y: 0,
imageX: 0, // 图像定位坐标
imageY: 0,
width: 27, // 图像显示区域大小
height: 27,
stop: true // 是否停止
},
{
x: 0, // 在canvas中的坐标
y: 0,
imageX: 0, // 图像定位坐标
imageY: 0,
width: 27, // 图像显示区域大小
height: 27,
stop: true // 是否停止
},
{
x: 0, // 在canvas中的坐标
y: 0,
imageX: 0, // 图像定位坐标
imageY: 0,
width: 27, // 图像显示区域大小
height: 27,
stop: true // 是否停止
}
]; /**
* 清除画布上的内容
*/
function clean() {
// clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
} /**
* 初始化玩家坦克
*/
function playerInit() {
playerImage.onload = _drawPlayer; //onload加载图片,_drawPlayer在画布中绘制图像
console.log('canvas:' + canvas.width + canvas.height)
} /**
* 初始化敌方坦克
*/
function enemyInit() {
enemyImage.onload = _drawEnemy;
/**
* 使用随机数,随机生成“上”,“下”,“左”,“右”,“开火”坦克的四个动作
*/
for (var m = 0; m < moveArray_enemy.length; m++) {
for (var i = 0; i < moveArray_enemy[0].length;) {
var directRandom = Math.round(Math.random() * 150);
console.log(directRandom);
if (directRandom <= 20) {
var j = i + Math.round(Math.random() * 20);
while (i < j) {
moveArray_enemy[m][i] = 'up'; //up
i++;
} } else if (directRandom > 20 && directRandom <= 40) {
var j = i + Math.round(Math.random() * 20);
while (i < j) {
moveArray_enemy[m][i] = 'down'; //down
i++;
} } else if (directRandom > 40 && directRandom <= 60) {
var j = i + Math.round(Math.random() * 20);
while (i < j) {
moveArray_enemy[m][i] = 'left'; //left
i++;
} } else if (directRandom > 60 && directRandom <= 80) {
var j = i + Math.round(Math.random() * 20);
while (i < j) {
moveArray_enemy[m][i] = 'right'; //right
i++;
}
} else if (directRandom > 80 && directRandom <= 150) {
moveArray_enemy[m][i] = 'fire'; //fire
i++;
}
console.log('数组[' + m + ']' + '[' + i + ']' + '值为:' + moveArray_enemy[m][i]);
}
} /**
* 使用定时函数,每隔2毫秒调用一次enemyMove,enemyMove函数的作用是使坦克移动起来
*/
var k = 0;
var enemyTank = window.setInterval(function() {
enemyMove(moveArray_enemy[0][k], 0);
enemyMove(moveArray_enemy[1][k], 1);
if (k == moveArray_enemy[0].length) {
clearInterval(enemyTank);
}
k++;
},
200);
console.log("enemy Move"); } /**
* 加载玩家坦克,并引入键盘事件,键盘控制坦克
*/
function drawPlayerTank() {
playerInit();
eventjs.bind(document, 'keydown', function(event) {
var d = eventjs.getDirection(event);
player.stop = true;
playerAction(d, 0);
});
eventjs.bind(document, 'keyup', function(event) {
var d = eventjs.getDirection(event);
player.stop = false;
playerAction(d, 0);
});
} /**
* 引入初始化敌方坦克
*/
function drawEnemy() {
enemyInit();
} /**
* 分别引入画布,玩家坦克,敌人坦克
*/
var initCanvas = drawCanvas();
var initTank = drawPlayerTank();
var initEnemy = drawEnemy(); /**
* @param {Object} value
* @param {Object} index //标明用到了哪个子弹,哪个爆炸效果
* 玩家坦克动作
*/
function playerMove(value, index) {
if ('right' === value) {
directRight = 1;
directDown = 0;
directUp = 0;
directLeft = 0;
player.imageX = 280;
player.imageY = 0;
player.x += 20; //玩家坦克速度
clean();
console.log("right y=" + player.y + " x=" + player.x);
} else if ('left' === value) {
directLeft = 1;
directRight = 0;
directUp = 0;
directDown = 0;
player.imageX = 0;
player.imageY = 0;
player.x -= 20; //玩家坦克速度
clean();
console.log("left y=" + player.y + " x=" + player.x);
} else if ('up' == value) {
directUp = 1;
directRight = 0;
directDown = 0;
directLeft = 0;
player.imageX = 150;
player.imageY = 0;
player.y -= 20; //玩家坦克速度
clean();
console.log("up y=" + player.y + " x=" + player.x);
} else if ('down' == value) {
directDown = 1;
directRight = 0;
directUp = 0;
directLeft = 0;
player.imageX = 150;
player.imageY = 100;
player.y += 20; //玩家坦克速度
clean();
console.log("down y=" + player.y + " x=" + player.x);
} else if ('fire' == value) {
/**
* 根据坦克目前的方向,判断出子弹的射向
*/
if (directUp == 1) {
bullet[index].imageX = 20;
bullet[index].imageY = 0;
bullet[index].x = player.x + 35;
bullet[index].y = player.y + 50;
/**
* 使用定时函数setInterval实现子弹一帧一帧的飞行效果
*/
var bulletFlyUp = window.setInterval(function() {
console.log("发射了Up子弹");
bullet[index].y -= 20; //子弹飞行速度
console.log(bullet[index].x + "," + bullet[index].y);
//如果向上发射的子弹击中了敌人坦克0
if (bullet[index].x + 50 >= enemy[0].x && bullet[index].x - 50 <= enemy[0].x &&
bullet[index].y + 20 >= enemy[0].y && bullet[index].y - 20 <= enemy[0].y) {
bomb[index].x = enemy[0].x;
bomb[index].y = enemy[0].y;
clearInterval(bulletFlyUp); //击中后就清除子弹,防止子弹继续飞行
enemy[0].x = Math.round(Math.random() * 1400); //设置敌人坦克0的复活地点(随机)
enemy[0].y = Math.round(Math.random() * 700);
}
//如果向上发射的子弹击中了敌人坦克1
if (bullet[index].x + 50 >= enemy[1].x && bullet[index].x - 50 <= enemy[1].x &&
bullet[index].y + 20 >= enemy[1].y && bullet[index].y - 20 <= enemy[1].y) {
bomb[index].x = enemy[1].x;
bomb[index].y = enemy[1].y;
clearInterval(bulletFlyUp); //击中后就清除子弹,防止子弹继续飞行
enemy[1].x = Math.round(Math.random() * 1400); //设置敌人坦克1的复活地点(随机)
enemy[1].y = Math.round(Math.random() * 700);
}
clean();
_drawBullet(index);
_drawPlayer();
_drawEnemy();
_drawBomb(index);
bomb[index].x = -200; //初始化爆炸效果的出现位置
bomb[index].y = -200;
//超出画布,则子弹停止飞行并清除子弹
if (bullet[index].x >= 1400 || bullet[index].y >= 700 || bullet[index].x <= 0 || bullet[index].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyUp);
}
}, 100);
} else if (directDown == 1) {
bullet[index].imageX = 20;
bullet[index].imageY = 30;
bullet[index].x = player.x + 35;
bullet[index].y = player.y + 50;
/**
* 使用定时函数setInterval实现子弹一帧一帧的飞行效果
*/
var bulletFlyDown = window.setInterval(function() {
console.log("发射了Down子弹");
bullet[index].y += 20; //子弹飞行速度
console.log(bullet[index].x + "," + bullet[index].y);
//如果向下发射的子弹击中了敌人坦克0
if (bullet[index].x + 50 >= enemy[0].x && bullet[index].x - 50 <= enemy[0].x &&
bullet[index].y + 20 >= enemy[0].y && bullet[index].y - 20 <= enemy[0].y) {
bomb[index].x = enemy[0].x;
bomb[index].y = enemy[0].y;
clearInterval(bulletFlyDown);
enemy[0].x = Math.round(Math.random() * 1400); //设置敌人坦克0的复活地点(随机)
enemy[0].y = Math.round(Math.random() * 700);
}
如果向下发射的子弹击中了敌人坦克1
if (bullet[index].x + 50 >= enemy[1].x && bullet[index].x - 50 <= enemy[1].x &&
bullet[index].y + 20 >= enemy[1].y && bullet[index].y - 20 <= enemy[1].y) {
bomb[index].x = enemy[1].x;
bomb[index].y = enemy[1].y;
//_drawBomb(index);
clearInterval(bulletFlyDown);
enemy[1].x = Math.round(Math.random() * 1400); //设置敌人坦克1的复活地点(随机)
enemy[1].y = Math.round(Math.random() * 700);
}
clean();
_drawBullet(index);
_drawPlayer();
_drawEnemy();
_drawBomb(index);
bomb[index].x = -200; //初始化爆炸效果的出现位置
bomb[index].y = -200;
//超出画布,则子弹停止飞行并清除子弹
if (bullet[index].x >= 1400 || bullet[index].y >= 700 || bullet[index].x <= 0 || bullet[index].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyDown);
}
}, 100);
} else if (directLeft == 1) {
bullet[index].imageX = 0;
bullet[index].imageY = 0;
bullet[index].x = player.x + 20;
bullet[index].y = player.y + 24;
/**
* 使用定时函数setInterval实现子弹一帧一帧的飞行效果
*/
var bulletFlyLeft = window.setInterval(function() {
console.log("发射了Left子弹");
bullet[index].x -= 20; //子弹飞行速度
console.log(bullet[index].x + "," + bullet[index].y);
//如果向左发射的子弹击中了敌人坦克0
if (bullet[index].x + 20 >= enemy[0].x && bullet[index].x - 20 <= enemy[0].x &&
bullet[index].y + 50 >= enemy[0].y && bullet[index].y - 50 <= enemy[0].y) {
bomb[index].x = enemy[0].x;
bomb[index].y = enemy[0].y;
clearInterval(bulletFlyLeft);
enemy[0].x = Math.round(Math.random() * 1400); //设置敌人坦克0的复活地点(随机
enemy[0].y = Math.round(Math.random() * 700);
}
//如果向左发射的子弹击中了敌人坦克1
if (bullet[index].x + 20 >= enemy[1].x && bullet[index].x - 20 <= enemy[1].x &&
bullet[index].y + 50 >= enemy[1].y && bullet[index].y - 50 <= enemy[1].y) {
bomb[index].x = enemy[1].x;
bomb[index].y = enemy[1].y;
clearInterval(bulletFlyLeft);
enemy[1].x = Math.round(Math.random() * 1400); //设置敌人坦克1的复活地点(随机
enemy[1].y = Math.round(Math.random() * 700);
}
clean();
_drawBullet(index);
_drawPlayer();
_drawEnemy();
_drawBomb(index);
bomb[index].x = -200; //初始化爆炸效果的出现位置
bomb[index].y = -200;
if (bullet[index].x >= 1400 || bullet[index].y >= 700 || bullet[index].x <= 0 || bullet[index].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyLeft);
}
}, 100);
} else if (directRight == 1) {
bullet[index].imageX = 40;
bullet[index].imageY = 0;
bullet[index].x = player.x + 70;
bullet[index].y = player.y + 24;
/**
* 使用定时函数setInterval实现子弹一帧一帧的飞行效果
*/
var bulletFlyRight = window.setInterval(function() {
console.log("发射了Right子弹");
bullet[index].x += 20; //子弹飞行速度
//如果向右发射的子弹击中了敌人坦克0
if (bullet[index].x + 20 >= enemy[0].x && bullet[index].x - 20 <= enemy[0].x &&
bullet[index].y + 50 >= enemy[0].y && bullet[index].y - 50 <= enemy[0].y) {
bomb[index].x = enemy[0].x;
bomb[index].y = enemy[0].y;
clearInterval(bulletFlyRight);
enemy[0].x = Math.round(Math.random() * 1400); //设置敌人坦克0的复活地点(随机)
enemy[0].y = Math.round(Math.random() * 700);
}
//如果向右发射的子弹击中了敌人坦克1
if (bullet[index].x + 20 >= enemy[1].x && bullet[index].x - 20 <= enemy[1].x &&
bullet[index].y + 50 >= enemy[1].y && bullet[index].y - 50 <= enemy[1].y) {
bomb[index].x = enemy[1].x;
bomb[index].y = enemy[1].y;
clearInterval(bulletFlyRight);
enemy[1].x = Math.round(Math.random() * 1400); //设置敌人坦克1的复活地点(随机)
enemy[1].y = Math.round(Math.random() * 700);
}
clean();
_drawBullet(index);
_drawPlayer();
_drawEnemy();
_drawBomb(index);
bomb[index].x = -200; //初始化爆炸效果的出现位置
bomb[index].y = -200;
if (bullet[index].x >= 1400 || bullet[index].y >= 700 || bullet[index].x <= 0 || bullet[index].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyRight);
}
}, 100);
} }
_drawPlayer();
_drawEnemy();
} /**
* @param {Object} value
* @param {Object} index
* 敌方坦克动作(逻辑同“playerMove方法”
*/
function enemyMove(value, index) {
/**
* 限制敌方坦克移动不会超过画布,如果超过画布就会被弹回
*/
if (enemy[index].x >= canvas.width - 20) {
enemy[index].x -= 100;
} else if (enemy[index].y > canvas.height - 20) {
enemy[index].y -= 100;
} else if (enemy[index].x < 20) {
enemy[index].x += 100;
} else if (enemy[index].y < 20) {
enemy[index].y += 100;
}
if ('right' == value) {
enemydirectRight[index] = 1;
enemydirectDown[index] = 0;
enemydirectUp[index] = 0;
enemydirectLeft[index] = 0;
enemy[index].imageX = 280;
enemy[index].imageY = 0;
enemy[index].x += 15;
clean();
console.log("right y=" + enemy[index].y + " x=" + enemy[index].x);
} else if ('left' == value) {
enemydirectLeft[index] = 1;
enemydirectRight[index] = 0;
enemydirectUp[index] = 0;
enemydirectDown[index] = 0;
enemy[index].imageX = 0;
enemy[index].imageY = 0;
enemy[index].x -= 15;
clean();
console.log("left y=" + enemy[index].y + " x=" + enemy[index].x);
} else if ('up' == value) {
enemydirectUp[index] = 1;
enemydirectRight[index] = 0;
enemydirectDown[index] = 0;
enemydirectLeft[index] = 0;
enemy[index].imageX = 150;
enemy[index].imageY = 0;
enemy[index].y -= 15;
clean();
console.log("up y=" + enemy[index].y + " x=" + enemy[index].x);
} else if ('down' == value) {
enemydirectDown[index] = 1;
enemydirectRight[index] = 0;
enemydirectUp[index] = 0;
enemydirectLeft[index] = 0;
enemy[index].imageX = 150;
enemy[index].imageY = 100;
enemy[index].y += 15;
clean();
console.log("down y=" + enemy[index].y + " x=" + enemy[index].x);
} else if ('fire' == value) {
console.log("敌方发射了子弹");
console.log("Up:" + enemydirectUp[index]);
console.log("Down:" + enemydirectDown[index]);
console.log("Left:" + enemydirectLeft[index]);
console.log("Right:" + enemydirectRight[index]);
var index_1 = index + 1;
if (enemydirectUp[index] == 1) {
bullet[index_1].imageX = 20;
bullet[index_1].imageY = 0;
bullet[index_1].x = enemy[index].x + 35;
bullet[index_1].y = enemy[index].y + 50;
var bulletFlyUp = window.setInterval(function() {
console.log("发射了Up子弹");
bullet[index_1].y -= 20;
console.log(bullet[index_1].x + "," + bullet[index_1].y);
if (bullet[index_1].x + 50 >= enemy[0].x && bullet[index_1].x - 50 <= enemy[0].x &&
bullet[index_1].y + 20 >= enemy[0].y && bullet[index_1].y - 20 <= enemy[0].y) {
bomb[index_1].x = enemy[0].x;
bomb[index_1].y = enemy[0].y;
clearInterval(bulletFlyUp);
enemy[0].x = Math.round(Math.random() * 1400); //设置敌方坦克0的复活地点
enemy[0].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 50 >= enemy[1].x && bullet[index_1].x - 50 <= enemy[1].x &&
bullet[index_1].y + 20 >= enemy[1].y && bullet[index_1].y - 20 <= enemy[1].y) {
bomb[index_1].x = enemy[1].x;
bomb[index_1].y = enemy[1].y;
clearInterval(bulletFlyUp);
enemy[1].x = Math.round(Math.random() * 1400); //设置敌方坦克1的复活地点
enemy[1].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 50 >= player.x && bullet[index_1].x - 50 <= player.x &&
bullet[index_1].y + 20 >= player.y && bullet[index_1].y - 20 <= player.y) {
bomb[index_1].x = player.x;
bomb[index_1].y = player.y;
clearInterval(bulletFlyUp);
player.x = 0; //设置玩家坦克的复活地点
player.y = 0;
}
clean();
_drawBullet(index_1);
_drawPlayer();
_drawEnemy();
_drawBomb(index_1);
bomb[index_1].x = -200;
bomb[index_1].y = -200;
if (bullet[index_1].x >= 1400 || bullet[index_1].y >= 700 || bullet[index_1].x <= 0 || bullet[index_1].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyUp);
}
}, 100);
} else if (enemydirectDown[index] == 1) {
bullet[index_1].imageX = 20;
bullet[index_1].imageY = 30;
bullet[index_1].x = enemy[index].x + 35;
bullet[index_1].y = enemy[index].y + 50;
var bulletFlyDown = window.setInterval(function() {
console.log("发射了Down子弹");
bullet[index_1].y += 20;
console.log(bullet[index_1].x + "," + bullet[index_1].y);
if (bullet[index_1].x + 50 >= enemy[0].x && bullet[index_1].x - 50 <= enemy[0].x &&
bullet[index_1].y + 20 >= enemy[0].y && bullet[index_1].y - 20 <= enemy[0].y) {
bomb[index_1].x = enemy[0].x;
bomb[index_1].y = enemy[0].y; clearInterval(bulletFlyDown);
enemy[0].x = Math.round(Math.random() * 1400); //设置enemy0的复活地点
enemy[0].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 50 >= enemy[1].x && bullet[index_1].x - 50 <= enemy[1].x &&
bullet[index_1].y + 20 >= enemy[1].y && bullet[index_1].y - 20 <= enemy[1].y) {
bomb[index_1].x = enemy[1].x;
bomb[index_1].y = enemy[1].y; clearInterval(bulletFlyDown);
enemy[1].x = Math.round(Math.random() * 1400); //设置enemy1的复活地点
enemy[1].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 50 >= player.x && bullet[index_1].x - 50 <= player.x &&
bullet[index_1].y + 20 >= player.y && bullet[index_1].y - 20 <= player.y) {
bomb[index_1].x = player.x;
bomb[index_1].y = player.y; clearInterval(bulletFlyDown);
player.x = 0; //设置player的复活地点
player.y = 0;
}
clean();
_drawBullet(index_1);
_drawPlayer();
_drawEnemy();
_drawBomb(index_1);
bomb[index_1].x = -200;
bomb[index_1].y = -200;
if (bullet[index_1].x >= 1400 || bullet[index_1].y >= 700 || bullet[index_1].x <= 0 || bullet[index_1].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyDown);
}
}, 100);
} else if (enemydirectLeft[index] == 1) {
bullet[index_1].imageX = 0;
bullet[index_1].imageY = 0;
bullet[index_1].x = enemy[index].x + 20;
bullet[index_1].y = enemy[index].y + 24;
var bulletFlyLeft = window.setInterval(function() {
console.log("发射了Left子弹");
bullet[index_1].x -= 20;
console.log(bullet[index_1].x + "," + bullet[index_1].y);
if (bullet[index_1].x + 20 >= enemy[0].x && bullet[index_1].x - 20 <= enemy[0].x &&
bullet[index_1].y + 50 >= enemy[0].y && bullet[index_1].y - 50 <= enemy[0].y) {
bomb[index_1].x = enemy[0].x;
bomb[index_1].y = enemy[0].y; clearInterval(bulletFlyLeft);
enemy[0].x = Math.round(Math.random() * 1400); //设置enemy0的复活地点
enemy[0].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 20 >= enemy[1].x && bullet[index_1].x - 20 <= enemy[1].x &&
bullet[index_1].y + 50 >= enemy[1].y && bullet[index_1].y - 50 <= enemy[1].y) {
bomb[index_1].x = enemy[1].x;
bomb[index_1].y = enemy[1].y; clearInterval(bulletFlyLeft);
enemy[1].x = Math.round(Math.random() * 1400); //设置enemy1的复活地点
enemy[1].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 20 >= player.x && bullet[index_1].x - 20 <= player.x &&
bullet[index_1].y + 50 >= player.y && bullet[index_1].y - 50 <= player.y) {
bomb[index_1].x = player.x;
bomb[index_1].y = player.y; clearInterval(bulletFlyLeft);
player.x = 0; //设置player的复活地点
player.y = 0;
}
clean();
_drawBullet(index_1);
_drawPlayer();
_drawEnemy();
_drawBomb(index_1);
bomb[index_1].x = -200;
bomb[index_1].y = -200;
if (bullet[index_1].x >= 1400 || bullet[index_1].y >= 700 || bullet[index_1].x <= 0 || bullet[index_1].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyLeft);
}
}, 100);
} else if (enemydirectRight[index] == 1) {
bullet[index_1].imageX = 40;
bullet[index_1].imageY = 0;
bullet[index_1].x = enemy[index].x + 70;
bullet[index_1].y = enemy[index].y + 24;
var bulletFlyRight = window.setInterval(function() {
console.log("发射了Right子弹");
bullet[index_1].x += 20;
console.log(bullet[index_1].x + "," + bullet[index_1].y);
if (bullet[index_1].x + 20 >= enemy[0].x && bullet[index_1].x - 20 <= enemy[0].x &&
bullet[index_1].y + 50 >= enemy[0].y && bullet[index_1].y - 50 <= enemy[0].y) {
bomb[index_1].x = enemy[0].x;
bomb[index_1].y = enemy[0].y; clearInterval(bulletFlyRight);
enemy[0].x = Math.round(Math.random() * 1400); //设置enemy0的复活地点
enemy[0].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 20 >= enemy[1].x && bullet[index_1].x - 20 <= enemy[1].x &&
bullet[index_1].y + 50 >= enemy[1].y && bullet[index_1].y - 50 <= enemy[1].y) {
bomb[index_1].x = enemy[1].x;
bomb[index_1].y = enemy[1].y; clearInterval(bulletFlyRight);
enemy[1].x = Math.round(Math.random() * 1400); //设置enemy1的复活地点
enemy[1].y = Math.round(Math.random() * 700);
}
if (bullet[index_1].x + 20 >= player.x && bullet[index_1].x - 20 <= player.x &&
bullet[index_1].y + 50 >= player.y && bullet[index_1].y - 50 <= player.y) {
bomb[index_1].x = player.x;
bomb[index_1].y = player.y; clearInterval(bulletFlyRight);
player.x = 0; //设置player的复活地点
player.y = 0;
}
clean();
_drawBullet(index_1);
_drawPlayer();
_drawEnemy();
_drawBomb(index_1);
bomb[index_1].x = -200;
bomb[index_1].y = -200;
if (bullet[index_1].x >= 1400 || bullet[index_1].y >= 700 || bullet[index_1].x <= 0 || bullet[index_1].y <= 0) {
console.log("子弹飞行停止");
clearInterval(bulletFlyRight);
}
}, 100);
} }
_drawPlayer();
_drawEnemy(); } /**
* 在画布上绘制玩家坦克
*/
function _drawPlayer() {
ctx.drawImage(playerImage, player.imageX, player.imageY, player.width, player.height, player.x, player.y, player.width,
player.height);
} /**
* 在画布上绘制敌方坦克
*/
function _drawEnemy() {
for (var i = 0; i < 2; i++) { //两辆敌方坦克
ctx.drawImage(enemyImage, enemy[i].imageX, enemy[i].imageY, enemy[i].width, enemy[i].height, enemy[i].x, enemy[i]
.y,
enemy[i].width,
enemy[i].height);
}
} /**
* @param {Object} index index参数表示是哪辆坦克的子弹,0为玩家坦克子弹,1为敌方坦克0子弹,2为敌方坦克1子弹
* 在画布上绘制子弹
*/
function _drawBullet(index) {
ctx.drawImage(bulletImage, bullet[index].imageX, bullet[index].imageY, bullet[index].width, bullet[index].height,
bullet[index].x,
bullet[index].y, bullet[index].width,
bullet[index].height);
} /**
* @param {Object} index index参数表示是哪辆坦克被击中爆炸了,0为玩家坦克爆炸,1为敌方坦克0爆炸,2为敌方坦克1爆炸
* 绘制爆炸效果
*/
function _drawBomb(index) {
ctx.drawImage(bombImage, bomb[index].imageX, bomb[index].imageY, bomb[index].width, bomb[index].height,
bomb[index].x,
bomb[index].y, bomb[index].width,
bomb[index].height);
} /**
* @param {Object} value
* @param {Object} index
* 对玩家坦克的移动进行边界控制,即限制玩家坦克开出画布
*/
function playerAction(value, index) {
var posX = 0;
var posY = 0;
switch (value) {
case 'up':
if (player.y < 5) {
return;
};
playerMove(value, index);
break;
break;
case 'right':
posX = player.x + player.width;
if (posX >= canvas.width) {
return;
};
playerMove(value, index);
break;
case 'down':
posY = player.y + player.height;
if (posY >= canvas.height) {
return;
};
playerMove(value, index);
break;
case 'left':
if (player.x < 5) {
return;
};
playerMove(value, index);
break;
case 'fire':
playerMove(value, index);
break;
};
return {
x: player.x,
y: player.y
};
}
}); /**
* 键盘事件
*/
var eventjs = {
//添加事件
bind: function(elem, type, handler) {
if (elem.addEventListener) {
elem.addEventListener(type, handler, false);
} else if (elem.attachEvent) {
//IE
elem.attachEvent("on" + type, handler);
} else {
elem["on" + type] = handler;
};
},
//删除事件
unbind: function(elem, type, handler) {
if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
} else if (elem.detachEvent) {
//IE
elem.detachEvent("on" + type, handler)
} else {
elem["on" + type] = handler;
};
},
//获取事件
getEvent: function(event) {
return event ? event : window.event;
},
//获取事件目标
getTarget: function(event) {
return event.target || event.srcElement;
},
//相关元素
relatedTarget: function(event) {
if (event.relatedTarget) {
return event.relatedTarget;
} else if (event.toElement) {
return event.toElement;
} else if (event.formElement) {
return event.formElement;
} else {
return null;
};
},
//阻止默认行为
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
//取消捕获/冒泡
cancelBubble: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
};
},
//获取鼠标按钮
getMouseButton: function(event) {
if (document.implementation.hasFeature("MouseEvents", "2.0")) {
return event.button;
} else {
switch (event.button) {
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
};
},
//获取键盘code
getCharCode: function(event) {
if (typeof event.charCode == "number") {
console.log('char code');
return event.charCode;
} else {
return event.keyCode;
};
},
getDirection: function(event) {
var keyCode = event.which || event.keyCode;
switch (keyCode) {
case 38:
return 'up';
break;
case 40:
return 'down';
break;
case 37:
return 'left';
break;
case 39:
return 'right';
break;
case 32:
return 'fire';
break;
}
}
};

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/tank.js"></script>
</head>
<body>
<canvas id="demo" style="border:1px solid #ddd;">您的浏览器不支持canvas标签。</canvas>
</body>
</html>

5、总结

这款游戏做的很粗糙很简陋,代码写得也挺复杂的。因为明天要上班所以就不继续优化了。我只是提供一个demo。

html取代flash是必然的趋势,随着游览器的升级,以及flash的慢慢停更,以后的浏览器可能就无法支持flash插件了,因此许多像4399,7K7K这些flash小游戏逐渐的就无法玩了。当然如果把那些网页flash小游戏全部做成html的,那么也可以在浏览器上玩这些小游戏。但很少甚至不会有人去做。因为随着移动技术的发展,以及像微信小程序这种技术。以前玩flash小游戏就是图这些小游戏加载起来快,不用安装,即点即玩,消磨时间。但现在智能手机的普及带动了手游的繁荣,微信小程序完美复刻了以前的网页flash小游戏的感觉。

https://mp.weixin.qq.com/s/TqZRynxO_X-ZjyKf4bHqkQ   《“爷青结”!Flash Player正式停止支持服务,《黄金矿工》、4399终究是到了结束的这一天......》

这是之前微信上看到的文章,也许几年以后,4399,7K7K这些flash小游戏,就会像上世纪的红白机游戏一样隐退江湖。

使用jquery—Canvas实现html5小游戏——《坦克大战》的更多相关文章

  1. 推荐10款超级有趣的HTML5小游戏

    HTML5的发展速度比任何人的都想像都要更快.更加强大有效的和专业的解决方案已经被开发......甚至在游戏世界中!这里跟大家分享有10款超级趣味的HTML5游戏,希望大家能够喜欢! Kern Typ ...

  2. HTML5小游戏UI美化版

    HTML5小游戏[是男人就下一百层]UI美化版 之前写的小游戏,要么就比较简单,要么就是比较难看,或者人物本身是不会动的. 结合了其它人的经验,研究了一下精灵运动,就写一个简单的小游戏来试一下. 介绍 ...

  3. 软件工程 Android小游戏 猜拳大战

    一.前言 最近学校举办的大学生程序设计竞赛,自己利用课余时间写了一个小游戏,最近一直在忙这个写这个小游戏,参加比赛,最终是老师说自己写的简单,可以做的更复杂的点的.加油 二.内容简介 自己玩过Andr ...

  4. Java小项目--坦克大战(version1.0)

    Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...

  5. 原生JS实现的h5小游戏-植物大战僵尸

    代码地址如下:http://www.demodashi.com/demo/12755.html 项目介绍 本项目是利用原生js实现的h5小游戏-植物大战僵尸,主要结合了一下自己对于h5小游戏的理解,结 ...

  6. HTML5小游戏源码收藏

    html5魅族创意的贪食蛇游戏源码下载 html5网页版打砖块小游戏源码下载 html5 3D立体魔方小游戏源码下载 html5网页版飞机躲避游戏源码下载 html5三国人物连连看游戏源码下载 js ...

  7. Html5 小游戏 俄罗斯方块

    导言 在一个风和日丽的一天,看完了疯狂HTML 5+CSS 3+JavaScript讲义,跟着做了书里最后一章的俄罗斯方块小游戏,并做了一些改进,作为自己前端学习的第一站. 游戏效果: 制作思路 因为 ...

  8. HTML5小游戏之见缝插针

    今天给大家带来的就是一款叫做<见缝插针>的游戏.有空你就往里插,直到你无处可插!看你能过多少关! 简洁大气 黑白搭配游戏画面非常的简洁,米白色的背景中央,放置着一个不断旋转的太阳状的球体, ...

  9. 菜鸟做HTML5小游戏 - 翻翻乐

    记录下开放过程.做小游戏开发,又要跨平台,flash又不支持iPhone,html5是最好的选择. 先看看最后效果: 好了,开始demo. 1.准备工作: 图片素材(省略...最后代码一起打包) 了解 ...

随机推荐

  1. MSQL-->存储引擎

    概述 MySQL体系结构图 Innodb引擎是在mysql的5.5版本之后的默认存储引擎. Index是在引擎层次的,不同的存储引擎index的用法不同. 存储引擎就是存储数据,建立索引,更新查询数据 ...

  2. NodeJS 服务 Docker 镜像极致优化指北

    这段时间在开发一个腾讯文档全品类通用的 HTML 动态服务,为了方便各品类接入的生成与部署,也顺应上云的趋势,考虑使用 Docker 的方式来固定服务内容,统一进行制品版本的管理.本篇文章就将我在服务 ...

  3. NOIP2017总结 & 题解

    day1t1的结论貌似在哪见过,自己稍微验证了一下貌似没记错就没有管了.t2一道很好(keng)的模拟题啊t3自己做题好慢啊,想出来dp打上去最后几分钟才过了大样例,我写的是记忆化搜索,判-1很好判, ...

  4. 一个电器工厂可以生产多种类型的电器,如海尔工厂可以生产海尔电视机、海尔空调等,TCL工厂可以生产TCL电视机,TCL空调等,相同品牌的电器构成一个产品族,而相同类型的电器构成了一个产品等级结构,现使用

    一个电器工厂可以生产多种类型的电器,如海尔工厂可以生产海尔电视机.海尔空调等,TCL工厂可以生产TCL电视机,TCL空调等,相同品牌的电器构成一个产品族,而相同类型的电器构成了一个产品等级结构,现使用 ...

  5. 一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1.简述MySQL中索引类型对数据库的性能的影响 2.RDB和AOF机制 3.Redis的过期键的删除策略 4.Redis ...

  6. 齐博x1客服系统显示客户在哪个页面

    如下图所示,要想实现下面的效果,即显示客户给你发消息时,当时处于哪个商品页面.这样方便跟客户针对此商品进行交流. 你的模板如果使用了碎片的话,就可以添加下面的代码index_style/default ...

  7. AR人体姿态识别,实现无边界的人机交互

    近年来,AR不断发展,作为一种增强现实技术,给用户带来了虚拟和现实世界的融合体验.但用户已经不满足于单纯地将某件虚拟物品放在现实场景中来感受AR技术,更想用身体姿势来触发某个指令,达到更具真实感的人机 ...

  8. Windows7下驱动开发与调试体系构建——4.在x64下使用汇编代码(x86下的_asm)

    目录/参考资料:https://www.cnblogs.com/railgunRG/p/14412321.html asm文件设置 在vs x64中无法使用_asm关键字,需要使用.asm文件. 按第 ...

  9. Appscan的安装破解以及使用

    本文简单介绍Appscan的安装和使用. 一.下载安装 可自行百度下载相关安装包(因较高版本的破解资料比较难找,建议下载9.0版本). 双击.exe安装文件进行安装,在弹出的安装指引中各选项默认安装即 ...

  10. java安全之CC1浅学(1)

    前言 由于CC链还是比较复杂的,我们可以先看命令执行的部分payload之后再加上反序列化部分组成一个完整的payload 调试一 项目导入依赖,这里使用3.1版本 <!-- https://m ...