打砖块

一个经典的打砖块游戏,包含玩家头像选择、多关卡、生命系统、排行榜和移动端触摸控制,支持保存高分记录到数据库。

Preview
Source CodeVersion 3
export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    // API routes for high scores
    if (url.pathname.startsWith('/api/')) {
      if (url.pathname === '/api/scores' && request.method === 'GET') {
        try {
          const scores = await env.DB.prepare(`
            SELECT player_name, score, level, avatar, created_at 
            FROM high_scores 
            ORDER BY score DESC 
            LIMIT 10
          `).all();
          
          return new Response(JSON.stringify({ data: scores.results || [] }), {
            headers: { 'Content-Type': 'application/json' }
          });
        } catch (error) {
          return new Response(JSON.stringify({ error: 'Failed to fetch scores' }), {
            status: 500,
            headers: { 'Content-Type': 'application/json' }
          });
        }
      }

      if (url.pathname === '/api/scores' && request.method === 'POST') {
        try {
          const { playerName, score, level, avatar } = await request.json();
          
          await env.DB.prepare(`
            INSERT INTO high_scores (id, player_name, score, level, avatar, created_at)
            VALUES (?1, ?2, ?3, ?4, ?5, datetime('now'))
          `).bind(crypto.randomUUID(), playerName, score, level, avatar || '😊').run();
          
          return new Response(JSON.stringify({ ok: true }), {
            headers: { 'Content-Type': 'application/json' }
          });
        } catch (error) {
          return new Response(JSON.stringify({ error: 'Failed to save score' }), {
            status: 500,
            headers: { 'Content-Type': 'application/json' }
          });
        }
      }

      return new Response(JSON.stringify({ error: 'Not found' }), {
        status: 404,
        headers: { 'Content-Type': 'application/json' }
      });
    }

    // Serve HTML
    return new Response(getHTML(), {
      headers: { 'Content-Type': 'text/html' }
    });
  }
};

function getHTML() {
  return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>打砖块大作战 | Breakout Game</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
  <style>
    * { font-family: 'Inter', sans-serif; }
    body { overflow: hidden; }
    canvas { border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(139, 92, 246, 0.25); }
    .gradient-bg { background: linear-gradient(135deg, #8b5cf6 0%, #3b82f6 100%); }
    .glow { box-shadow: 0 0 20px rgba(139, 92, 246, 0.5); }
    .avatar-option {
      transition: all 0.2s ease;
    }
    .avatar-option:hover {
      transform: scale(1.2);
      background-color: rgba(139, 92, 246, 0.3);
    }
    .avatar-option.selected {
      background-color: rgba(139, 92, 246, 0.6);
      transform: scale(1.1);
    }
  </style>
</head>
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center gradient-bg">
  <div class="container mx-auto px-4">
    <!-- Game Header -->
    <div class="text-center mb-6">
      <h1 class="text-4xl md:text-6xl font-bold mb-2 text-white drop-shadow-lg">🧱 打砖块大作战</h1>
      <p class="text-white/80 text-lg">经典怀旧,激情重燃!</p>
    </div>

    <!-- Game Container -->
    <div class="flex flex-col lg:flex-row items-start justify-center gap-6">
      <!-- Game Canvas -->
      <div class="relative">
        <canvas id="gameCanvas" width="800" height="600" class="bg-black/20 backdrop-blur border border-white/20 rounded-xl"></canvas>
        
        <!-- Game Over Overlay -->
        <div id="gameOverlay" class="absolute inset-0 bg-black/80 backdrop-blur flex items-center justify-center rounded-xl hidden">
          <div class="text-center p-8">
            <!-- Player Setup Screen -->
            <div id="playerSetupScreen">
              <h2 class="text-3xl font-bold mb-4">🎮 游戏设置</h2>
              
              <!-- Player Name -->
              <div class="mb-6">
                <label class="block text-white/80 text-lg mb-2">玩家姓名</label>
                <input id="setupPlayerName" type="text" placeholder="输入你的名字" maxlength="20" 
                       class="w-64 px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-white/60 focus:border-violet-500 focus:outline-none">
              </div>
              
              <!-- Avatar Selection -->
              <div class="mb-6">
                <label class="block text-white/80 text-lg mb-4">选择头像</label>
                <div id="avatarGrid" class="grid grid-cols-5 gap-3 max-w-xs mx-auto mb-4">
                  <!-- Avatar options will be populated by JavaScript -->
                </div>
                <p class="text-white/60 text-sm">点击选择你的专属头像</p>
              </div>
              
              <!-- Start Button -->
              <button id="setupStartBtn" class="px-8 py-4 bg-gradient-to-r from-violet-50
...

Comments (0)

No comments yet. Be the first!