游戏厅架构设计与实现总览

AI 智能总结

简介

游戏厅(Arcade)是 Lumin 博客的一个独立页面,集成了 9 款经典小游戏,通过标签页切换实现单页多游戏体验。所有游戏均支持最高分本地存储和暗色主题适配。

游戏列表

#游戏实现方式操作
1五子棋DOM + CSS Grid鼠标点击
2扫雷DOM + CSS Grid鼠标点击/右键
3贪吃蛇Canvas方向键
4俄罗斯方块Canvas方向键 + 空格
52048DOM + CSS Grid方向键
6Flappy BirdCanvas空格/点击
7记忆翻牌DOM + CSS 3D鼠标点击
8打砖块Canvas方向键/鼠标
9井字棋DOM + CSS Grid鼠标点击

架构设计

单页多面板架构

所有 9 个游戏放在同一个 HTML 文件中,通过 CSS display: none/block 切换面板:

 1┌──────────────────────────────────────────────┐
 2│  [五子棋] [扫雷] [贪吃蛇] [俄罗斯方块]      │
 3│  [2048] [Flappy Bird] [记忆翻牌]            │  ← 标签栏
 4│  [打砖块] [井字棋]                          │
 5├──────────────────────────────────────────────┤
 6│                                              │
 7│           游戏面板 (display: block)          │  ← 当前活跃游戏
 8│                                              │
 9├──────────────────────────────────────────────┤
10│          侧边栏 (分数/状态/操作)             │  ← 游戏信息面板
11└──────────────────────────────────────────────┘

标签切换机制

 1function switchGame(gameName) {
 2  // 隐藏所有面板
 3  document.querySelectorAll('.arcade-game-panel').forEach(function(p) {
 4    p.classList.remove('active');
 5  });
 6  // 显示目标面板
 7  document.getElementById('panel-' + gameName).classList.add('active');
 8  // 更新标签状态
 9  document.querySelectorAll('.arcade-tab').forEach(function(t) {
10    t.classList.toggle('active', t.dataset.game === gameName);
11  });
12}

Canvas 游戏生命周期

Canvas 游戏(贪吃蛇、俄罗斯方块、Flappy Bird、打砖块)需要注意切换时的生命周期管理:

 1// 切换离开时停止动画循环
 2function leaveGame() {
 3  if (animFrameId) {
 4    cancelAnimationFrame(animFrameId);
 5    animFrameId = null;
 6  }
 7}
 8
 9// 切换回来时重新初始化
10function enterGame() {
11  init();
12  // 仅当面板激活且游戏状态为 playing 时启动动画
13  if (playing) animFrameId = requestAnimationFrame(gameLoop);
14}

键盘事件隔离

多个游戏使用相同的键盘事件(方向键),需要根据当前活跃面板过滤:

1document.addEventListener('keydown', function(e) {
2  // 不同游戏各自检查自己的面板是否活跃
3  if (!document.getElementById('panel-snake').classList.contains('active')) return;
4  // 处理方向键...
5});

样式设计

标签栏

每个标签使用彩色圆点区分游戏:

1.arcade-tab .tab-dot.gomoku   { background: #3b82f6; }  /* 蓝色 - 五子棋 */
2.arcade-tab .tab-dot.minesweeper { background: #ef4444; } /* 红色 - 扫雷 */
3.arcade-tab .tab-dot.snake    { background: #22c55e; }  /* 绿色 - 贪吃蛇 */
4.arcade-tab .tab-dot.tetris   { background: #8b5cf6; }  /* 紫色 - 俄罗斯方块 */
5.arcade-tab .tab-dot.tzfe     { background: #f97316; }  /* 橙色 - 2048 */
6.arcade-tab .tab-dot.flappy   { background: #14b8a6; }  /* 青色 - Flappy Bird */
7.arcade-tab .tab-dot.memory   { background: #ec4899; }  /* 粉色 - 记忆翻牌 */
8.arcade-tab .tab-dot.breakout { background: #ef4444; }  /* 红色 - 打砖块 */
9.arcade-tab .tab-dot.tictactoe{ background: #6366f1; }  /* 靛色 - 井字棋 */

游戏面板布局

每个游戏面板采用左右分栏布局:

1┌──────────────────────┬──────────────────┐
2│                      │   状态栏          │
3│    游戏主区域        │   当前分数        │
4│   (Canvas / Grid)   │   最高分          │
5│                      │   操作按键说明    │
6│                      │   [重新开始]      │
7└──────────────────────┴──────────────────┘

数据持久化

所有游戏使用 localStorage 存储最高分:

游戏localStorage Key
贪吃蛇arcade-snake-best
俄罗斯方块arcade-tetris-best
2048arcade-tzfe-best
Flappy Birdarcade-flappy-best
打砖块arcade-breakout-best

扫雷、五子棋、井字棋使用运行时状态,不需要持久化。

暗色主题适配

所有游戏组件通过 CSS 变量和 [data-theme="dark"] 选择器适配暗色模式:

1[data-theme="dark"] .game-board {
2  background: #1e293b;
3  border-color: #334155;
4}
5[data-theme="dark"] .game-card {
6  background: rgba(30, 41, 59, 0.8);
7}

Canvas 游戏通过 JavaScript 检测主题并切换绘制颜色:

1function getThemeColors() {
2  var isDark = document.documentElement.dataset.theme === 'dark';
3  return {
4    bg: isDark ? '#0f172a' : '#f8fafc',
5    grid: isDark ? '#1e293b' : '#e2e8f0',
6    text: isDark ? '#e2e8f0' : '#1e293b'
7  };
8}

响应式布局

通过 CSS 媒体查询适配移动端:

1@media (max-width: 900px) {
2  .game-body {
3    flex-direction: column;
4  }
5  .game-panel {
6    width: 100%;
7  }
8}

文件结构

1layouts/
2└── arcade/
3    └── list.html    # 游戏厅主模板(全部 CSS + HTML + JS)
4
5content/
6└── arcade/
7    └── _index.md    # 页面元数据(type: arcade, aside: false)
8
9hugo.toml             # 导航菜单配置

总结

游戏厅采用单文件模板架构,将 9 款游戏的 CSS、HTML、JavaScript 全部内联在一个模板文件中,利用 Hugo 的 define "main"define "scripts" 块分离结构与逻辑。这种设计避免了大量小文件的维护成本,同时通过标签切换实现流畅的游戏切换体验。

留言评论

期待你的想法

评论加载中