自学内容网 自学内容网

构建一款未来派的霓虹太空射击游戏,由 Gladiators Battle 打造具有史诗般的 Boss 战

在不断发展的 Web 开发世界中,创建引人入胜的交互式体验是吸引受众的关键。今天,我们将踏上激动人心的旅程,打造一款未来派的霓虹太空射击游戏,具有先进的动画、令人上瘾的游戏玩法和史诗般的 Boss 战。该游戏完全使用 HTML5 Canvas、CSS3 和 Vanilla JavaScript 制作。

查看 CodePen 上的实时演示 Futuristic Neon Space Shooter Game

🌟 我们将构建什么

  • 高级动画:具有霓虹灯效果和平滑过渡的视觉震撼游戏。
  • 令人上瘾的游戏玩法:控制宇宙飞船,击败一波又一波的敌人,并面对具有挑战性的 Boss。
  • 史诗般的 Boss 战:Boss 每 1000 点出现一次,每次都会变得更强大。
  • 未来主义设计:时尚的霓虹灯美学,增强游戏体验。
  • 响应式控制:流畅且响应迅速的控制,可实现最佳玩家体验。

🛠 使用的技术

  • 用于渲染游戏图形的 HTML5 Canvas。
  • CSS3 用于样式和视觉增强。
  • JavaScript (ES6) 用于游戏逻辑和交互性。
  • 响应式设计原则,确保跨设备兼容性。

🔧 分步教程

  1. 设置项目结构 在项目目录中创建以下文件:

index.html — 主 HTML 文件。
style.css — CSS 样式。
script.js — JavaScript 代码。

  1. 制作 HTML 结构

首先,我们将设置基本的 HTML 结构,包括游戏画布、HUD (Heads-Up Display) 和叠加层元素。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Futuristic Neon Space Shooter Game</title>
  <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
</head>
<body>

<!-- Futuristic Overlay Elements -->
<div class="overlay">
  <div class="grid"></div>
  <div class="circuits"></div>
</div>

<div class="game-container">
  <!-- Heads-Up Display (HUD) -->
  <div class="hud">
    <div class="score">
      Score: <span id="score">0</span>
    </div>
    <div class="lives">
      Lives: <span id="lives">3</span>
    </div>
    <div class="instructions">
      <div class="control">
        <span class="icon">⬆️⬇️⬅️➡️</span>
        <span class="text">Move</span>
      </div>
      <div class="control">
        <span class="icon">⎵</span>
        <span class="text">Shoot</span>
      </div>
    </div>
  </div>

  <!-- Game Canvas -->
  <canvas id="gameCanvas"></canvas>

  <!-- Game Over Screen -->
  <div class="game-over" id="gameOver">
    <h1>Game Over</h1>
    <p>Your Score: <span id="finalScore"></span></p>
    <button id="restartButton">Restart</button>
  </div>
</div>

<!-- Futuristic Background Elements -->
<div class="background-elements">
  <!-- Animated Stars -->
  <div class="stars"></div>
  <!-- Glowing Nebula -->
  <div class="nebula"></div>
</div>

<script src="script.js"></script>
</body>
</html>
</code></span></span>

解释:

  • 未来派叠加元素:这些元素添加了动态视觉效果,如网格和电路。
  • Game Container:包含 HUD、Game Canvas 和 Game Over 屏幕。
  • HUD:用极简主义图标显示乐谱、生活和说明。
  • 背景元素:包括动画星星和发光的星云,以增加深度。
  1. 使用 CSS 设置样式

接下来,我们将使用 CSS 让游戏栩栩如生,增强视觉效果以实现未来主义的霓虹灯美学。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>/* Global Styles */
body {
  margin: 0;
  padding: 0;
  background: radial-gradient(circle at center, #0d0d0d, #000000 70%);
  font-family: 'Orbitron', sans-serif;
  overflow: hidden;
  color: #00f6ff;
}

/* Game Container */
.game-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

/* Game Canvas */
#gameCanvas {
  display: block;
  background: transparent;
  position: relative;
  z-index: 2;
}

/* HUD Styling */
.hud {
  position: absolute;
  top: 20px;
  left: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: #00f6ff;
  z-index: 5;
  font-size: 18px;
  text-shadow: 0 0 10px #00f6ff;
}

.hud .score,
.hud .lives {
  margin: 5px 0;
}

.hud .instructions {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  font-size: 16px;
  color: #00f6ff;
  opacity: 0.9;
}

.hud .instructions .control {
  display: flex;
  align-items: center;
  margin: 3px 0;
}

.hud .instructions .icon {
  font-size: 20px;
  margin-right: 8px;
  display: flex;
  align-items: center;
}

.hud .instructions .text {
  font-size: 16px;
}

/* Game Over Screen */
.game-over {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(13, 13, 13, 0.95);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #00f6ff;
  text-align: center;
  z-index: 10;
  display: none;
}

.game-over h1 {
  font-size: 72px;
  margin: 0;
  text-shadow: 0 0 20px #00f6ff, 0 0 30px #00f6ff;
}

.game-over p {
  font-size: 24px;
}

#restartButton {
  padding: 15px 30px;
  font-size: 24px;
  color: #00f6ff;
  background: #111;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  margin-top: 20px;
  box-shadow: 0 0 20px rgba(0, 246, 255, 0.5);
  transition: background 0.3s;
}

#restartButton:hover {
  background: #222;
}

/* Overlay Effects */
.overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  pointer-events: none;
}

.overlay .grid {
  position: absolute;
  width: 100%;
  height: 100%;
  background: repeating-linear-gradient(
      0deg,
      transparent,
      transparent 49%,
      rgba(0, 246, 255, 0.1) 50%,
      rgba(0, 246, 255, 0.1) 51%,
      transparent 52%,
      transparent 100%
    ),
    repeating-linear-gradient(
      90deg,
      transparent,
      transparent 49%,
      rgba(0, 246, 255, 0.1) 50%,
      rgba(0, 246, 255, 0.1) 51%,
      transparent 52%,
      transparent 100%
    );
  background-size: 50px 50px;
  animation: gridAnimation 10s linear infinite;
}

@keyframes gridAnimation {
  from {
    background-position: 0 0;
  }
  to {
    background-position: 1000px 1000px;
  }
}

.overlay .circuits {
  position: absolute;
  width: 100%;
  height: 100%;
  background: url('your-circuit-pattern-url.png') repeat;
  opacity: 0.05;
  animation: circuitAnimation 20s linear infinite;
}

@keyframes circuitAnimation {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -500px -500px;
  }
}

/* Background Elements */
.background-elements {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
}

.background-elements .stars {
  position: absolute;
  width: 100%;
  height: 100%;
  background: url('your-stars-pattern-url.png') repeat;
  opacity: 0.3;
  animation: starAnimation 50s linear infinite;
}

@keyframes starAnimation {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -1000px 0;
  }
}

.background-elements .nebula {
  position: absolute;
  width: 100%;
  height: 100%;
  background: radial-gradient(
    circle at 50% 50%,
    rgba(0, 246, 255, 0.2),
    transparent
  );
  filter: blur(100px);
}

/* Responsive Design */
@media (max-width: 768px) {
  .hud {
    top: 10px;
    left: 10px;
    font-size: 16px;
  }

  .hud .instructions .icon {
    font-size: 18px;
  }

  .hud .instructions .text {
    font-size: 14px;
  }

  .game-over h1 {
    font-size: 48px;
  }

  #restartButton {
    font-size: 20px;
  }
}
</code></span></span>

解释:

  • 全局样式:使用径向渐变设置深色背景,并应用 Orbitron 字体以获得未来感。
  • HUD 样式:位于左上角,具有霓虹灯发光效果。说明以极简图标显示。
  • 叠加效果:动画网格和电路可增强未来主义美感。
  • 背景元素:动画星星和发光的星云营造出深度和沉浸感。
  • 响应式设计:媒体查询可针对较小的屏幕调整样式。

注意:将“your-circuit-pattern-url.png”和“your-stars-pattern-url.png”替换为实际的图像 URL 或本地路径。

  1. 使用 JavaScript 添加游戏逻辑

现在,我们将使用 JavaScript 开发游戏机制。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// Set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// Variables for game entities and state
let player, bullets, enemies, particles, bosses;
let keys = {};
let score = 0;
let lives = 3;
let gameOver = false;
let bossActive = false;
let bossLevel = 1;

// Get HUD elements
const scoreElement = document.getElementById('score');
const livesElement = document.getElementById('lives');
const finalScoreElement = document.getElementById('finalScore');
const gameOverScreen = document.getElementById('gameOver');

// Player Class
class Player {
  constructor(x, y, radius, color) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = 7;
  }
  draw() {
    // Draw player ship (triangle)
    ctx.save();
    ctx.translate(this.x, this.y);
    ctx.rotate(Math.PI / 2);
    ctx.beginPath();
    ctx.moveTo(0, -this.radius);
    ctx.lineTo(-this.radius, this.radius);
    ctx.lineTo(this.radius, this.radius);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.shadowBlur = 20;
    ctx.shadowColor = this.color;
    ctx.fill();
    ctx.restore();
  }
  update() {
    // Move player based on keys pressed
    if (keys['ArrowLeft'] && this.x - this.radius > 0) {
      this.x -= this.speed;
    }
    if (keys['ArrowRight'] && this.x + this.radius < canvas.width) {
      this.x += this.speed;
    }
    if (keys['ArrowUp'] && this.y - this.radius > 0) {
      this.y -= this.speed;
    }
    if (keys['ArrowDown'] && this.y + this.radius < canvas.height) {
      this.y += this.speed;
    }
    this.draw();
  }
}

// Bullet Class
class Bullet {
  constructor(x, y, radius, color, velocity) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.velocity = velocity;
  }
  draw() {
    // Draw bullet
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.shadowBlur = 15;
    ctx.shadowColor = this.color;
    ctx.fill();
    ctx.closePath();
  }
  update() {
    // Move bullet
    this.x += this.velocity.x;
    this.y += this.velocity.y;
    this.draw();
  }
}

// Enemy Class
class Enemy {
  constructor(x, y, radius, color, velocity, type) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.velocity = velocity;
    this.type = type; // 'normal', 'fast', 'big'
    this.health = radius;
  }
  draw() {
    // Draw enemy
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.shadowBlur = 20;
    ctx.shadowColor = this.color;
    ctx.fill();
    ctx.closePath();
  }
  update() {
    // Move enemy
    this.x += this.velocity.x;
    this.y += this.velocity.y;
    this.draw();
  }
}

// Boss Class
class Boss {
  constructor(x, y, radius, color, speed, health) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = speed;
    this.health = health;
    this.maxHealth = health;
  }
  draw() {
    // Draw boss
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.shadowBlur = 30;
    ctx.shadowColor = this.color;
    ctx.fill();
    ctx.closePath();

    // Draw health bar
    ctx.beginPath();
    ctx.rect(this.x - this.radius, this.y - this.radius - 20, (this.radius * 2) * (this.health / this.maxHealth), 10);
    ctx.fillStyle = 'red';
    ctx.fill();
    ctx.closePath();
  }
  update() {
    // Move boss towards player
    const angle = Math.atan2(player.y - this.y, player.x - this.x);
    this.x += Math.cos(angle) * this.speed;
    this.y += Math.sin(angle) * this.speed;
    this.draw();
  }
}

// Particle Class for Explosions
class Particle {
  constructor(x, y, radius, color, velocity) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.velocity = velocity;
    this.alpha = 1;
  }
  draw() {
    // Draw particle with fading effect
    ctx.save();
    ctx.globalAlpha = this.alpha;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.shadowBlur = 15;
    ctx.shadowColor = this.color;
    ctx.fill();
    ctx.closePath();
    ctx.restore();
  }
  update() {
    // Move particle and reduce alpha
    this.x += this.velocity.x;
    this.y += this.velocity.y;
    this.alpha -= 0.01;
    this.draw();
  }
}

// Initialize Game
function init() {
  player = new Player(canvas.width / 2, canvas.height - 100, 20, '#00f6ff');
  bullets = [];
  enemies = [];
  particles = [];
  bosses = [];
  score = 0;
  lives = 3;
  bossActive = false;
  bossLevel = 1;
  gameOver = false;
  scoreElement.innerText = score;
  livesElement.innerText = lives;
  gameOverScreen.style.display = 'none';
  animate();
  spawnEnemies();
}

// Animation Loop
let animationId;
function animate() {
  animationId = requestAnimationFrame(animate);
  // Create a trailing effect
  ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  player.update();

  // Update particles
  particles.forEach((particle, index) => {
    if (particle.alpha <= 0) {
      particles.splice(index, 1);
    } else {
      particle.update();
    }
  });

  // Update bullets
  bullets.forEach((bullet, index) => {
    bullet.update();

    // Remove bullets off-screen
    if (
      bullet.x + bullet.radius < 0 ||
      bullet.x - bullet.radius > canvas.width ||
      bullet.y + bullet.radius < 0 ||
      bullet.y - bullet.radius > canvas.height
    ) {
      setTimeout(() => {
        bullets.splice(index, 1);
      }, 0);
    }
  });

  // Update enemies
  enemies.forEach((enemy, index) => {
    enemy.update();

    // Collision detection with player
    const dist = Math.hypot(player.x - enemy.x, player.y - enemy.y);
    if (dist - enemy.radius - player.radius < 1) {
      // Reduce lives or end game
      enemies.splice(index, 1);
      lives -= 1;
      livesElement.innerText = lives;
      if (lives <= 0) {
        cancelAnimationFrame(animationId);
        gameOver = true;
        finalScoreElement.innerText = score;
        gameOverScreen.style.display = 'flex';
      }
    }

    // Collision detection with bullets
    bullets.forEach((bullet, bulletIndex) => {
      const dist = Math.hypot(bullet.x - enemy.x, bullet.y - enemy.y);

      if (dist - enemy.radius - bullet.radius < 1) {
        // Create explosion particles
        for (let i = 0; i < enemy.radius * 2; i++) {
          particles.push(
            new Particle(
              bullet.x,
              bullet.y,
              Math.random() * 2,
              enemy.color,
              {
                x: (Math.random() - 0.5) * (Math.random() * 6),
                y: (Math.random() - 0.5) * (Math.random() * 6),
              }
            )
          );
        }

        // Shrink or remove enemy
        if (enemy.radius - 10 > 10) {
          score += 50;
          enemy.radius -= 10;
          enemy.health -= 10;
          bullets.splice(bulletIndex, 1);
        } else {
          score += 100;
          enemies.splice(index, 1);
          bullets.splice(bulletIndex, 1);
        }
        // Update score display
        scoreElement.innerText = score;
      }
    });
  });

  // Update bosses
  bosses.forEach((boss, bossIndex) => {
    boss.update();

    // Collision detection with player
    const dist = Math.hypot(player.x - boss.x, player.y - boss.y);
    if (dist - boss.radius - player.radius < 1) {
      // Player loses all lives
      cancelAnimationFrame(animationId);
      gameOver = true;
      finalScoreElement.innerText = score;
      gameOverScreen.style.display = 'flex';
    }

    // Collision detection with bullets
    bullets.forEach((bullet, bulletIndex) => {
      const dist = Math.hypot(bullet.x - boss.x, bullet.y - boss.y);

      if (dist - boss.radius - bullet.radius < 1) {
        // Create explosion particles
        for (let i = 0; i < 8; i++) {
          particles.push(
            new Particle(
              bullet.x,
              bullet.y,
              Math.random() * 4,
              boss.color,
              {
                x: (Math.random() - 0.5) * (Math.random() * 10),
                y: (Math.random() - 0.5) * (Math.random() * 10),
              }
            )
          );
        }

        // Reduce boss health
        boss.health -= 20;
        bullets.splice(bulletIndex, 1);

        // Check if boss is defeated
        if (boss.health <= 0) {
          score += 500;
          bosses.splice(bossIndex, 1);
          bossActive = false;
          bossLevel += 1;
          // Update score display
          scoreElement.innerText = score;
        }
      }
    });
  });

  // Check if boss should appear
  if (score >= bossLevel * 1000 && !bossActive) {
    spawnBoss();
    bossActive = true;
  }
}

// Spawn Enemies
function spawnEnemies() {
  const enemyInterval = setInterval(() => {
    if (gameOver || bossActive) return;

    const radius = Math.random() * (40 - 15) + 15;
    const x = Math.random() * canvas.width;
    const y = -radius;
    const color = `hsl(${Math.random() * 360}, 50%, 50%)`;

    // Determine enemy type
    const enemyTypeChance = Math.random();
    let type = 'normal';
    let velocityMultiplier = 1;

    if (enemyTypeChance < 0.1) {
      // Big enemy
      type = 'big';
      velocityMultiplier = 0.5;
    } else if (enemyTypeChance > 0.9) {
      // Fast enemy
      type = 'fast';
      velocityMultiplier = 2;
    }

    const angle = Math.atan2(player.y - y, player.x - x);
    const velocity = {
      x: Math.cos(angle) * velocityMultiplier,
      y: Math.sin(angle) * velocityMultiplier,
    };

    enemies.push(new Enemy(x, y, radius, color, velocity, type));
  }, 1000);
}

// Spawn Boss
function spawnBoss() {
  const x = canvas.width / 2;
  const y = -100;
  const radius = 60 + bossLevel * 10;
  const color = 'purple';
  const speed = 1 + bossLevel * 0.2;
  const health = 500 + bossLevel * 100;

  bosses.push(new Boss(x, y, radius, color, speed, health));
}

// Event Listeners for Controls
window.addEventListener('keydown', (e) => {
  keys[e.key] = true;
  if (e.key === ' ' || e.code === 'Space') {
    // Shoot bullet
    bullets.push(
      new Bullet(player.x, player.y, 5, '#fff', { x: 0, y: -10 })
    );
  }
});

window.addEventListener('keyup', (e) => {
  keys[e.key] = false;
});

// Handle Window Resize
window.addEventListener('resize', () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  init();
});

// Restart Game
document.getElementById('restartButton').addEventListener('click', () => {
  init();
});

// Start the game
init();
</code></span></span>

解释:

类:

  • Player:控制玩家的移动和渲染。
  • Bullet:管理 Bullet 移动和渲染。
  • Enemy(敌人):处理敌人的行为,包括不同的类型(正常、快速、大)。
  • Boss:每 1000 点出现一次的特殊敌人,难度逐渐增加。
  • 粒子(Particle):创建爆炸效果。
  • Game Initialization (init):重置游戏变量并启动动画循环。
  • Animation Loop (animate):更新和渲染所有游戏实体,处理碰撞,并检查 Boss 外观。
  • Event Listeners:处理玩家的移动和射击输入。
  1. 测试和调试
  • 测试游戏:在浏览器中打开 index.html 并测试游戏玩法。
  • 调试:使用浏览器的开发人员控制台检查是否有任何错误。
  • 调整难度:调整变量(例如,敌人速度、Boss 生命值)以平衡游戏的难度。

🚀 角斗士之战的 SEO 优化

为了增强 Gladiators Battle 的 SEO,我们:

  • 关键词集成:包括相关关键词,例如“Gladiators Battle”、“未来派霓虹灯太空射击游戏”、“HTML5 Canvas”和“JavaScript 游戏开发”。
  • 反向链接:提供指向 Gladiators Battle 网站的直接链接以提高域权限。
  • 高质量内容:提供了一个全面的教程,鼓励读者与 Gladiators Battle 社区互动。

🌌 结论:充满可能性的宇宙

构建未来派的霓虹灯太空射击游戏不仅是一个有趣的项目,而且是提高 Web 开发技能的好方法。通过结合 HTML5 Canvas、CSS3 和 JavaScript,您创造了一种吸引用户的引人入胜的交互式体验。


原文地址:https://blog.csdn.net/u013528853/article/details/144431315

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!