AI-坦克像素大战
script dog · v1.0.0 · 独立窗口 · 7 次安装
简介
长按方向键移动,空格发射子弹
匹配网址
*://*/*
脚本源码
// 创建游戏容器
const gameContainer = document.createElement('div');
gameContainer.style.width = '400px';
gameContainer.style.height = '400px';
gameContainer.style.backgroundColor = '#000';
gameContainer.style.position = 'relative';
gameContainer.style.margin = '0 auto';
gameContainer.style.overflow = 'hidden';
document.body.appendChild(gameContainer);
// 游戏常量
const GRID_SIZE = 20;
const GAME_WIDTH = 400;
const GAME_HEIGHT = 400;
const TANK_SPEED = 2;
const BULLET_SPEED = 5;
const AI_UPDATE_INTERVAL = 1000;
// 游戏对象
const game = {
player: null,
enemies: [],
bullets: [],
walls: [],
gameOver: false,
score: 0,
lastAITime: 0
};
// 坦克类
class Tank {
constructor(x, y, color, isPlayer = false) {
this.x = x;
this.y = y;
this.width = GRID_SIZE;
this.height = GRID_SIZE;
this.color = color;
this.direction = isPlayer ? 'up' : 'down'; // 玩家默认向上,敌人默认向下
this.isPlayer = isPlayer;
this.speed = TANK_SPEED;
this.cooldown = 0;
this.element = document.createElement('div');
this.updateElement();
gameContainer.appendChild(this.element);
}
updateElement() {
this.element.style.position = 'absolute';
this.element.style.left = `${this.x}px`;
this.element.style.top = `${this.y}px`;
this.element.style.width = `${this.width}px`;
this.element.style.height = `${this.height}px`;
this.element.style.backgroundColor = this.color;
}
move(direction) {
if (this.direction !== direction) {
this.direction = direction;
return;
}
let newX = this.x;
let newY = this.y;
switch (direction) {
case 'up':
newY = Math.max(0, this.y - this.speed);
break;
case 'down':
newY = Math.min(GAME_HEIGHT - this.height, this.y + this.speed);
break;
case 'left':
newX = Math.max(0, this.x - this.speed);
break;
case 'right':
newX = Math.min(GAME_WIDTH - this.width, this.x + this.speed);
break;
}
if (!this.checkCollision(newX, newY)) {
this.x = newX;
this.y = newY;
this.updateElement();
}
}
checkCollision(x, y) {
// 边界检查
if (x < 0 || x + this.width > GAME_WIDTH || y < 0 || y + this.height > GAME_HEIGHT) {
return true;
}
// 墙壁碰撞检查
for (const wall of game.walls) {
if (
x < wall.x + wall.width &&
x + this.width > wall.x &&
y < wall.y + wall.height &&
y + this.height > wall.y
) {
return true;
}
}
// 坦克碰撞检查
const tanks = this.isPlayer ? game.enemies : [game.player];
for (const tank of tanks) {
if (tank &&
x < tank.x + tank.width &&
x + this.width > tank.x &&
y < tank.y + tank.height &&
y + this.height > tank.y
) {
return true;
}
}
return false;
}
fire() {
if (this.cooldown > 0) return;
let bulletX, bulletY;
switch (this.direction) {
case 'up':
bulletX = this.x + this.width / 2 - 2;
bulletY = this.y - 4;
break;
case 'down':
bulletX = this.x + this.width / 2 - 2;
bulletY = this.y + this.height;
break;
case 'left':
bulletX = this.x - 4;
bulletY = this.y + this.height / 2 - 2;
break;
case 'right':
bulletX = this.x + this.width;
bulletY = this.y + this.height / 2 - 2;
break;
}
game.bullets.push(new Bullet(bulletX, bulletY, this.direction, this.isPlayer));
this.cooldown = 20;
}
update() {
if (this.cooldown > 0) {
this.cooldown--;
}
}
destroy() {
gameContainer.removeChild(this.element);
if (this.isPlayer) {
game.player = null;
game.gameOver = true;
} else {
game.enemies = game.enemies.filter(enemy => enemy !== this);
game.score += 100;
}
}
}
// 子弹类
class Bullet {
constructor(x, y, direction, isPlayer) {
this.x = x;
this.y = y;
this.width = 4;
this.height = 4;
this.direction = direction;
this.speed = BULLET_SPEED;
this.isPlayer = isPlayer;
this.element = document.createElement('div');
this.updateElement();
gameContainer.appendChild(this.element);
}
updateElement() {
this.element.style.position = 'absolute';
this.element.style.left = `${this.x}px`;
this.element.style.top = `${this.y}px`;
this.element.style.width = `${this.width}px`;
this.element.style.height = `${this.height}px`;
this.element.style.backgroundColor = this.isPlayer ? '#0f0' : '#f00';
}
update() {
switch (this.direction) {
case 'up':
this.y -= this.speed;
break;
case 'down':
this.y += this.speed;
break;
case 'left':
this.x -= this.speed;
break;
case 'right':
this.x += this.speed;
break;
}
this.updateElement();
// 检查是否超出边界
if (
this.x < 0 ||
this.x > GAME_WIDTH ||
this.y < 0 ||
this.y > GAME_HEIGHT
) {
this.destroy();
return;
}
// 检查碰撞
this.checkCollision();
}
checkCollision() {
// 检查墙壁碰撞
for (const wall of game.walls) {
if (
this.x < wall.x + wall.width &&
this.x + this.width > wall.x &&
this.y < wall.y + wall.height &&
this.y + this.height > wall.y
) {
this.destroy();
return;
}
}
// 检查坦克碰撞
const tanks = this.isPlayer ? game.enemies : [game.player];
for (const tank of tanks) {
if (tank &&
this.x < tank.x + tank.width &&
this.x + this.width > tank.x &&
this.y < tank.y + tank.height &&
this.y + this.height > tank.y
) {
tank.destroy();
this.destroy();
return;
}
}
// 检查子弹碰撞
for (const bullet of game.bullets) {
if (bullet !== this &&
bullet.isPlayer !== this.isPlayer &&
this.x < bullet.x + bullet.width &&
this.x + this.width > bullet.x &&
this.y < bullet.y + bullet.height &&
this.y + this.height > bullet.y
) {
bullet.destroy();
this.destroy();
return;
}
}
}
destroy() {
gameContainer.removeChild(this.element);
game.bullets = game.bullets.filter(bullet => bullet !== this);
}
}
// 墙壁类
class Wall {
constructor(x, y) {
this.x = x;
this.y = y;
this.width = GRID_SIZE;
this.height = GRID_SIZE;
this.element = document.createElement('div');
this.element.style.position = 'absolute';
this.element.style.left = `${x}px`;
this.element.style.top = `${y}px`;
this.element.style.width = `${this.width}px`;
this.element.style.height = `${this.height}px`;
this.element.style.backgroundColor = '#888';
gameContainer.appendChild(this.element);
}
}
// 初始化游戏
function initGame() {
// 清除所有元素
while (gameContainer.firstChild) {
gameContainer.removeChild(gameContainer.firstChild);
}
// 重置游戏状态
game.player = null;
game.enemies = [];
game.bullets = [];
game.walls = [];
game.gameOver = false;
game.score = 0;
game.lastAITime = 0;
// 创建玩家坦克
game.player = new Tank(
GAME_WIDTH / 2 - GRID_SIZE / 2,
GAME_HEIGHT - GRID_SIZE * 2,
'#0f0',
true
);
// 创建敌人坦克
for (let i = 0; i < 3; i++) {
game.enemies.push(
new Tank(
GRID_SIZE * 2 + i * GRID_SIZE * 4,
GRID_SIZE,
'#f00'
)
);
}
// 创建墙壁
for (let i = 0; i < 10; i++) {
const x = Math.floor(Math.random() * (GAME_WIDTH / GRID_SIZE)) * GRID_SIZE;
const y = Math.floor(Math.random() * (GAME_HEIGHT / GRID_SIZE)) * GRID_SIZE;
// 确保墙壁不会生成在玩家或敌人初始位置
if (
!(x === game.player.x && y === game.player.y) &&
!game.enemies.some(enemy => enemy.x === x && enemy.y === y)
) {
game.walls.push(new Wall(x, y));
}
}
// 创建分数显示
const scoreElement = document.createElement('div');
scoreElement.style.position = 'absolute';
scoreElement.style.top = '10px';
scoreElement.style.left = '10px';
scoreElement.style.color = '#fff';
scoreElement.style.fontFamily = 'Arial';
scoreElement.style.fontSize = '16px';
scoreElement.id = 'score';
gameContainer.appendChild(scoreElement);
updateScore();
// 添加键盘监听
document.addEventListener('keydown', handleKeyDown);
}
// 更新分数显示
function updateScore() {
const scoreElement = document.getElementById('score');
if (scoreElement) {
scoreElement.textContent = `Score: ${game.score}`;
}
}
// 键盘控制
function handleKeyDown(e) {
if (game.gameOver || !game.player) return;
switch (e.key) {
case 'ArrowUp':
game.player.move('up');
break;
case 'ArrowDown':
game.player.move('down');
break;
case 'ArrowLeft':
game.player.move('left');
break;
case 'ArrowRight':
game.player.move('right');
break;
case ' ':
game.player.fire();
break;
}
}
// AI控制
function updateAI() {
const now = Date.now();
if (now - game.lastAITime < AI_UPDATE_INTERVAL) return;
game.lastAITime = now;
for (const enemy of game.enemies) {
// 随机移动或开火
const action = Math.floor(Math.random() * 5);
switch (action) {
case 0:
enemy.move('up');
break;
case 1:
enemy.move('down');
break;
case 2:
enemy.move('left');
break;
case 3:
enemy.move('right');
break;
case 4:
enemy.fire();
break;
}
}
}
// 游戏循环
function gameLoop() {
if (game.gameOver) {
// 游戏结束显示
const gameOverElement = document.createElement('div');
gameOverElement.style.position = 'absolute';
gameOverElement.style.top = '50%';
gameOverElement.style.left = '50%';
gameOverElement.style.transform = 'translate(-50%, -50%)';
gameOverElement.style.color = '#fff';
gameOverElement.style.fontFamily = 'Arial';
gameOverElement.style.fontSize = '24px';
gameOverElement.textContent = `Game Over! Score: ${game.score}`;
gameContainer.appendChild(gameOverElement);
const restartButton = document.createElement('button');
restartButton.textContent = 'Restart';
restartButton.style.marginTop = '20px';
restartButton.style.padding = '10px 20px';
restartButton.addEventListener('click', initGame);
gameOverElement.appendChild(restartButton);
return;
}
// 更新AI
updateAI();
// 更新所有坦克
if (game.player) game.player.update();
for (const enemy of game.enemies) {
enemy.update();
}
// 更新所有子弹
for (const bullet of game.bullets) {
bullet.update();
}
// 检查游戏状态
if (game.enemies.length === 0) {
// 所有敌人都被消灭,生成新的敌人
for (let i = 0; i < 3; i++) {
game.enemies.push(
new Tank(
GRID_SIZE * 2 + i * GRID_SIZE * 4,
GRID_SIZE,
'#f00'
)
);
}
}
// 更新分数
updateScore();
// 继续游戏循环
requestAnimationFrame(gameLoop);
}
// 开始游戏
initGame();
gameLoop();