- BC20280055's blog
射击游戏
- @ 2025-11-21 18:14:44
太空射击游戏
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
}
.game-container {
position: relative;
width: 800px;
height: 600px;
background: rgba(0, 0, 0, 0.7);
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
overflow: hidden;
}
#gameCanvas {
background: #000;
display: block;
}
.game-ui {
position: absolute;
top: 20px;
left: 20px;
font-size: 18px;
z-index: 10;
}
.controls {
margin-top: 20px;
text-align: center;
background: rgba(0, 0, 0, 0.5);
padding: 15px;
border-radius: 10px;
width: 800px;
}
button {
background: linear-gradient(to bottom, #ff8a00, #da1b60);
border: none;
color: white;
padding: 12px 25px;
font-size: 18px;
border-radius: 30px;
cursor: pointer;
margin: 0 10px;
transition: all 0.3s;
box-shadow: 0 0 15px rgba(255, 0, 128, 0.5);
}
button:hover {
transform: scale(1.05);
box-shadow: 0 0 20px rgba(255, 0, 128, 0.8);
}
.game-over {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 20;
display: none;
}
.game-over h2 {
font-size: 48px;
color: #ff0055;
margin-bottom: 20px;
text-shadow: 0 0 10px #ff0055;
}
.game-over p {
font-size: 24px;
margin-bottom: 30px;
}
.instructions {
margin-top: 20px;
background: rgba(0, 0, 0, 0.5);
padding: 15px;
border-radius: 10px;
width: 800px;
}
.instructions h3 {
color: #00ffff;
margin-bottom: 10px;
}
.instructions p {
margin: 5px 0;
}
.power-ups {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.power-up {
display: flex;
align-items: center;
margin: 0 10px;
}
.power-up-icon {
width: 20px;
height: 20px;
border-radius: 50%;
margin-right: 5px;
}
.shield {
background: #00ffff;
box-shadow: 0 0 10px #00ffff;
}
.rapid-fire {
background: #ff0055;
box-shadow: 0 0 10px #ff0055;
}
.health {
background: #00ff00;
box-shadow: 0 0 10px #00ff00;
}
</style>
太空射击游戏
<div class="game-container">
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div class="game-ui">
<div>分数: <span id="score">0</span></div>
<div>生命值: <span id="health">100</span></div>
<div>等级: <span id="level">1</span></div>
</div>
<div class="game-over" id="gameOver">
<h2>游戏结束!</h2>
<p>你的最终得分: <span id="finalScore">0</span></p>
<button id="restartButton">重新开始</button>
</div>
</div>
<div class="controls">
<button id="startButton">开始游戏</button>
<button id="pauseButton">暂停游戏</button>
</div>
<div class="instructions">
<h3>游戏说明</h3>
<p>使用 <strong>A/D 或 左/右箭头</strong> 移动飞船</p>
<p>使用 <strong>空格键</strong> 发射激光</p>
<p>躲避陨石和敌机,尽可能获得高分!</p>
<div class="power-ups">
<div class="power-up">
<div class="power-up-icon shield"></div>
<span>护盾 - 暂时无敌</span>
</div>
<div class="power-up">
<div class="power-up-icon rapid-fire"></div>
<span>快速射击 - 提高射速</span>
</div>
<div class="power-up">
<div class="power-up-icon health"></div>
<span>生命值 - 恢复生命</span>
</div>
</div>
</div>
<script>
// 获取Canvas和上下文
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 游戏状态
let gameRunning = false;
let gamePaused = false;
let score = 0;
let health = 100;
let level = 1;
// 玩家飞船
const player = {
x: canvas.width / 2 - 25,
y: canvas.height - 80,
width: 50,
height: 60,
speed: 8,
color: '#00aaff',
lasers: [],
lastShot: 0,
shootDelay: 300, // 射击延迟(毫秒)
shieldActive: false,
shieldTime: 0,
rapidFireActive: false,
rapidFireTime: 0
};
// 敌机和陨石
let enemies = [];
let asteroids = [];
let powerUps = [];
// 按键状态
const keys = {
ArrowLeft: false,
ArrowRight: false,
KeyA: false,
KeyD: false,
Space: false
};
// 游戏元素图像
function drawPlayer() {
ctx.save();
// 绘制飞船主体
ctx.fillStyle = player.color;
ctx.beginPath();
ctx.moveTo(player.x + player.width / 2, player.y);
ctx.lineTo(player.x + player.width, player.y + player.height);
ctx.lineTo(player.x, player.y + player.height);
ctx.closePath();
ctx.fill();
// 绘制飞船细节
ctx.fillStyle = '#0055aa';
ctx.fillRect(player.x + player.width / 2 - 10, player.y + 10, 20, 20);
// 如果护盾激活,绘制护盾效果
if (player.shieldActive) {
ctx.strokeStyle = '#00ffff';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(player.x + player.width / 2, player.y + player.height / 2,
player.width / 2 + 10, 0, Math.PI * 2);
ctx.stroke();
// 护盾光晕效果
ctx.strokeStyle = 'rgba(0, 255, 255, 0.3)';
ctx.lineWidth = 8;
ctx.beginPath();
ctx.arc(player.x + player.width / 2, player.y + player.height / 2,
player.width / 2 + 15, 0, Math.PI * 2);
ctx.stroke();
}
ctx.restore();
}
function drawLasers() {
ctx.fillStyle = '#00ff00';
player.lasers.forEach(laser => {
ctx.fillRect(laser.x, laser.y, laser.width, laser.height);
// 激光光效
ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
ctx.fillRect(laser.x - 2, laser.y, laser.width + 4, laser.height);
ctx.fillStyle = '#00ff00';
});
}
function drawEnemies() {
enemies.forEach(enemy => {
// 敌机主体
ctx.fillStyle = enemy.color;
ctx.beginPath();
ctx.moveTo(enemy.x, enemy.y);
ctx.lineTo(enemy.x + enemy.width, enemy.y);
ctx.lineTo(enemy.x + enemy.width / 2, enemy.y + enemy.height);
ctx.closePath();
ctx.fill();
// 敌机细节
ctx.fillStyle = '#550000';
ctx.fillRect(enemy.x + enemy.width / 2 - 5, enemy.y + 5, 10, 10);
});
}
function drawAsteroids() {
asteroids.forEach(asteroid => {
ctx.fillStyle = asteroid.color;
ctx.beginPath();
ctx.arc(asteroid.x, asteroid.y, asteroid.radius, 0, Math.PI * 2);
ctx.fill();
// 陨石纹理
ctx.fillStyle = 'rgba(100, 100, 100, 0.5)';
ctx.beginPath();
ctx.arc(asteroid.x - asteroid.radius / 3, asteroid.y - asteroid.radius / 3,
asteroid.radius / 3, 0, Math.PI * 2);
ctx.fill();
});
}
function drawPowerUps() {
powerUps.forEach(powerUp => {
ctx.fillStyle = powerUp.color;
ctx.beginPath();
ctx.arc(powerUp.x, powerUp.y, powerUp.radius, 0, Math.PI * 2);
ctx.fill();
// 能量效果
ctx.strokeStyle = powerUp.glowColor;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(powerUp.x, powerUp.y, powerUp.radius + 3, 0, Math.PI * 2);
ctx.stroke();
// 内部图标
ctx.fillStyle = '#ffffff';
if (powerUp.type === 'shield') {
ctx.beginPath();
ctx.arc(powerUp.x, powerUp.y, powerUp.radius / 2, 0, Math.PI * 2);
ctx.stroke();
} else if (powerUp.type === 'rapidFire') {
ctx.fillRect(powerUp.x - 3, powerUp.y - 8, 6, 16);
ctx.fillRect(powerUp.x - 8, powerUp.y - 3, 16, 6);
} else if (powerUp.type === 'health') {
ctx.beginPath();
ctx.moveTo(powerUp.x, powerUp.y - 5);
ctx.lineTo(powerUp.x - 5, powerUp.y + 5);
ctx.lineTo(powerUp.x + 5, powerUp.y + 5);
ctx.closePath();
ctx.fill();
}
});
}
function drawBackground() {
// 绘制星空背景
ctx.fillStyle = '#000011';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制星星
ctx.fillStyle = '#ffffff';
for (let i = 0; i < 100; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
const size = Math.random() * 2;
ctx.fillRect(x, y, size, size);
}
// 绘制远处星云
ctx.fillStyle = 'rgba(30, 10, 60, 0.3)';
ctx.beginPath();
ctx.ellipse(150, 100, 200, 80, 0, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = 'rgba(10, 30, 60, 0.3)';
ctx.beginPath();
ctx.ellipse(650, 150, 150, 100, 0, 0, Math.PI * 2);
ctx.fill();
}
// 游戏逻辑
function updatePlayer() {
// 移动玩家
if ((keys.ArrowLeft || keys.KeyA) && player.x > 0) {
player.x -= player.speed;
}
if ((keys.ArrowRight || keys.KeyD) && player.x < canvas.width - player.width) {
player.x += player.speed;
}
// 射击
if (keys.Space && Date.now() - player.lastShot > player.shootDelay) {
player.lasers.push({
x: player.x + player.width / 2 - 2,
y: player.y,
width: 4,
height: 15,
speed: 10
});
player.lastShot = Date.now();
// 如果快速射击激活,减少射击延迟
if (player.rapidFireActive) {
player.shootDelay = 100;
} else {
player.shootDelay = 300;
}
}
// 更新护盾状态
if (player.shieldActive && Date.now() > player.shieldTime) {
player.shieldActive = false;
}
// 更新快速射击状态
if (player.rapidFireActive && Date.now() > player.rapidFireTime) {
player.rapidFireActive = false;
player.shootDelay = 300;
}
}
function updateLasers() {
// 移动激光并移除超出屏幕的激光
player.lasers = player.lasers.filter(laser => {
laser.y -= laser.speed;
return laser.y > 0;
});
}
function spawnEnemies() {
// 根据等级调整敌人生成频率
const spawnRate = Math.max(1000 - (level - 1) * 100, 300);
if (Math.random() < 0.02 && enemies.length < 5 + level) {
enemies.push({
x: Math.random() * (canvas.width - 40),
y: -40,
width: 40,
height: 40,
speed: 2 + level * 0.2,
color: '#ff5555'
});
}
}
function spawnAsteroids() {
// 根据等级调整陨石生成频率
const spawnRate = Math.max(800 - (level - 1) * 80, 200);
if (Math.random() < 0.015 && asteroids.length < 3 + level) {
asteroids.push({
x: Math.random() * canvas.width,
y: -30,
radius: 15 + Math.random() * 15,
speed: 1 + level * 0.3,
color: '#888888'
});
}
}
function spawnPowerUps() {
if (Math.random() < 0.005 && powerUps.length < 2) {
const types = ['shield', 'rapidFire', 'health'];
const type = types[Math.floor(Math.random() * types.length)];
let color, glowColor;
if (type === 'shield') {
color = '#00aaff';
glowColor = '#00ffff';
} else if (type === 'rapidFire') {
color = '#ff0055';
glowColor = '#ff00aa';
} else {
color = '#00ff00';
glowColor = '#aaffaa';
}
powerUps.push({
x: Math.random() * (canvas.width - 30) + 15,
y: -15,
radius: 10,
speed: 2,
type: type,
color: color,
glowColor: glowColor
});
}
}
function updateEnemies() {
enemies.forEach((enemy, index) => {
enemy.y += enemy.speed;
// 检测敌机与玩家碰撞
if (!player.shieldActive &&
enemy.x < player.x + player.width &&
enemy.x + enemy.width > player.x &&
enemy.y < player.y + player.height &&
enemy.y + enemy.height > player.y) {
takeDamage(20);
enemies.splice(index, 1);
}
// 检测敌机与激光碰撞
player.lasers.forEach((laser, laserIndex) => {
if (laser.x < enemy.x + enemy.width &&
laser.x + laser.width > enemy.x &&
laser.y < enemy.y + enemy.height &&
laser.y + laser.height > enemy.y) {
enemies.splice(index, 1);
player.lasers.splice(laserIndex, 1);
score += 10;
updateScore();
}
});
// 移除超出屏幕的敌机
if (enemy.y > canvas.height) {
enemies.splice(index, 1);
}
});
}
function updateAsteroids() {
asteroids.forEach((asteroid, index) => {
asteroid.y += asteroid.speed;
// 检测陨石与玩家碰撞
if (!player.shieldActive) {
const dx = asteroid.x - (player.x + player.width / 2);
const dy = asteroid.y - (player.y + player.height / 2);
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < asteroid.radius + player.width / 2) {
takeDamage(15);
asteroids.splice(index, 1);
}
}
// 检测陨石与激光碰撞
player.lasers.forEach((laser, laserIndex) => {
const dx = asteroid.x - (laser.x + laser.width / 2);
const dy = asteroid.y - (laser.y + laser.height / 2);
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < asteroid.radius + laser.width / 2) {
asteroids.splice(index, 1);
player.lasers.splice(laserIndex, 1);
score += 5;
updateScore();
}
});
// 移除超出屏幕的陨石
if (asteroid.y > canvas.height + asteroid.radius) {
asteroids.splice(index, 1);
}
});
}
function updatePowerUps() {
powerUps.forEach((powerUp, index) => {
powerUp.y += powerUp.speed;
// 检测能量道具与玩家碰撞
const dx = powerUp.x - (player.x + player.width / 2);
const dy = powerUp.y - (player.y + player.height / 2);
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < powerUp.radius + player.width / 2) {
activatePowerUp(powerUp.type);
powerUps.splice(index, 1);
}
// 移除超出屏幕的能量道具
if (powerUp.y > canvas.height + powerUp.radius) {
powerUps.splice(index, 1);
}
});
}
function activatePowerUp(type) {
if (type === 'shield') {
player.shieldActive = true;
player.shieldTime = Date.now() + 5000; // 护盾持续5秒
} else if (type === 'rapidFire') {
player.rapidFireActive = true;
player.rapidFireTime = Date.now() + 7000; // 快速射击持续7秒
player.shootDelay = 100;
} else if (type === 'health') {
health = Math.min(health + 30, 100);
updateHealth();
}
}
function takeDamage(amount) {
health -= amount;
updateHealth();
if (health <= 0) {
gameOver();
}
}
function updateLevel() {
// 每100分升一级
const newLevel = Math.floor(score / 100) + 1;
if (newLevel > level) {
level = newLevel;
document.getElementById('level').textContent = level;
}
}
function updateScore() {
document.getElementById('score').textContent = score;
updateLevel();
}
function updateHealth() {
document.getElementById('health').textContent = health;
}
function gameOver() {
gameRunning = false;
document.getElementById('finalScore').textContent = score;
document.getElementById('gameOver').style.display = 'flex';
}
function resetGame() {
score = 0;
health = 100;
level = 1;
player.x = canvas.width / 2 - 25;
player.y = canvas.height - 80;
player.lasers = [];
player.shieldActive = false;
player.rapidFireActive = false;
enemies = [];
asteroids = [];
powerUps = [];
updateScore();
updateHealth();
document.getElementById('level').textContent = level;
document.getElementById('gameOver').style.display = 'none';
}
// 游戏循环
function gameLoop() {
if (!gameRunning || gamePaused) return;
// 清除画布
drawBackground();
// 更新游戏状态
updatePlayer();
updateLasers();
spawnEnemies();
spawnAsteroids();
spawnPowerUps();
updateEnemies();
updateAsteroids();
updatePowerUps();
// 绘制游戏元素
drawLasers();
drawEnemies();
drawAsteroids();
drawPowerUps();
drawPlayer();
// 继续游戏循环
requestAnimationFrame(gameLoop);
}
// 事件监听
document.addEventListener('keydown', (e) => {
if (keys.hasOwnProperty(e.code)) {
keys[e.code] = true;
}
});
document.addEventListener('keyup', (e) => {
if (keys.hasOwnProperty(e.code)) {
keys[e.code] = false;
}
});
document.getElementById('startButton').addEventListener('click', () => {
if (!gameRunning) {
gameRunning = true;
gamePaused = false;
resetGame();
gameLoop();
}
});
document.getElementById('pauseButton').addEventListener('click', () => {
if (gameRunning) {
gamePaused = !gamePaused;
if (!gamePaused) {
gameLoop();
}
}
});
document.getElementById('restartButton').addEventListener('click', () => {
resetGame();
gameRunning = true;
gamePaused = false;
gameLoop();
});
// 初始绘制
drawBackground();
drawPlayer();
</script>