canvas+js实现坦克大战多模式版

html坦克游戏,HTML5+JS实现坦克大战小游戏 听了韩顺平老师的视频教程,学到了不少编程思想,原来看似简单的坦克大战小游戏写起来其实并不简单。这里总结一下这几天学到的东西。首先是关于html5的知识了。这里我们基本上只用了画布canvas来画坦克,还有就是html5的第一行来说明这是一个使用html5写的页面,html5的特性之一就包括canvas,这是html中没有的标签。另外一个就是js了,涉及到的语法都是最简单、最基本的用法,这在代码中进... 阅读详情

之前上传的坦克大战因为改来改去没完整上传导致出了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>道具&nbsp;&nbsp;T+:坦克变大&nbsp;T-:坦克变小&nbsp;H+:生命加一&nbsp;V+:坦克速度变快&nbsp;S+:炮弹速度变快&nbsp;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)
    }
}
使用Canvas实现坦克大战游戏开发全解析 Canvas作为HTML5的核心绘图技术,通过JavaScript API实现动态2D图形渲染,是网页游戏开发的利器。其基于像素的渲染机制相比传统DOM操作具有更高性能,特别适合需要频繁重绘的游戏场景。本文以经典坦克大战为例,详细讲解如何利用Canvas实现游戏主循环、对象碰撞检测、AI行为控制等核心模块。通过分层渲染、对象池等优化技巧,开发者可以构建流畅的2D游戏体验。该案例展示了前端三件套(HTML+CSS+JavaScript)与现代浏览器API结合的游戏开发范式,为网页游戏开发提供实践参考。 阅读详情

相关推荐

JavaScript面向对象实现-坦克大战(附前端全套学习路线)

【课程简介】使用javascript+面向对象实现一个坦克大战游戏,让更多的同学能更加深入地理解面向对象思想。文末附有前端全套学习路线。【主讲内容】1. 讲解什么是面向对象,javascript中如何实现面向对象2. 分析坦克大战中需要用到哪些对象3. 使用canvas实现游戏地图的绘制4. 使用canvas实现坦克的绘制5. 如何使用键盘控制坦克移动6. 如何生成敌对的坦克7. 如何使用寻路算法让敌人寻找玩家的坦克...

weixin_51689029的博客 1832

利用js轻松实现坦克大战小游戏

利用js轻松实现坦克大战小游戏

weixin_44856221的博客 846

复刻经典:HTML+CSS+JavaScript打造双人坦克游戏

本文还有配套的精品资源,点击获取 简介:本文介绍了如何利用HTML、CSS和JavaScript技术实现一个复刻经典小霸王游戏——坦克大战的Web版本,并且加入了双人模式。文章详细阐述了游戏开发的核心技术,包括使用HTML构建游戏界面元素,CSS设计视觉效果,以及JavaScript处理游戏逻辑、双人模式同步、游戏对象状态管理、事件处理、布局与碰撞检测、动画帧率控制和数据持...

weixin_35762258的博客 1348

JS坦克大战游戏

JS实现坦克大战

weixin_62061392的博客 7955

JavaScript版坦克大战游戏开发深度解析

本文还有配套的精品资源,点击获取 简介:《JS版坦克大战》是利用JavaScript语言开发的一款在线坦克战斗游戏。该游戏以经典的坦克战斗场景为背景,引入了多样化的地形元素和多达18辆敌方坦克,为玩家提供了丰富的战略选择。文章详细介绍了开发这款游戏所需的多个技术要点,包括HTML5 Canvas绘图、JavaScript基础语法、对象与类的使用、事件处理、动画框架、碰撞检测...

weixin_27645199的博客 1704

HTML5 canvas实现坦克大战小游戏

Web Audio API为网页游戏提供了强大的音频处理能力。它允许开发者控制音频上下文、节点、音源、效果器等。通过Web Audio API可以实现高质量的音频输出,包括混音、淡入淡出、空间音效等。使用Web Audio API的基本流程包括:创建音频上下文(加载音频资源(创建音频源()并连接到目标。控制音频源的播放(如开始、结束播放、循环播放等)。应用效果器(如混响、失真、均衡器等)。

weixin_42513928的博客 985

【Three.js】web版 3D坦克大战

制作动态图的软件付费的,所以比较模糊,后续会陆续更新开发思路……

饺子大魔王 4794

JavaScript实现网页版疯狂坦克大战游戏完整源码项目

JavaScript自ES6起正式引入了class语法糖,使得开发者可以用更接近传统OOP语言的方式组织代码。以下是一个典型的Tank类定义示例:this.x = x;this.y = y;break;break;break;// 绘制炮管逻辑逐行解读与参数说明:初始化坦克的位置 (xy)、尺寸 (widthheight)、移动速度 (speed) 和朝向 (

weixin_42355400的博客 1188

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

听了韩顺平老师的视频教程,学到了

基督山伯爵的博客 1万+

JS坦克大战,内附源码

JS坦克大战,可双人配合娱乐,酷似红白机FC原始版的坦克大战

纯JS实现坦克大战

纯JS编写的坦克大战Html文件

用canvas,javascript制作“坦克大战“小游戏

...

zhulong16的博客 1481

js写的坦克大战 源码 可以运行

一个很牛逼的js写的坦克大战,里面有全部的素材和清晰的文档,经过本人的测试,可以完美运行,对于做前端的同学的学习有很大的帮助!欢迎大家下载!

js+jq实现坦克大战

之前为了练习canvas写了个贪吃蛇,逻辑控制和计算过程实现起来也很简单,都说canvas很6,这次决定用它来实现一个坦克大战,但真实的坦克大战等级很多,估计建设坦克地图就能把人累死,如果封装的好一些,还可以省些精力,写个步骤,慢慢来! 一.坦克体积和基地分布区种类场景 1.坦克体积   - 我的坦克体积控制在40x40,画了个坦克原型欣赏一下   - 左翼履带和右翼履带分别是三个10x10绿色方...

Vic's blog 1117

js实现坦克大战 javascript

js实现坦克大战按方向键移动坦克,按空格键发炮

js实现坦克大战游戏

本文实例为大家分享了js实现坦克大战游戏的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html> <head> <title>tank</title> <style type="text/css"> body { margin: 0px; padding: 0px; border: 0px; } .map { position: absolute; top: 30px; width: 390px; height: 390px; left: 50%; margin-left: -200px; border: 9

使用jquery—Canvas实现html5小游戏——《坦克大战》

目录 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...

weixin_42032770的博客 1924

浅谈车联网概述-1

车联网技术目前在车企中应用广泛,车联网通过车载传感器、无线通信等技术,能够将车辆上百的传感器数据上传至云端,当前智能网联车辆可以理解为一个“大号”手机。

Hello, World! 新能源汽车智能网联工程师,分享日常工作思考。 560

用html语言做坦克大战

我的博客 给大家揭秘一下坦克大战是怎么做的吧,只有一部分!!看到文章底下!! 1、把这段代码复制到index.html中; 坦克大战主界面 body{ background:#cce8cf; margin-top: 5%; } $(function(){ var i=0; //用于判断音乐符号的标志 $("#music").c

只是个菜鸡 4039

2025.06.20【pacbio】|PB甲基化分析结果的统计与可视化介绍

本文介绍了PacBio甲基化数据的统计分析与可视化方法。主要内容包括:1) 分析甲基化位点分布、比例及染色体分布;2) 修饰基序(Motif)的统计与热图展示;3) 全基因组和局部区域测序深度可视化;4) 使用IGV查看单个reads修饰情况。文章提供了R代码示例,涵盖柱状图、分布图、热图等多种可视化形式,并建议了差异甲基化分析等进阶方法,帮助科研人员深入挖掘甲基化数据。

2067

读书笔记:深度学习入门-基于python的理论与实现(俗称鱼书)

终于从头到尾把鱼书看完啦,真的是非常入门,非常查漏补缺,对新手很友好,对有一定基础的人也非常不错。看完不复习等于没看,所以今天开始复盘,顺便写这篇读书笔记。希望分享给没看过这本书或者看过这本书的同僚们参考,欢迎大家指教。我将从第三章神经网络开始复习,前两章内容书里已经非常基础and清楚了。(会持续更新滴).........

博客而已 1万+
上一篇: LeetCode 79.单词搜索 Java实现
下一篇: typescript基础知识(三)类
前端小黑
博客等级 码龄9年 148粉丝 222原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值