<!DOCTYPE html>
<html>
<head>
<title>太空射击游戏</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
font-family: Arial, sans-serif;
}
canvas {
border: 2px solid #00ffff;
background-color: #000;
}
#gameInfo {
position: absolute;
top: 10px;
left: 10px;
color: white;
font-size: 18px;
}
#startScreen {
position: absolute;
color: white;
text-align: center;
z-index: 10;
}
button {
background-color: #00ffff;
color: #000;
border: none;
padding: 10px 20px;
font-size: 18px;
cursor: pointer;
border-radius: 5px;
}
button:hover {
background-color: #00cccc;
}
</style>
</head>
<body>
<div id="startScreen">
<h1>太空射击游戏</h1>
<p>使用 ← → 移动飞船,空格键射击</p>
<button onclick="startGame()">开始游戏</button>
</div>
<div id="gameInfo">得分: <span id="score">0</span> | 生命: <span id="lives">3</span></div>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script>
// 游戏变量
let canvas = document.getElementById('gameCanvas');
let ctx = canvas.getContext('2d');
let scoreElement = document.getElementById('score');
let livesElement = document.getElementById('lives');
let startScreen = document.getElementById('startScreen');
// 游戏状态
let gameRunning = false;
let score = 0;
let lives = 3;
// 玩家飞船
let player = {
x: canvas.width / 2 - 25,
y: canvas.height - 60,
width: 50,
height: 40,
speed: 7,
color: '#00ffff'
};
// 子弹数组
let bullets = [];
let bulletSpeed = 10;
// 敌人数组
let enemies = [];
let enemySpeed = 2;
let enemySpawnRate = 60; // 每60帧生成一个敌人
let frameCount = 0;
// 飞行器数组
let particles = [];
// 键盘状态
let keys = {};
// 添加粒子效果
function addParticle(x, y, color, size) {
particles.push({
x: x,
y: y,
size: Math.random() * size + 2,
speedX: (Math.random() - 0.5) * 4,
speedY: (Math.random() - 0.5) * 4,
color: color,
life: 30
});
}
// 创建敌人
function createEnemy() {
enemies.push({
x: Math.random() * (canvas.width - 40),
y: -40,
width: 40,
height: 40,
color: '#ff0000'
});
}
// 更新玩家位置
function updatePlayer() {
if (keys['ArrowLeft'] && player.x > 0) {
player.x -= player.speed;
}
if (keys['ArrowRight'] && player.x < canvas.width - player.width) {
player.x += player.speed;
}
}
// 更新子弹
function updateBullets() {
for (let i = bullets.length - 1; i >= 0; i--) {
bullets[i].y -= bulletSpeed;
// 移除超出屏幕的子弹
if (bullets[i].y < 0) {
bullets.splice(i, 1);
}
}
}
// 更新敌人
function updateEnemies() {
for (let i = enemies.length - 1; i >= 0; i--) {
enemies[i].y += enemySpeed;
// 移除超出屏幕的敌人
if (enemies[i].y > canvas.height) {
enemies.splice(i, 1);
lives--;
livesElement.textContent = lives;
if (lives <= 0) {
gameOver();
}
}
}
}
// 更新粒子效果
function updateParticles() {
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].x += particles[i].speedX;
particles[i].y += particles[i].speedY;
particles[i].life--;
if (particles[i].life <= 0) {
particles.splice(i, 1);
}
}
}
// 射击函数
function shoot() {
bullets.push({
x: player.x + player.width / 2 - 3,
y: player.y,
width: 6,
height: 15,
color: '#ffff00'
});
}
// 碰撞检测
function checkCollisions() {
// 子弹与敌人的碰撞
for (let i = bullets.length - 1; i >= 0; i--) {
for (let j = enemies.length - 1; j >= 0; j--) {
if (bullets[i] && enemies[j] &&
bullets[i].x < enemies[j].x + enemies[j].width &&
bullets[i].x + bullets[i].width > enemies[j].x &&
bullets[i].y < enemies[j].y + enemies[j].height &&
bullets[i].y + bullets[i].height > enemies[j].y) {
// 碰撞效果
for (let k = 0; k < 10; k++) {
addParticle(enemies[j].x + enemies[j].width/2,
enemies[j].y + enemies[j].height/2,
'#ff0000', 3);
}
// 删除子弹和敌人
bullets.splice(i, 1);
enemies.splice(j, 1);
// 增加分数
score += 100;
scoreElement.textContent = score;
break;
}
}
}
// 敌人与玩家的碰撞
for (let i = enemies.length - 1; i >= 0; i--) {
if (player.x < enemies[i].x + enemies[i].width &&
player.x + player.width > enemies[i].x &&
player.y < enemies[i].y + enemies[i].height &&
player.y + player.height > enemies[i].y) {
// 碰撞效果
for (let k = 0; k < 20; k++) {
addParticle(player.x + player.width/2,
player.y + player.height/2,
'#00ffff', 5);
}
// 删除敌人
enemies.splice(i, 1);
// 生命减少
lives--;
livesElement.textContent = lives;
if (lives <= 0) {
gameOver();
}
break;
}
}
}
// 游戏主循环
function gameLoop() {
if (!gameRunning) return;
// 清除画布
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 更新游戏状态
updatePlayer();
updateBullets();
updateEnemies();
updateParticles();
// 生成敌人
frameCount++;
if (frameCount % enemySpawnRate === 0) {
createEnemy();
}
// 碰撞检测
checkCollisions();
// 绘制玩家飞船
ctx.fillStyle = player.color;
ctx.beginPath();
ctx.moveTo(player.x, player.y + player.height);
ctx.lineTo(player.x + player.width, player.y + player.height);
ctx.lineTo(player.x + player.width/2, player.y);
ctx.closePath();
ctx.fill();
// 绘制飞船细节
ctx.fillStyle = '#0088ff';
ctx.fillRect(player.x + 15, player.y + player.height - 10, 20, 10);
ctx.fillRect(player.x + 18, player.y + player.height - 20, 14, 10);
// 绘制子弹
ctx.fillStyle = '#ffff00';
for (let i = 0; i < bullets.length; i++) {
ctx.fillRect(bullets[i].x, bullets[i].y, bullets[i].width, bullets[i].height);
}
// 绘制敌人
ctx.fillStyle = '#ff0000';
for (let i = 0; i < enemies.length; i++) {
ctx.beginPath();
ctx.arc(enemies[i].x + enemies[i].width/2, enemies[i].y + enemies[i].height/2,
enemies[i].width/2 - 5, 0, Math.PI * 2);
ctx.fill();
// 添加敌机细节
ctx.fillStyle = '#ff6666';
ctx.fillRect(enemies[i].x + 10, enemies[i].y + 10, 20, 10);
}
// 绘制粒子效果
for (let i = 0; i < particles.length; i++) {
ctx.fillStyle = particles[i].color;
ctx.globalAlpha = particles[i].life / 30;
ctx.fillRect(particles[i].x, particles[i].y, particles[i].size, particles[i].size);
ctx.globalAlpha = 1;
}
// 请求下一帧
requestAnimationFrame(gameLoop);
}
// 开始游戏
function startGame() {
gameRunning = true;
startScreen.style.display = 'none';
score = 0;
lives = 3;
scoreElement.textContent = score;
livesElement.textContent = lives;
// 重置游戏对象
bullets = [];
enemies = [];
particles = [];
frameCount = 0;
// 重置玩家位置
player.x = canvas.width / 2 - 25;
// 开始游戏循环
gameLoop();
}
// 游戏结束
function gameOver() {
gameRunning = false;
alert(`游戏结束! 最终得分: ${score}`);
startScreen.style.display = 'block';
}
// 键盘事件监听
window.addEventListener('keydown', (e) => {
keys[e.key] = true;
// 射击
if (e.key === ' ' && gameRunning) {
e.preventDefault();
shoot();
}
});
window.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
// 初始背景
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
</script>
</body>
</html>
index.html