坦克大战HTML网页游戏 (永久免费)

发布于:2025-04-15 ⋅ 阅读:(25) ⋅ 点赞:(0)
<!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>

<!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>