<!DOCTYPE html>
<html>
<head><title>Advanced Tank War with Ally</title><style>canvas { border: 1px solid black; }#info { position: absolute; left: 620px; top: 10px; width: 200px; }</style>
</head>
<body><canvas id="gameCanvas" width="800" height="600"></canvas><div id="info"></div><script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const INFO_HTML = `
<h3>操作说明</h3>
方向键:移动<br>
空格:射击(冷却时间)<br>
鼠标:瞄准<br>
<h3>单位类型</h3>
绿色:玩家坦克<br>
蓝色:友方AI坦克<br>
浅红:普通敌人<br>
深红:重型敌人<br>
最红:精英敌人(会拦截射击)`;let gameState = {player: {x: 400, y: 300, size: 30, color: '#0f0',speed: 5, hp: 10, angle: 0,fireCooldown: 0, fireCooldownTime: 20},ally: {x: 200, y: 200, size: 30, color: '#00f',speed: 4, hp: 3, angle: 0,fireCooldown: 0, fireCooldownTime: 10,target: null, state: 'patrol', patrolTimer: 0},enemies: [],bullets: [],level: 1,aimAngle: {x: 400, y: 300},gameOver: false,totalEnemies: 0,escapedEnemies: 0
};function initGame() {alert(INFO_HTML);generateEnemies();
}function generateEnemies() {const count = gameState.level * 3 + 2;gameState.totalEnemies = count;gameState.escapedEnemies = 0;for (let i = 0; i < count; i++) {const red = 150 + Math.random() * 105;const type = red > 240 ? 'elite' : red > 180 ? 'heavy' : 'normal';gameState.enemies.push({x: -50,y: Math.random() * 550 + 25,size: 30,color: `rgb(${red},0,0)`,speed: type === 'elite' ? 1.5 : 3 - (red-150)/50,hp: Math.ceil((red-150)/35),angle: 0,targetAngle: 0,type: type,fireCooldown: 0});}
}function checkCollision(rect1, rect2) {return rect1.x < rect2.x + rect2.size &&rect1.x + rect1.size > rect2.x &&rect1.y < rect2.y + rect2.size &&rect1.y + rect1.size > rect2.y;
}function gameLoop() {if (gameState.gameOver) return;ctx.clearRect(0, 0, canvas.width, canvas.height);updateGame();drawPlayer();drawAlly();drawEnemies();drawBullets();drawAim();drawUI();requestAnimationFrame(gameLoop);
}function updateGame() {// 更新友方AIupdateAlly();// 更新敌人状态for (let i = gameState.enemies.length - 1; i >= 0; i--) {const enemy = gameState.enemies[i];// 精英坦克逻辑if (enemy.type === 'elite') {const targetX = gameState.player.x + 300;const targetY = gameState.player.y;if (enemy.x < targetX - 50) {enemy.x += enemy.speed * 1.2;} else {// 瞄准射击const dx = gameState.player.x - enemy.x;const dy = gameState.player.y - enemy.y;enemy.targetAngle = Math.atan2(dy, dx);if (enemy.fireCooldown <= 0) {gameState.bullets.push({x: enemy.x + 15,y: enemy.y + 15,angle: enemy.targetAngle,size: 6,isEnemy: true});enemy.fireCooldown = 80;} else {enemy.fireCooldown--;}}} else {enemy.x += enemy.speed;}// 逃逸检测if (enemy.x > 800) {gameState.escapedEnemies++;gameState.enemies.splice(i, 1);}}// 更新子弹for (let i = gameState.bullets.length - 1; i >= 0; i--) {const bullet = gameState.bullets[i];bullet.x += Math.cos(bullet.angle) * 10;bullet.y += Math.sin(bullet.angle) * 10;// 边界检测if (bullet.x < 0 || bullet.x > 800 || bullet.y < 0 || bullet.y > 600) {gameState.bullets.splice(i, 1);continue;}// 碰撞检测if (bullet.isEnemy) {if (checkCollision(bullet, gameState.player)) {gameState.player.hp--;gameState.bullets.splice(i, 1);if (gameState.player.hp <= 0) gameOver(false);} else if (checkCollision(bullet, gameState.ally)) {gameState.ally.hp--;gameState.bullets.splice(i, 1);if (gameState.ally.hp <= 0) {alert("友军坦克被摧毁!");gameState.ally.hp = 3; // 友军重生}}} else {for (let j = gameState.enemies.length - 1; j >= 0; j--) {if (checkCollision(bullet, gameState.enemies[j])) {gameState.enemies[j].hp--;if (gameState.enemies[j].hp <= 0) {gameState.enemies.splice(j, 1);}gameState.bullets.splice(i, 1);break;}}}}// 关卡状态检测if (gameState.escapedEnemies > gameState.totalEnemies * 0.5) {alert(`超过50%敌人逃脱!关卡${gameState.level}失败!`);generateEnemies();return;}if (gameState.enemies.length === 0) {gameState.level++;if (gameState.level > 3) {gameOver(true);return;}generateEnemies();}// 更新玩家冷却if (gameState.player.fireCooldown > 0) {gameState.player.fireCooldown--;}
}function updateAlly() {const ally = gameState.ally;// 优先寻找重型或精英坦克if (!ally.target || ally.target.hp <= 0 || ally.patrolTimer > 90) {ally.target = findPriorityTarget();ally.patrolTimer = 0;}if (ally.target) {// 攻击模式const dx = ally.target.x - ally.x;const dy = ally.target.y - ally.y;const dist = Math.sqrt(dx*dx + dy*dy);// 动态移动策略if (dist > 250) {// 快速接近目标ally.x += (dx/dist) * ally.speed * 1.2;ally.y += (dy/dist) * ally.speed * 1.2;} else if (dist < 150) {// 保持安全距离ally.x -= (dx/dist) * ally.speed * 0.8;ally.y -= (dy/dist) * ally.speed * 0.8;} else {// 侧向移动避免直线冲锋const sideMove = Math.sin(Date.now()/500) * 50;ally.x += (dy/dist) * sideMove * 0.1;ally.y -= (dx/dist) * sideMove * 0.1;}// 瞄准射击ally.angle = Math.atan2(dy, dx);if (ally.fireCooldown <= 0 && dist < 300) {gameState.bullets.push({x: ally.x + 15,y: ally.y + 15,angle: ally.angle,size: 6,isEnemy: false});ally.fireCooldown = ally.fireCooldownTime;}} else {// 没有目标时的巡逻行为ally.patrolTimer++;if (ally.patrolTimer > 120) {ally.x += (Math.random() - 0.5) * 50;ally.y += (Math.random() - 0.5) * 50;ally.patrolTimer = 0;}// 向玩家靠拢但保持一定距离const px = gameState.player.x - ally.x;const py = gameState.player.y - ally.y;const pDist = Math.sqrt(px*px + py*py);if (pDist > 200) {ally.x += (px/pDist) * ally.speed * 0.5;ally.y += (py/pDist) * ally.speed * 0.5;}}// 边界检查ally.x = Math.max(0, Math.min(770, ally.x));ally.y = Math.max(0, Math.min(570, ally.y));// 冷却更新if (ally.fireCooldown > 0) {ally.fireCooldown--;}
}// 寻找优先目标(重型/精英坦克)
function findPriorityTarget() {let priorityTarget = null;let minDist = Infinity;gameState.enemies.forEach(enemy => {// 优先选择重型或精英坦克if (enemy.type === 'heavy' || enemy.type === 'elite') {const dist = Math.sqrt(Math.pow(enemy.x - gameState.ally.x, 2) + Math.pow(enemy.y - gameState.ally.y, 2));if (dist < minDist) {minDist = dist;priorityTarget = enemy;}}});// 如果没有优先目标,选择最近的普通坦克if (!priorityTarget && gameState.enemies.length > 0) {gameState.enemies.forEach(enemy => {const dist = Math.sqrt(Math.pow(enemy.x - gameState.ally.x, 2) + Math.pow(enemy.y - gameState.ally.y, 2));if (dist < minDist) {minDist = dist;priorityTarget = enemy;}});}return priorityTarget;
}function gameOver(isWin) {gameState.gameOver = true;alert(isWin ? "最终胜利!" : "游戏失败!");location.reload();
}function drawPlayer() {drawTank(gameState.player);
}function drawAlly() {drawTank(gameState.ally);// 绘制友军状态指示器ctx.fillStyle = gameState.ally.state === 'attack' ? '#f00' : '#0a0';ctx.beginPath();ctx.arc(gameState.ally.x + 15, gameState.ally.y - 10, 5, 0, Math.PI*2);ctx.fill();
}function drawEnemies() {gameState.enemies.forEach(enemy => {drawTank(enemy);if (enemy.type === 'elite') {ctx.beginPath();ctx.arc(enemy.x+15, enemy.y+15, 40, 0, Math.PI*2);ctx.strokeStyle = 'rgba(255,0,0,0.3)';ctx.stroke();}});
}function drawTank(tank) {ctx.save();ctx.translate(tank.x + tank.size/2, tank.y + tank.size/2);ctx.rotate(tank.angle);ctx.fillStyle = tank.color;ctx.fillRect(-tank.size/2, -tank.size/2, tank.size, tank.size);ctx.strokeStyle = '#333';ctx.lineWidth = 4;ctx.beginPath();ctx.moveTo(0, 0);ctx.lineTo(tank.size/2, 0);ctx.stroke();ctx.restore();
}function drawBullets() {ctx.fillStyle = '#000';gameState.bullets.forEach(bullet => {ctx.beginPath();ctx.arc(bullet.x, bullet.y, 3, 0, Math.PI*2);ctx.fill();});
}function drawAim() {ctx.strokeStyle = '#f00';ctx.beginPath();ctx.arc(gameState.aimAngle.x, gameState.aimAngle.y, 10, 0, Math.PI*2);ctx.stroke();
}function drawUI() {const cdPercent = (gameState.player.fireCooldown / gameState.player.fireCooldownTime) * 100;document.getElementById('info').innerHTML = `关卡:${gameState.level}<br>玩家HP:${gameState.player.hp}<br>友军HP:${gameState.ally.hp}<br>逃脱敌人:${gameState.escapedEnemies}/${gameState.totalEnemies}<div style="background:#ddd; width:100px; height:10px"><div style="background:#f00; width:${cdPercent}%; height:10px"></div></div>`;
}document.addEventListener('keydown', (e) => {const p = gameState.player;if (e.key === 'ArrowUp') p.y = Math.max(0, p.y - p.speed);if (e.key === 'ArrowDown') p.y = Math.min(570, p.y + p.speed);if (e.key === 'ArrowLeft') p.x = Math.max(0, p.x - p.speed);if (e.key === 'ArrowRight') p.x = Math.min(770, p.x + p.speed);if (e.code === 'Space' && p.fireCooldown <= 0) {const angle = Math.atan2(gameState.aimAngle.y - p.y -15,gameState.aimAngle.x - p.x -15);gameState.bullets.push({x: p.x + 15, y: p.y + 15, angle, size: 6});p.fireCooldown = p.fireCooldownTime;}
});canvas.addEventListener('mousemove', (e) => {const rect = canvas.getBoundingClientRect();gameState.aimAngle.x = e.clientX - rect.left;gameState.aimAngle.y = e.clientY - rect.top;
});initGame();
gameLoop();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Advanced Tank War with Ally</title>
<style>
canvas { border: 1px solid black; }
#info { position: absolute; left: 620px; top: 10px; width: 200px; }
</style>
</head>
<body>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div id="info"></div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const INFO_HTML = `
<h3>操作说明</h3>
方向键:移动<br>
空格:射击(冷却时间)<br>
鼠标:瞄准<br>
<h3>单位类型</h3>
绿色:玩家坦克<br>
蓝色:友方AI坦克<br>
浅红:普通敌人<br>
深红:重型敌人<br>
最红:精英敌人(会拦截射击)`;
let gameState = {
player: {
x: 400, y: 300, size: 30, color: '#0f0',
speed: 5, hp: 10, angle: 0,
fireCooldown: 0, fireCooldownTime: 20
},
ally: {
x: 200, y: 200, size: 30, color: '#00f',
speed: 4, hp: 3, angle: 0,
fireCooldown: 0, fireCooldownTime: 10,
target: null, state: 'patrol', patrolTimer: 0
},
enemies: [],
bullets: [],
level: 1,
aimAngle: {x: 400, y: 300},
gameOver: false,
totalEnemies: 0,
escapedEnemies: 0
};
function initGame() {
alert(INFO_HTML);
generateEnemies();
}
function generateEnemies() {
const count = gameState.level * 3 + 2;
gameState.totalEnemies = count;
gameState.escapedEnemies = 0;
for (let i = 0; i < count; i++) {
const red = 150 + Math.random() * 105;
const type = red > 240 ? 'elite' : red > 180 ? 'heavy' : 'normal';
gameState.enemies.push({
x: -50,
y: Math.random() * 550 + 25,
size: 30,
color: `rgb(${red},0,0)`,
speed: type === 'elite' ? 1.5 : 3 - (red-150)/50,
hp: Math.ceil((red-150)/35),
angle: 0,
targetAngle: 0,
type: type,
fireCooldown: 0
});
}
}
function checkCollision(rect1, rect2) {
return rect1.x < rect2.x + rect2.size &&
rect1.x + rect1.size > rect2.x &&
rect1.y < rect2.y + rect2.size &&
rect1.y + rect1.size > rect2.y;
}
function gameLoop() {
if (gameState.gameOver) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
updateGame();
drawPlayer();
drawAlly();
drawEnemies();
drawBullets();
drawAim();
drawUI();
requestAnimationFrame(gameLoop);
}
function updateGame() {
// 更新友方AI
updateAlly();
// 更新敌人状态
for (let i = gameState.enemies.length - 1; i >= 0; i--) {
const enemy = gameState.enemies[i];
// 精英坦克逻辑
if (enemy.type === 'elite') {
const targetX = gameState.player.x + 300;
const targetY = gameState.player.y;
if (enemy.x < targetX - 50) {
enemy.x += enemy.speed * 1.2;
} else {
// 瞄准射击
const dx = gameState.player.x - enemy.x;
const dy = gameState.player.y - enemy.y;
enemy.targetAngle = Math.atan2(dy, dx);
if (enemy.fireCooldown <= 0) {
gameState.bullets.push({
x: enemy.x + 15,
y: enemy.y + 15,
angle: enemy.targetAngle,
size: 6,
isEnemy: true
});
enemy.fireCooldown = 80;
} else {
enemy.fireCooldown--;
}
}
} else {
enemy.x += enemy.speed;
}
// 逃逸检测
if (enemy.x > 800) {
gameState.escapedEnemies++;
gameState.enemies.splice(i, 1);
}
}
// 更新子弹
for (let i = gameState.bullets.length - 1; i >= 0; i--) {
const bullet = gameState.bullets[i];
bullet.x += Math.cos(bullet.angle) * 10;
bullet.y += Math.sin(bullet.angle) * 10;
// 边界检测
if (bullet.x < 0 || bullet.x > 800 || bullet.y < 0 || bullet.y > 600) {
gameState.bullets.splice(i, 1);
continue;
}
// 碰撞检测
if (bullet.isEnemy) {
if (checkCollision(bullet, gameState.player)) {
gameState.player.hp--;
gameState.bullets.splice(i, 1);
if (gameState.player.hp <= 0) gameOver(false);
} else if (checkCollision(bullet, gameState.ally)) {
gameState.ally.hp--;
gameState.bullets.splice(i, 1);
if (gameState.ally.hp <= 0) {
alert("友军坦克被摧毁!");
gameState.ally.hp = 3; // 友军重生
}
}
} else {
for (let j = gameState.enemies.length - 1; j >= 0; j--) {
if (checkCollision(bullet, gameState.enemies[j])) {
gameState.enemies[j].hp--;
if (gameState.enemies[j].hp <= 0) {
gameState.enemies.splice(j, 1);
}
gameState.bullets.splice(i, 1);
break;
}
}
}
}
// 关卡状态检测
if (gameState.escapedEnemies > gameState.totalEnemies * 0.5) {
alert(`超过50%敌人逃脱!关卡${gameState.level}失败!`);
generateEnemies();
return;
}
if (gameState.enemies.length === 0) {
gameState.level++;
if (gameState.level > 3) {
gameOver(true);
return;
}
generateEnemies();
}
// 更新玩家冷却
if (gameState.player.fireCooldown > 0) {
gameState.player.fireCooldown--;
}
}
function updateAlly() {
const ally = gameState.ally;
// 优先寻找重型或精英坦克
if (!ally.target || ally.target.hp <= 0 || ally.patrolTimer > 90) {
ally.target = findPriorityTarget();
ally.patrolTimer = 0;
}
if (ally.target) {
// 攻击模式
const dx = ally.target.x - ally.x;
const dy = ally.target.y - ally.y;
const dist = Math.sqrt(dx*dx + dy*dy);
// 动态移动策略
if (dist > 250) {
// 快速接近目标
ally.x += (dx/dist) * ally.speed * 1.2;
ally.y += (dy/dist) * ally.speed * 1.2;
} else if (dist < 150) {
// 保持安全距离
ally.x -= (dx/dist) * ally.speed * 0.8;
ally.y -= (dy/dist) * ally.speed * 0.8;
} else {
// 侧向移动避免直线冲锋
const sideMove = Math.sin(Date.now()/500) * 50;
ally.x += (dy/dist) * sideMove * 0.1;
ally.y -= (dx/dist) * sideMove * 0.1;
}
// 瞄准射击
ally.angle = Math.atan2(dy, dx);
if (ally.fireCooldown <= 0 && dist < 300) {
gameState.bullets.push({
x: ally.x + 15,
y: ally.y + 15,
angle: ally.angle,
size: 6,
isEnemy: false
});
ally.fireCooldown = ally.fireCooldownTime;
}
} else {
// 没有目标时的巡逻行为
ally.patrolTimer++;
if (ally.patrolTimer > 120) {
ally.x += (Math.random() - 0.5) * 50;
ally.y += (Math.random() - 0.5) * 50;
ally.patrolTimer = 0;
}
// 向玩家靠拢但保持一定距离
const px = gameState.player.x - ally.x;
const py = gameState.player.y - ally.y;
const pDist = Math.sqrt(px*px + py*py);
if (pDist > 200) {
ally.x += (px/pDist) * ally.speed * 0.5;
ally.y += (py/pDist) * ally.speed * 0.5;
}
}
// 边界检查
ally.x = Math.max(0, Math.min(770, ally.x));
ally.y = Math.max(0, Math.min(570, ally.y));
// 冷却更新
if (ally.fireCooldown > 0) {
ally.fireCooldown--;
}
}
// 寻找优先目标(重型/精英坦克)
function findPriorityTarget() {
let priorityTarget = null;
let minDist = Infinity;
gameState.enemies.forEach(enemy => {
// 优先选择重型或精英坦克
if (enemy.type === 'heavy' || enemy.type === 'elite') {
const dist = Math.sqrt(
Math.pow(enemy.x - gameState.ally.x, 2) +
Math.pow(enemy.y - gameState.ally.y, 2)
);
if (dist < minDist) {
minDist = dist;
priorityTarget = enemy;
}
}
});
// 如果没有优先目标,选择最近的普通坦克
if (!priorityTarget && gameState.enemies.length > 0) {
gameState.enemies.forEach(enemy => {
const dist = Math.sqrt(
Math.pow(enemy.x - gameState.ally.x, 2) +
Math.pow(enemy.y - gameState.ally.y, 2)
);
if (dist < minDist) {
minDist = dist;
priorityTarget = enemy;
}
});
}
return priorityTarget;
}
function gameOver(isWin) {
gameState.gameOver = true;
alert(isWin ? "最终胜利!" : "游戏失败!");
location.reload();
}
function drawPlayer() {
drawTank(gameState.player);
}
function drawAlly() {
drawTank(gameState.ally);
// 绘制友军状态指示器
ctx.fillStyle = gameState.ally.state === 'attack' ? '#f00' : '#0a0';
ctx.beginPath();
ctx.arc(gameState.ally.x + 15, gameState.ally.y - 10, 5, 0, Math.PI*2);
ctx.fill();
}
function drawEnemies() {
gameState.enemies.forEach(enemy => {
drawTank(enemy);
if (enemy.type === 'elite') {
ctx.beginPath();
ctx.arc(enemy.x+15, enemy.y+15, 40, 0, Math.PI*2);
ctx.strokeStyle = 'rgba(255,0,0,0.3)';
ctx.stroke();
}
});
}
function drawTank(tank) {
ctx.save();
ctx.translate(tank.x + tank.size/2, tank.y + tank.size/2);
ctx.rotate(tank.angle);
ctx.fillStyle = tank.color;
ctx.fillRect(-tank.size/2, -tank.size/2, tank.size, tank.size);
ctx.strokeStyle = '#333';
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(tank.size/2, 0);
ctx.stroke();
ctx.restore();
}
function drawBullets() {
ctx.fillStyle = '#000';
gameState.bullets.forEach(bullet => {
ctx.beginPath();
ctx.arc(bullet.x, bullet.y, 3, 0, Math.PI*2);
ctx.fill();
});
}
function drawAim() {
ctx.strokeStyle = '#f00';
ctx.beginPath();
ctx.arc(gameState.aimAngle.x, gameState.aimAngle.y, 10, 0, Math.PI*2);
ctx.stroke();
}
function drawUI() {
const cdPercent = (gameState.player.fireCooldown / gameState.player.fireCooldownTime) * 100;
document.getElementById('info').innerHTML = `
关卡:${gameState.level}<br>
玩家HP:${gameState.player.hp}<br>
友军HP:${gameState.ally.hp}<br>
逃脱敌人:${gameState.escapedEnemies}/${gameState.totalEnemies}
<div style="background:#ddd; width:100px; height:10px">
<div style="background:#f00; width:${cdPercent}%; height:10px"></div>
</div>`;
}
document.addEventListener('keydown', (e) => {
const p = gameState.player;
if (e.key === 'ArrowUp') p.y = Math.max(0, p.y - p.speed);
if (e.key === 'ArrowDown') p.y = Math.min(570, p.y + p.speed);
if (e.key === 'ArrowLeft') p.x = Math.max(0, p.x - p.speed);
if (e.key === 'ArrowRight') p.x = Math.min(770, p.x + p.speed);
if (e.code === 'Space' && p.fireCooldown <= 0) {
const angle = Math.atan2(
gameState.aimAngle.y - p.y -15,
gameState.aimAngle.x - p.x -15
);
gameState.bullets.push({
x: p.x + 15, y: p.y + 15, angle, size: 6
});
p.fireCooldown = p.fireCooldownTime;
}
});
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
gameState.aimAngle.x = e.clientX - rect.left;
gameState.aimAngle.y = e.clientY - rect.top;
});
initGame();
gameLoop();
</script>
</body>
</html>