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
...
No comments yet. Be the first!