之前上传的坦克大战因为改来改去没完整上传导致出了bug。。。半年前的代码改到心累。。。这次干脆就把修改到最后的版本发上来,虽然也是几个月前的东西了。。。路过的大佬有兴趣就拉下代码玩玩吧
在之前的版本上添加了地图选择,玩家数量选择,模式选择,按键设置等
文件路径:
tankAI.html
<!DOCTYPE html>
<html>
<head>
<title>坦克大战</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/tank.css">
</head>
<body>
<div class="homePage" id="home">
<h1>坦克大战</h1>
<p class="startGame">游戏开始</p>
<p>地图选择</p>
<p>游戏设置</p>
<p>游戏规则</p>
</div>
<div class="gameStart" id="start">
<canvas id="canvas" class="canvas">当前浏览器不支持canvas标签,请更换浏览器重新尝试</canvas>
<p class="playerData">player1:
<span class="h">h:</span>
<span class="kills">kill:</span>
</p>
<p class="playerData">player2:
<span class="h">h:</span>
<span class="kills">kill:</span>
</p>
</div>
<div class="picChoose" id="picCh">
<p></p>
<button type="button" class="startGame">开始游戏</button>
<button type="button" class="back">回到首页</button>
</div>
<div class="gameSetting" id="set">
<form>
<fieldset id="player" class="playSet">
<label>player1:</label>
<input type="button" name="code" class="left code" value="left">
<input type="button" name="code" class="up code" value="up">
<input type="button" name="code" class="right code" value="right">
<input type="button" name="code" class="down code" value="down">
<input type="button" name="code" class="shot code" value="shot">
<label>player2:</label>
<input type="button" name="code" class="left code" value="left">
<input type="button" name="code" class="up code" value="up">
<input type="button" name="code" class="right code" value="right">
<input type="button" name="code" class="down code" value="down">
<input type="button" name="code" class="shot code" value="shot">
</fieldset>
<fieldset id="modeChoose">
<input type="radio" name="mode" id="fight" checked="checked">
<label for="fight">无尽模式</label>
<input type="radio" name="mode" id="protect">
<label for="protect">保卫模式</label>
</fieldset>
<fieldset>
<input type="radio" name="playerChoose" id="single" checked="checked">
<label for="single">单人模式</label>
<input type="radio" name="playerChoose" id="double">
<label for="double">双人模式</label>
</fieldset>
</form>
<button type="button" class="startGame">游戏开始</button>
<button type="button" class="back">回到首页</button>
<button type="button" class="setFinish">设置完成</button>
<button type="button" class="setBegin">初始设置</button>
</div>
<div class="gameRules" id="rule">
<p>玩家双方操纵自己的坦克,尽可能地摧毁敌方坦克</p>
<p>无尽模式:敌方坦克的数量保持不变,玩家通过摧毁一定数量的坦克获得胜利</p>
<p>保卫模式:玩家保护自己的基地,将生成的坦克全部摧毁,则获得胜利</p>
<p>道具 T+:坦克变大 T-:坦克变小 H+:生命加一 V+:坦克速度变快 S+:炮弹速度变快 S-:炮弹发射间隔减短</p>
<button type="button" class="startGame">游戏开始</button>
<button type="button" class="back">回到首页</button>
</div>
<script type="text/javascript" src="js/barrier.js"></script>
<script type="text/javascript" src="js/tankAI.js"></script>
</body>
</html>
tank.css
body>div{
text-align: center;
display: none;
}
input{
outline: none;
}
.homePage{
display: block;
}
.homePage p{
font-size: 20px;
}
.homePage p:hover{
font-weight: bold;
color: rgb(0,0,255);
background-color: rgb(255,0,0);
cursor: pointer;
}
.picChoose canvas:first-child{
filter: brightness(200%);
border: 2px solid rgb(255,0,0);
}
.picChoose canvas{
margin: 0 10px;
cursor: pointer;
}
.playSet input{
border:outset;
background-color: rgb(102,153,51);
cursor: pointer;
}
.setFinish{
display: none;
}
.playerData span{
margin-left: 20px;
}
barrier.js
var woods=[
[],
[{x:25,y:26},{x:24,y:26},{x:23,y:26},{x:22,y:26},{x:27,y:26},{x:28,y:26},{x:29,y:26},{x:30,y:26},{x:26,y:25},{x:26,y:24},{x:26,y:23},{x:26,y:22},{x:26,y:27},{x:26,y:28},{x:26,y:29},{x:26,y:30},{x:11,y:12},{x:10,y:12},{x:9,y:12},{x:8,y:12},{x:13,y:12},{x:14,y:12},{x:15,y:12},{x:16,y:12},{x:12,y:11},{x:12,y:10},{x:12,y:9},{x:12,y:8},{x:12,y:13},{x:12,y:14},{x:12,y:15},{x:12,y:16},{x:39,y:12},{x:38,y:12},{x:37,y:12},{x:36,y:12},{x:41,y:12},{x:42,y:12},{x:43,y:12},{x:44,y:12},{x:40,y:11},{x:40,y:10},{x:40,y:9},{x:40,y:8},{x:40,y:13},{x:40,y:14},{x:40,y:15},{x:40,y:16},{x:39,y:40},{x:38,y:40},{x:37,y:40},{x:36,y:40},{x:41,y:40},{x:42,y:40},{x:43,y:40},{x:44,y:40},{x:40,y:39},{x:40,y:38},{x:40,y:37},{x:40,y:36},{x:40,y:41},{x:40,y:42},{x:40,y:43},{x:40,y:44},{x:11,y:40},{x:10,y:40},{x:9,y:40},{x:8,y:40},{x:13,y:40},{x:14,y:40},{x:15,y:40},{x:16,y:40},{x:12,y:39},{x:12,y:38},{x:12,y:37},{x:12,y:36},{x:12,y:41},{x:12,y:42},{x:12,y:43},{x:12,y:44}
],
[],
[{x:11,y:2},{x:11,y:3},{x:11,y:4},{x:11,y:5},{x:11,y:6},{x:11,y:7},{x:11,y:8},{x:11,y:9},{x:11,y:10},{x:11,y:12},{x:11,y:13},{x:11,y:14},{x:11,y:15},{x:11,y:16},{x:11,y:17},{x:11,y:18},{x:11,y:19},{x:11,y:20},{x:11,y:22},{x:11,y:23},{x:11,y:24},{x:11,y:25},{x:11,y:26},{x:11,y:27},{x:11,y:28},{x:11,y:29},{x:11,y:30},{x:11,y:32},{x:11,y:33},{x:11,y:34},{x:11,y:35},{x:11,y:36},{x:11,y:37},{x:11,y:38},{x:11,y:39},{x:11,y:40},{x:11,y:42},{x:11,y:43},{x:11,y:44},{x:11,y:45},{x:31,y:2},{x:31,y:3},{x:31,y:4},{x:31,y:5},{x:31,y:6},{x:31,y:7},{x:31,y:8},{x:31,y:9},{x:31,y:10},{x:31,y:12},{x:31,y:13},{x:31,y:14},{x:31,y:15},{x:31,y:16},{x:31,y:17},{x:31,y:18},{x:31,y:19},{x:31,y:20},{x:31,y:22},{x:31,y:23},{x:31,y:24},{x:31,y:25},{x:31,y:26},{x:31,y:27},{x:31,y:28},{x:31,y:29},{x:31,y:30},{x:31,y:32},{x:31,y:33},{x:31,y:34},{x:31,y:35},{x:31,y:36},{x:31,y:37},{x:31,y:38},{x:31,y:39},{x:31,y:40},{x:31,y:42},{x:31,y:43},{x:31,y:44},{x:31,y:45},{x:21,y:7},{x:21,y:8},{x:21,y:9},{x:21,y:10},{x:21,y:12},{x:21,y:13},{x:21,y:14},{x:21,y:15},{x:21,y:16},{x:21,y:17},{x:21,y:18},{x:21,y:19},{x:21,y:20},{x:21,y:22},{x:21,y:23},{x:21,y:24},{x:21,y:25},{x:21,y:26},{x:21,y:27},{x:21,y:28},{x:21,y:29},{x:21,y:30},{x:21,y:32},{x:21,y:33},{x:21,y:34},{x:21,y:35},{x:21,y:36},{x:21,y:37},{x:21,y:38},{x:21,y:39},{x:21,y:40},{x:21,y:42},{x:21,y:43},{x:21,y:44},{x:21,y:45},{x:21,y:46},{x:21,y:47},{x:21,y:48},{x:21,y:49},{x:21,y:50},{x:21,y:51},{x:21,y:52},{x:41,y:7},{x:41,y:8},{x:41,y:9},{x:41,y:10},{x:41,y:12},{x:41,y:13},{x:41,y:14},{x:41,y:15},{x:41,y:16},{x:41,y:17},{x:41,y:18},{x:41,y:19},{x:41,y:20},{x:41,y:22},{x:41,y:23},{x:41,y:24},{x:41,y:25},{x:41,y:26},{x:41,y:27},{x:41,y:28},{x:41,y:29},{x:41,y:30},{x:41,y:32},{x:41,y:33},{x:41,y:34},{x:41,y:35},{x:41,y:36},{x:41,y:37},{x:41,y:38},{x:41,y:39},{x:41,y:40},{x:41,y:42},{x:41,y:43},{x:41,y:44},{x:41,y:45},{x:41,y:46},{x:41,y:47},{x:41,y:48},{x:41,y:49},{x:41,y:50},{x:41,y:51},{x:41,y:52}
]
];
var Fes=[
[],
[{x:26,y:26},{x:12,y:12},{x:40,y:40},{x:12,y:40},{x:40,y:12}
],
[{x:25,y:26},{x:24,y:26},{x:23,y:26},{x:22,y:26},{x:27,y:26},{x:28,y:26},{x:29,y:26},{x:30,y:26},{x:26,y:25},{x:26,y:24},{x:26,y:23},{x:26,y:22},{x:26,y:27},{x:26,y:28},{x:26,y:29},{x:26,y:30},{x:11,y:12},{x:10,y:12},{x:9,y:12},{x:8,y:12},{x:13,y:12},{x:14,y:12},{x:15,y:12},{x:16,y:12},{x:12,y:11},{x:12,y:10},{x:12,y:9},{x:12,y:8},{x:12,y:13},{x:12,y:14},{x:12,y:15},{x:12,y:16},{x:39,y:12},{x:38,y:12},{x:37,y:12},{x:36,y:12},{x:41,y:12},{x:42,y:12},{x:43,y:12},{x:44,y:12},{x:40,y:11},{x:40,y:10},{x:40,y:9},{x:40,y:8},{x:40,y:13},{x:40,y:14},{x:40,y:15},{x:40,y:16},{x:39,y:40},{x:38,y:40},{x:37,y:40},{x:36,y:40},{x:41,y:40},{x:42,y:40},{x:43,y:40},{x:44,y:40},{x:40,y:39},{x:40,y:38},{x:40,y:37},{x:40,y:36},{x:40,y:41},{x:40,y:42},{x:40,y:43},{x:40,y:44},{x:11,y:40},{x:10,y:40},{x:9,y:40},{x:8,y:40},{x:13,y:40},{x:14,y:40},{x:15,y:40},{x:16,y:40},{x:12,y:39},{x:12,y:38},{x:12,y:37},{x:12,y:36},{x:12,y:41},{x:12,y:42},{x:12,y:43},{x:12,y:44}
],
[{x:11,y:11},{x:11,y:21},{x:11,y:31},{x:11,y:41},{x:21,y:11},{x:21,y:21},{x:21,y:31},{x:21,y:41},{x:31,y:11},{x:31,y:21},{x:31,y:31},{x:31,y:41},{x:41,y:11},{x:41,y:21},{x:41,y:31},{x:41,y:41}
]
];
var protects=[
{x:25,y:51},{x:25,y:50},{x:25,y:49},{x:26,y:49},{x:27,y:49},{x:28,y:49},{x:29,y:49},{x:29,y:51},{x:29,y:50}
]
tankAI.js
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
canvas.width = 520;
canvas.height = 520;
//定义坦克初始位置
let tanksPosition = [
{ x: 220, y: canvas.height - 20 },
{ x: 310, y: canvas.height - 20 }
]
//定义坦克数组
let tanks = [
{ x: 220, y: canvas.height - 20, v: 5, l: 20, h: 3, d: 1, i: 0, up: [38, false], right: [39, false], down: [40, false], left: [37, false], shot: [32, false], bv: 6, inter: 500, color: 'rgb(0,204,204)' },
{ x: 310, y: canvas.height - 20, v: 5, l: 20, h: 3, d: 1, i: 0, up: [87, false], right: [68, false], down: [83, false], left: [65, false], shot: [192, false], bv: 6, inter: 500, color: 'rgb(0,255,0)' }
];
//初始化摧毁数
let kills = 0;
let kill = [0, 0]
//定义炮弹数组
let bullets = [];
//定义木头宽度
let woodLength = 10;
//定义铁块宽度
let Felength = 10;
//定义旗的宽度
let flagLength = 15;
//定义不同的坦克AI
let tankAiModel = [
{ v: 6, h: 2, l: 25, inter: 1000, color: 'rgb(255,0,0)', bv: 8 }, //炮弹t毫秒移动一次
{ v: 10, h: 0, l: 15, inter: 1000, color: 'rgb(204,204,204)', bv: 12 },
{ v: 5, h: 0, l: 20, inter: 1000, color: 'rgb(204,204,204)', bv: 7 }
];
//初始化坦克同一时间出现数量
let tankDisplay = 10;
//初始化胜利所需摧毁的坦克数
let wins = 10;
//初始化地图选取
let pic = 0;
//游戏结束声明
let end = false;
//储存坦克AI的数组
let tanksAi = [];
//声明游戏模式
let flagSymbol = false;
//定义道具标签
let randomProp = [{ t: 'T+', c: 'rgb(102,204,204)' }, { t: 'T-', c: 'rgb(0,204,51)' }, { t: 'H+', c: 'rgb(204,102,0)' }, { t: 'V+', c: 'rgb(204,0,204)' }, { t: 'S+', c: 'rgb(102,102,102)' }, { t: 'S-', c: 'rgb(204,153,204)' }];
//定义道具数组
let props = [];
//定义道具边长
let propLength = 15;
//封装通过class获取节点方法
function getElementsByClassName(node, classname) {
if (node.getElementsByClassName) {
return node.getElementsByClassName(classname);
} else {
let results = new Array(),
elems = node.getElementsByTagName('*');
for (let i = 0; i < elems.length; i++)
if (elems[i].className.indexOf(classname) != -1) {
results[results.length] = elems[i];
}
}
return results;
}
window.onload = function() {
clickDisplay();
clickStart();
clickBack();
codeSet();
setMaps();
}
//点击首页显示对应内容
function clickDisplay() {
for (let i = 0, len = home.getElementsByTagName('p').length; i < len; i++) {
(function(i) {
home.getElementsByTagName('p')[i].onclick = function() {
home.style.display = 'none';
document.getElementsByTagName('div')[i + 1].style.display = 'block';
}
})(i);
}
}
//点击开始游戏
function clickStart() {
for (let i = 0, len = getElementsByClassName(document, 'startGame').length; i < len; i++) {
(function(i) {
getElementsByClassName(document, 'startGame')[i].onclick = function() {
this.parentNode.style.display = 'none';
start.style.display = 'block';
gameHandle();
markProp();
tankAiProduce();
if (document.getElementById('modeChoose').getElementsByTagName('input')[1].checked) {
tankDisplay = Math.floor(tankDisplay / 2);
flagSymbol = true;
}
if (document.getElementById('single').checked) {
tanks.splice(1, 1);
}
wins = wins * tanks.length;
getElementsByClassName(document, 'h')[0].innerHTML = 'h:' + tanks[0].h;
getElementsByClassName(document, 'kills')[0].innerHTML = 'kill:' + kill[0];
if (tanks.length > 1) {
getElementsByClassName(document, 'h')[1].innerHTML = 'h:' + tanks[1].h;
getElementsByClassName(document, 'kills')[1].innerHTML = 'kill:' + kill[1];
} else {
getElementsByClassName(document, 'playerData')[1].innerHTML = '';
}
}
})(i);
}
}
//点击返回首页
function clickBack() {
for (let i = 0, len = getElementsByClassName(document, 'back').length; i < len; i++) {
(function(i) {
getElementsByClassName(document, 'back')[i].onclick = function() {
this.parentNode.style.display = 'none';
home.style.display = 'block';
}
})(i);
}
}
//设置按键
function codeSet() {
for (let i = 0, len = document.getElementById('player').getElementsByTagName('input').length; i < len; i++) {
(function(i) {
document.getElementById('player').getElementsByTagName('input')[i].onclick = function() {
getElementsByClassName(set, 'startGame')[0].style.display = 'none';
getElementsByClassName(document, 'setFinish')[0].style.display = 'inline';
for (let j = 0; j < getElementsByClassName(set, 'code').length; j++)
getElementsByClassName(set, 'code')[j].style.borderStyle = 'outset';
this.style.borderStyle = 'inset';
document.onkeydown = function() {
e = event || window.event;
switch (i) {
case 0:
tanks[0].left[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 1:
tanks[0].up[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 2:
tanks[0].right[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 3:
tanks[0].down[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 4:
tanks[0].shot[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 5:
tanks[1].left[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 6:
tanks[1].up[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 7:
tanks[1].right[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 8:
tanks[1].down[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
case 9:
tanks[1].shot[0] = e.keyCode;
document.getElementById('player').getElementsByTagName('input')[i].style.borderStyle = 'outset';
document.onkeydown = null;
break;
default:
;
}
}
}
})(i)
}
getElementsByClassName(document, 'setFinish')[0].onclick = function() {
for (let j = 0; j < getElementsByClassName(set, 'code').length; j++)
getElementsByClassName(set, 'code')[j].style.borderStyle = 'outset';
document.onkeydown = null;
getElementsByClassName(set, 'startGame')[0].style.display = 'inline';
this.style.display = 'none';
}
getElementsByClassName(document, 'setBegin')[0].onclick = function() {
for (let j = 0; j < getElementsByClassName(set, 'code').length; j++)
getElementsByClassName(set, 'code')[j].style.borderStyle = 'outset';
document.onkeydown = null;
getElementsByClassName(set, 'startGame')[0].style.display = 'inline';
getElementsByClassName(document, 'setFinish')[0].style.display = 'none';
tanks[0].up[0] = 38;
tanks[0].left[0] = 39;
tanks[0].down[0] = 40;
tanks[0].left[0] = 37;
tanks[0].shot[0] = 32;
tanks[1].up[0] = 87;
tanks[1].left[0] = 68;
tanks[1].down[0] = 83;
tanks[1].left[0] = 65;
tanks[1].shot[0] = 192;
}
}
//游戏开始
function gameHandle() {
context.cirRct(0, 0, canvas.width, canvas.height, 0, 'rgb(0,0,0)');
woodContrust();
FeContrust();
codeChange();
if (flagSymbol) {
protectContrust();
context.drawFlag((canvas.width + flagLength) / 2, canvas.height - flagLength, flagLength);
}
if (props.length > 0) {
context.drawProp(props[0].x, props[0].y, propLength, props[0].t);
}
for (let i = 0, len = tanks.length; i < len; i++) {
context.drawTank(tanks[i].x, tanks[i].y, tanks[i].l, tanks[i].d, tanks[i].color);
playerTanksMove(i);
}
for (let j = 0, blen = bullets.length; j < blen; j++) {
bulletsMove(bullets[j].belong, bullets[j], bullets[j].d, j, bullets[j].v);
context.drawBullets(bullets[j].x, bullets[j].y, bullets[j].l, bullets[j].color);
}
for (let k = 0, alen = tanksAi.length; k < alen; k++) {
context.drawTank(tanksAi[k].x, tanksAi[k].y, tanksAi[k].l, tanksAi[k].d, tanksAi[k].color);
AIshot(k);
}
if (tanksAi.length > 0)
AImove();
if (AIalive() < tankDisplay)
setTimeout(function() {
tankAiProduce();
}, 200);
if (!end) {
setTimeout(function() {
gameHandle();
}, 40);
} else {
setTimeout(function() {
bullets.length = 0;
tanksAi.length = 0;
}, 1000)
}
while (bullets.length > 500)
bullets.shift();
}
//定义画出圆角矩形的原型方法
CanvasRenderingContext2D.prototype.cirRct = function(x, y, w, l, r, color) {
this.beginPath();
this.moveTo(x + r, y);
this.lineTo(x + w - r, y);
this.arcTo(x + w, y, x + w, y + r, r);
this.lineTo(x + w, y + l - r);
this.arcTo(x + w, y + l, x + w - r, y + l, r);
this.lineTo(x + r, y + l);
this.arcTo(x, y + l, x, y + l - r, r);
this.lineTo(x, y + r);
this.arcTo(x, y, x + r, y, r);
this.fillStyle = color;
this.closePath();
this.fill();
this.stroke();
}
//定义画出坦克的原型方法
CanvasRenderingContext2D.prototype.drawTank = function(x, y, l, d, color) {
let l1 = 0.5 * l,
w1 = 0.2 * l,
l2 = 0.4 * l,
w2 = 0.3 * l,
l3 = 0.2 * l,
w3 = 0.2 * l,
l4 = 0.6 * l,
w4 = 0.3 * l;
let spaceW = l - w2 - 2 * w4;
if (d == 1) { //上
//画出两个车轮
this.cirRct(x + spaceW / 2, y + l - l4, w4, l4, 0, color);
this.cirRct(x + (l + w2) / 2, y + l - l4, w4, l4, 0, color);
//画出炮口
this.cirRct(x + spaceW / 2 + w4 + (w2 - w3) / 2, y, w1, l1, 0, color);
//画出炮身
this.cirRct(x + spaceW / 2 + w4, y + l1, w2, l2, 0, color);
//画出炮舱
this.cirRct(x + spaceW / 2 + w4 + (w2 - w3) / 2, y + l1 + (l2 - l3) / 2, w3, l3, 0, color);
} else if (d == 2) { //右
this.cirRct(x, y + spaceW / 2, l4, w4, 0, color);
this.cirRct(x, y + spaceW / 2 + w2 + w4, l4, w4, 0, color);
this.cirRct(x + l - l1, y + spaceW / 2 + w4, l1, w1, 0, color);
this.cirRct(x + l - l1 - l2, y + spaceW / 2 + w4, l2, w2, 0, color);
this.cirRct(x + l - l1 - (l2 + l3) / 2, y + spaceW / 2 + w4 + (w2 - w3) / 2, l3, w3, 0, color);
} else if (d == 3) { //下
this.cirRct(x + spaceW / 2, y, w4, l4, 0, color);
this.cirRct(x + (l + w2) / 2, y, w4, l4, 0, color);
this.cirRct(x + spaceW / 2 + w4 + (w2 - w3) / 2, y + l - l1, w1, l1, 0, color);
this.cirRct(x + spaceW / 2 + w4, y + l - l1 - l2, w2, l2, 0, color);
this.cirRct(x + spaceW / 2 + w4 + (w2 - w3) / 2, y + l - l1 - (l2 + l3) / 2, w3, l3, 0, color);
} else if (d == 4) { //左
this.cirRct(x + l - l4, y + spaceW / 2, l4, w4, 0, color);
this.cirRct(x + l - l4, y + (l + w2) / 2, l4, w4, 0, color);
this.cirRct(x, y + spaceW / 2 + w4 + (w2 - w3) / 2, l1, w1, 0, color);
this.cirRct(x + l1, y + spaceW / 2 + w4, l2, w2, 0, color);
this.cirRct(x + l1 + (l2 - l3) / 2, y + spaceW / 2 + w4 + (w2 - w3) / 2, l3, w3, 0, color);
}
}
//定义画出旗的方法
CanvasRenderingContext2D.prototype.drawFlag = function(x, y, l) {
this.cirRct(x + l * 0.1, y, l * 0.75, l / 2, 0, 'rgb(255,0,0)');
this.beginPath();
this.moveTo(x + l * 0.1 + 1, y + l / 2);
this.lineTo(x + l * 0.1 + 1, y + l);
this.strokeStyle = 'rgb(255,255,255)';
this.stroke();
this.closePath();
this.strokeStyle = 'rgb(0,0,0)';
}
//画出炮弹
CanvasRenderingContext2D.prototype.drawBullets = function(x, y, l, color) {
this.cirRct(x, y, l, l, 0, color);
}
//画出道具
CanvasRenderingContext2D.prototype.drawProp = function(x, y, l, index) {
this.cirRct(x, y, l, l, 1, randomProp[index].c);
this.fillStyle = 'rgb(0,0,0)'; //设置字体颜色
this.textAlign = 'center';
this.textBaseline = 'middle';
this.font = '8px Adobe Ming Std';
this.fillText(randomProp[index].t, x + l / 2, y + l / 2);
}
//标记道具
function markProp() {
setTimeout(function() {
let randomx = Math.floor(Math.random() * (520 - propLength)),
randomy = Math.floor(Math.random() * (520 - propLength)),
randomt = Math.floor(Math.random() * randomProp.length);
props[props.length] = { x: randomx, y: randomy, t: randomt };
setTimeout(function() { props.length = 0 }, 5000);
markProp();
}, 8000);
}
//建筑木块
function woodContrust() {
for (let i = 0, len = woods[pic].length; i < len; i++) {
context.cirRct(woods[pic][i].x * woodLength, woods[pic][i].y * woodLength, woodLength, woodLength, 0, 'rgb(255,204,51)');
}
}
//建筑铁块
function FeContrust() {
for (let i = 0, len = Fes[pic].length; i < len; i++) {
context.cirRct(Fes[pic][i].x * Felength, Fes[pic][i].y * Felength, Felength, Felength, 0, 'rgb(102,102,102)');
}
}
//加建筑保护层
function protectContrust() {
for (let i = 0, len = protects.length; i < len; i++) {
context.cirRct(protects[i].x * woodLength, protects[i].y * woodLength, woodLength, woodLength, 0, 'rgb(255,204,51)');
}
}
//判断是否超出容器
function outOfcContainer(x, y, l, vx, vy, width, height) { //物体的x,y坐标,边长,速度,容器宽高
if ((x + vx < 0) || (x + l + vx > width))
return true;
else if ((y + vy < 0) || (y + l + vy > height))
return true;
else
return false;
}
//道具生效
function propsApply(index) {
if (props[0].t == 0) {
if (tanks[index].l <= 40) {
tanks[index].l += 5;
}
} else if (props[0].t == 1) {
if (tanks[index].l >= 15) {
tanks[index].l -= 5;
}
} else if (props[0].t == 2) {
if (tanks[index].h <= 4) {
tanks[index].h++;
if (getElementsByClassName(document, 'h').length > 1)
getElementsByClassName(document, 'h')[index].innerHTML = 'h:' + tanks[index].h;
else
getElementsByClassName(document, 'h')[index].innerHTML = 'h:' + tanks[0].h;
}
} else if (props[0].t == 3) {
if (tanks[index].v <= 8)
tanks[index].v++;
} else if (props[0].t == 4) {
if (tanks[index].bv < 12)
tanks[index].bv++;
} else if (props[0].t == 5) {
if (tanks[index].inter >= 300)
tanks[index].inter -= 50;
}
}
//玩家坦克的移动
function playerTanksMove(i) {
if (tanks[i].up[1] == true) {
tanks[i].d = 1;
tanksMove(i, 0, -1, 'player');
} else if (tanks[i].right[1] == true) {
tanks[i].d = 2;
tanksMove(i, 1, 0, 'player');
} else if (tanks[i].down[1] == true) {
tanks[i].d = 3;
tanksMove(i, 0, 1, 'player');
} else if (tanks[i].left[1] == true) {
tanks[i].d = 4;
tanksMove(i, -1, 0, 'player');
}
if ((tanks[i].shot[1] == true) && (tanks[i].i < 1)) {
tanks[i].i = 1;
shotInterval(i, tanks);
bullets[bullets.length] = { x: tanks[i].x + tanks[i].l * 3 / 8, y: tanks[i].y + tanks[i].l * 3 / 8, l: tanks[i].l / 4, v: tanks[i].bv, color: 'rgb(255,0,0)', belong: i + 1, d: tanks[i].d };
if (tanks[i].d == 1) {
bullets[bullets.length - 1].y = tanks[i].y - tanks[i].l / 4;
} else if (tanks[i].d == 2) {
bullets[bullets.length - 1].x = tanks[i].x + tanks[i].l;
} else if (tanks[i].d == 3) {
bullets[bullets.length - 1].y = tanks[i].y + tanks[i].l;
} else if (tanks[i].d == 4) {
bullets[bullets.length - 1].x = tanks[i].x - tanks[i].l / 4;
}
}
}
//射击间隔
function shotInterval(i, tank) {
setTimeout(function() {
if (tank[i])
tank[i].i--;
}, tank[i].inter);
}
//按键按下对应改变按键状态
function codeChange() {
document.onkeydown = function() {
let e = event || window.event;
for (let i = 0; i < tanks.length; i++) {
(function(i) {
if (e.keyCode == tanks[i].left[0]) {
codeReset(i);
tanks[i].left[1] = true;
} else if (e.keyCode == tanks[i].up[0]) {
codeReset(i);
tanks[i].up[1] = true;
} else if (e.keyCode == tanks[i].right[0]) {
codeReset(i);
tanks[i].right[1] = true;
} else if (e.keyCode == tanks[i].down[0]) {
codeReset(i);
tanks[i].down[1] = true;
}
if ((e.keyCode == tanks[i].shot[0]) && (tanks[i].i == 0)) {
tanks[i].shot[1] = true;
}
})(i);
}
}
document.onkeyup = function() {
let e = event || window.event;
for (let i = 0; i < tanks.length; i++) {
(function(i) {
if (e.keyCode == tanks[i].left[0]) {
tanks[i].left[1] = false;
} else if (e.keyCode == tanks[i].up[0]) {
tanks[i].up[1] = false;
} else if (e.keyCode == tanks[i].right[0]) {
tanks[i].right[1] = false;
} else if (e.keyCode == tanks[i].down[0]) {
tanks[i].down[1] = false;
}
if (e.keyCode == tanks[i].shot[0]) {
tanks[i].shot[1] = false;
}
})(i);
}
}
}
//重置按钮状态
function codeReset(i) {
tanks[i].up[1] = false;
tanks[i].right[1] = false;
tanks[i].left[1] = false;
tanks[i].down[1] = false;
}
//AI坦克的移动
function AImove() {
let Rd = Math.floor(Math.random() * 4) + 1;
let tanksAiX, tanksAiY;
for (let i = 0, len = tanksAi.length; i < len; i++) {
if (tanksAi[i].x < canvas.width) {
tanksAiX = tanksAi[i].x;
tanksAiY = tanksAi[i].y;
if (tanksAi[i].d == 1) {
tanksMove(i, 0, -1, 'AI');
if ((tanksAiX == tanksAi[i].x) && (tanksAiY == tanksAi[i].y))
tanksAi[i].d = Rd;
} else if (tanksAi[i].d == 2) {
tanksMove(i, 1, 0, 'AI');
if ((tanksAiX == tanksAi[i].x) && (tanksAiY == tanksAi[i].y))
tanksAi[i].d = Rd;
} else if (tanksAi[i].d == 3) {
tanksMove(i, 0, 1, 'AI');
if ((tanksAiX == tanksAi[i].x) && (tanksAiY == tanksAi[i].y))
tanksAi[i].d = Rd;
} else if (tanksAi[i].d == 4) {
tanksMove(i, -1, 0, 'AI');
if ((tanksAiX == tanksAi[i].x) && (tanksAiY == tanksAi[i].y))
tanksAi[i].d = Rd;
}
}
}
}
//AI坦克射击
function AIshot(i) {
if (tanksAi[i].i == 0) {
tanksAi[i].i = 1;
shotInterval(i, tanksAi);
bullets[bullets.length] = { x: tanksAi[i].x + tanksAi[i].l * 3 / 8, y: tanksAi[i].y + tanksAi[i].l * 3 / 8, l: tanksAi[i].l / 4, v: tanksAi[i].bv, color: 'rgb(255,0,0)', belong: 0, d: tanksAi[i].d };
if (tanksAi[i].d == 1) {
bullets[bullets.length - 1].y = tanksAi[i].y - tanksAi[i].l / 4;
} else if (tanksAi[i].d == 2) {
bullets[bullets.length - 1].x = tanksAi[i].x + tanksAi[i].l;
} else if (tanksAi[i].d == 3) {
bullets[bullets.length - 1].y = tanksAi[i].y + tanksAi[i].l;
} else if (tanksAi[i].d == 4) {
bullets[bullets.length - 1].x = tanksAi[i].x - tanksAi[i].l / 4;
}
}
}
//坦克的移动
function tanksMove(i, dx, dy, type) {
if (type == 'AI') {
tanksAi[i].x += tanksAi[i].v * dx;
tanksAi[i].y += tanksAi[i].v * dy;
for (let j = 0, len = tanksAi.length; j < len; j++) {
if ((i != j) && (judgeCrash(tanksAi[i].x, tanksAi[i].y, tanksAi[i].l, tanksAi[j].x, tanksAi[j].y, tanksAi[j].l))) {
tanksAi[i].x -= tanksAi[i].v * dx;
tanksAi[i].y -= tanksAi[i].v * dy;
break;
}
}
for (let w = 0, wlen = woods[pic].length; w < wlen; w++) {
if (judgeCrash(tanksAi[i].x, tanksAi[i].y, tanksAi[i].l, woods[pic][w].x * woodLength, woods[pic][w].y * woodLength, woodLength)) {
tanksAi[i].x -= tanksAi[i].v * dx;
tanksAi[i].y -= tanksAi[i].v * dy;
break;
}
}
for (let f = 0, flen = Fes[pic].length; f < flen; f++) {
if (judgeCrash(tanksAi[i].x, tanksAi[i].y, tanksAi[i].l, Fes[pic][f].x * Felength, Fes[pic][f].y * Felength, Felength)) {
tanksAi[i].x -= tanksAi[i].v * dx;
tanksAi[i].y -= tanksAi[i].v * dy;
break;
}
}
for (let p = 0, plen = tanks.length; p < plen; p++) {
if (judgeCrash(tanksAi[i].x, tanksAi[i].y, tanksAi[i].l, tanks[p].x, tanks[p].y, tanks[p].l)) {
tanksAi[i].x -= tanksAi[i].v * dx;
tanksAi[i].y -= tanksAi[i].v * dy;
break;
}
}
if (flagSymbol) {
for (let pr = 0, prlen = protects.length; pr < prlen; pr++) {
if (judgeCrash(tanksAi[i].x, tanksAi[i].y, tanksAi[i].l, protects[pr].x * woodLength, protects[pr].y * woodLength, woodLength)) {
tanksAi[i].x -= tanksAi[i].v * dx;
tanksAi[i].y -= tanksAi[i].v * dy;
break;
}
}
}
if ((tanksAi[i].x < 0) || (tanksAi[i].x + tanksAi[i].l > canvas.width) || (tanksAi[i].y < 0) || (tanksAi[i].y + tanksAi[i].l > canvas.height)) {
tanksAi[i].x -= tanksAi[i].v * dx;
tanksAi[i].y -= tanksAi[i].v * dy;
}
} else {
tanks[i].x += (tanks[i].v * dx);
tanks[i].y += (tanks[i].v * dy);
for (let j = 0, len = tanksAi.length; j < len; j++) {
if (judgeCrash(tanks[i].x, tanks[i].y, tanks[i].l, tanksAi[j].x, tanksAi[j].y, tanksAi[j].l)) {
tanks[i].x -= (tanks[i].v * dx);
tanks[i].y -= (tanks[i].v * dy);
break;
}
}
for (let w = 0, wlen = woods[pic].length; w < wlen; w++) {
if (judgeCrash(tanks[i].x, tanks[i].y, tanks[i].l, woods[pic][w].x * woodLength, woods[pic][w].y * woodLength, woodLength)) {
tanks[i].x -= (tanks[i].v * dx);
tanks[i].y -= (tanks[i].v * dy);
break;
}
}
for (let f = 0, flen = Fes[pic].length; f < flen; f++) {
if (judgeCrash(tanks[i].x, tanks[i].y, tanks[i].l, Fes[pic][f].x * Felength, Fes[pic][f].y * Felength, Felength)) {
tanks[i].x -= (tanks[i].v * dx);
tanks[i].y -= (tanks[i].v * dy);
break;
}
}
if (props.length > 0) {
if (judgeCrash(tanks[i].x, tanks[i].y, tanks[i].l, props[0].x, props[0].y, propLength)) {
propsApply(i);
props.length = 0;
}
}
if (flagSymbol) {
for (let pr = 0, prlen = protects.length; pr < prlen; pr++) {
if (judgeCrash(tanks[i].x, tanks[i].y, tanks[i].l, protects[pr].x * woodLength, protects[pr].y * woodLength, woodLength)) {
tanks[i].x -= tanks[i].v * dx;
tanks[i].y -= tanks[i].v * dy;
break;
}
}
}
if ((tanks[i].x < 0) || (tanks[i].x + tanks[i].l > canvas.width) || (tanks[i].y < 0) || (tanks[i].y + tanks[i].l > canvas.height)) {
tanks[i].x -= tanks[i].v * dx;
tanks[i].y -= tanks[i].v * dy;
}
}
}
//判断两物体是否碰撞
function judgeCrash(x1, y1, l1, x2, y2, l2) {
if (l1 > l2) {
if ((x2 >= x1) && (x2 <= x1 + l1) && (y2 >= y1) && (y2 <= y1 + l1))
return true;
else if ((x2 + l2 >= x1) && (x2 + l2 <= x1 + l1) && (y2 >= y1) && (y2 <= y1 + l1))
return true;
else if ((x2 >= x1) && (x2 <= x1 + l1) && (y2 + l2 >= y1) && (y2 + l2 <= y1 + l1))
return true;
else if ((x2 + l2 >= x1) && (x2 + l2 <= x1 + l1) && (y2 + l2 >= y1) && (y2 + l2 <= y1 + l1))
return true;
} else {
if ((x1 >= x2) && (x1 <= x2 + l2) && (y1 >= y2) && (y1 <= y2 + l2))
return true;
else if ((x1 + l1 >= x2) && (x1 + l1 <= x2 + l2) && (y1 >= y2) && (y1 <= y2 + l2))
return true;
else if ((x1 >= x2) && (x1 <= x2 + l2) && (y1 + l1 >= y2) && (y1 + l1 <= y2 + l2))
return true;
else if ((x1 + l1 >= x2) && (x1 + l1 <= x2 + l2) && (y1 + l1 >= y2) && (y1 + l1 <= y2 + l2))
return true;
}
return false;
}
//炮弹的移动
function bulletsMove(belong, bullet, d, index, v) { //炮弹所属,要移动的炮弹,炮弹在x,y正方向上的移动,(0:不移动,1:向正方向移动,-1:向反方向移动),炮弹的索引
if (d == 1)
bullet.y -= v;
else if (d == 2)
bullet.x += v;
else if (d == 3)
bullet.y += v;
else if (d == 4)
bullet.x -= v;
if (bullet.belong != 0) {
for (let t = 0, tlen = tanksAi.length; t < tlen; t++) {
if (judgeCrash(bullet.x, bullet.y, bullet.l, tanksAi[t].x, tanksAi[t].y, tanksAi[t].l)) {
bullet.x = 0 - bullet.l;
bullet.y = 0 - bullet.l;
tanksAi[t].h--;
switch (tanksAi[t].h) {
case 0:
tanksAi[t].color = 'rgb(204,204,204)';
break;
case 1:
tanksAi[t].color = 'rgb(153,51,51)';
break;
default:
;
}
if (tanksAi[t].h < 0) {
kill[bullet.belong - 1]++;
kills++;
tanksAi[t].l = 0;
tanksAi[t].x = canvas.width + t;
if (getElementsByClassName(document, 'kills').length > 1)
getElementsByClassName(document, 'kills')[bullet.belong - 1].innerHTML = 'kills:' + kill[bullet.belong - 1];
else
getElementsByClassName(document, 'kills')[0].innerHTML = 'kills:' + kill[bullet.belong - 1];
}
if (kills >= wins) {
alert('you win');
alert('player1:' + kill[0] + '\nplayer2:' + kill[1]);
end = true;
kills = 0;
}
break;
}
}
} else if (bullet.belong == 0) {
for (let p = 0, plen = tanks.length; p < plen; p++) {
if (judgeCrash(bullet.x, bullet.y, bullet.l, tanks[p].x, tanks[p].y, tanks[p].l)) {
bullet.x = -bullet.l;
bullet.y = -bullet.l;
tanks[p].h--;
tanks[p].x = tanksPosition[p].x;
tanks[p].y = tanksPosition[p].y;
if (getElementsByClassName(document, 'h').length > 1)
getElementsByClassName(document, 'h')[p].innerHTML = 'h:' + tanks[p].h;
else
getElementsByClassName(document, 'h')[0].innerHTML = 'h:' + tanks[p].h;
if (tanks[p].h < 0) {
tanks.splice(p, 1);
getElementsByClassName(document, 'playerData')[p].innerHTML = 'player' + (p + 1) + ': game over';
}
if (tanks.length == 0) {
alert('game over');
end = true;
}
break;
}
}
}
for (let b = 0, blen = bullets.length; b < blen; b++) {
if (index != b) {
if (judgeCrash(bullet.x, bullet.y, bullet.l, bullets[b].x, bullets[b].y, bullets[b].l)) {
bullet.x = -bullet.l;
bullets[b].x = canvas.width + bullets[b].l + b;
bullet.y = -bullet.l;
bullets[b].y = canvas.height + bullets[b].l + b;
break;
}
}
}
for (let w = 0, wlen = woods[pic].length; w < wlen; w++) {
if (judgeCrash(bullet.x, bullet.y, bullet.l, woods[pic][w].x * woodLength, woods[pic][w].y * woodLength, woodLength)) {
bullet.x = -bullet.l;
bullet.y = -bullet.l;
woods[pic].splice(w, 1);
break;
}
}
for (let f = 0, flen = Fes[pic].length; f < flen; f++) {
if (judgeCrash(bullet.x, bullet.y, bullet.l, Fes[pic][f].x * Felength, Fes[pic][f].y * Felength, Felength)) {
bullet.x = -bullet.l;
bullet.y = -bullet.l;
break;
}
}
if (flagSymbol) {
for (let pr = 0, prlen = protects.length; pr < prlen; pr++) {
if (judgeCrash(bullet.x, bullet.y, bullet.l, protects[pr].x * woodLength, protects[pr].y * woodLength, woodLength)) {
bullet.x = -bullet.l;
bullet.y = -bullet.l;
protects.splice(pr, 1);
break;
}
}
if (judgeCrash(bullet.x, bullet.y, bullet.l, (canvas.width + flagLength) / 2, canvas.height - flagLength, flagLength)) {
bullet.x = -bullet.l;
bullet.y = -bullet.l;
alert('game over');
end = true;
}
}
}
//生成AI坦克
function tankAiProduce() {
let Rform = Math.floor(Math.random() * tankAiModel.length),
Rd = Math.floor(Math.random() * 4) + 1,
Rx = Math.floor(Math.random() * canvas.width);
if (Rx > canvas.width - tankAiModel[Rform].l)
Rx = canvas.width - tankAiModel[Rform].l;
while (judgeRepeat(Rx, Rform)) {
Rx = (Math.random() * canvas.width);
if (Rx > canvas.width - tankAiModel[Rform].l)
Rx = canvas.width - tankAiModel[Rform].l;
}
tanksAi[tanksAi.length] = { x: Rx, y: 0, i: 0, v: tankAiModel[Rform].v, h: tankAiModel[Rform].h, inter: tankAiModel[Rform].inter, bv: tankAiModel[Rform].bv, d: Rd, l: tankAiModel[Rform].l, color: tankAiModel[Rform].color };
}
//判断随机数出现是否重叠
function judgeRepeat(x, r) {
for (let i = 0, len = tanksAi.length; i < len; i++) {
if (judgeCrash(x, 0, tankAiModel[r].l, tanksAi[i].x, tanksAi[i].y, tanksAi[i].l))
return true; //重叠
}
return false;
}
//计算剩余存活的坦克数量
function AIalive() {
let a = 0;
for (let i = 0, len = tanksAi.length; i < len; i++) {
if (tanksAi[i].h >= 0)
a++;
}
return a;
}
//创建小地图
function setMaps() {
let txt = document.createTextNode('当前浏览器不支持canvas,请换取较高级浏览器尝试该游戏');
let canvasArray = [];
let contextArray = [];
for (let i = 0; i < woods.length; i++) {
canvasArray[i] = document.createElement('canvas');
canvasArray[i].appendChild(txt);
picCh.getElementsByTagName('p')[0].appendChild(canvasArray[i]);
canvasArray[i].width = 104;
canvasArray[i].height = 104;
contextArray[i] = canvasArray[i].getContext('2d');
contextArray[i].cirRct(0, 0, canvasArray[i].width, canvasArray[i].height, 0, 'rgb(0,0,0,0.8)');
for (let j = 0; j < woods[i].length; j++) {
contextArray[i].cirRct(woods[i][j].x * 2, woods[i][j].y * 2, 2, 2, 0, 'rgb(255,204,51)');
}
for (let k = 0; k < Fes[i].length; k++) {
contextArray[i].cirRct(Fes[i][k].x * 2, Fes[i][k].y * 2, 2, 2, 0, 'rgb(102,102,102)');
}
}
//点击更换地图
for (let i = 0; i < document.getElementById('picCh').getElementsByTagName('canvas').length; i++) {
(function(i) {
document.getElementById('picCh').getElementsByTagName('canvas')[i].onclick = function() {
pic = i;
for (let j = 0; j < document.getElementById('picCh').getElementsByTagName('canvas').length; j++) {
document.getElementById('picCh').getElementsByTagName('canvas')[j].style.filter = 'brightness(100%)';
document.getElementById('picCh').getElementsByTagName('canvas')[j].style.border = 'none';
}
this.style.border = '2px solid rgb(255,0,0)';
this.style.filter = 'brightness(200%)';
}
})(i)
}
}