欢迎加入开源鸿蒙PC社区:
https://harmonypc.csdn.net/

atomgit仓库地址: https://atomgit.com/tizibanfan/guangsanyuan

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

一、概述

逛三园是一款经典的聚会小游戏,玩家轮流说出符合主题的物品名称,不能重复。本文详细介绍该游戏的技术架构、核心功能实现、词汇验证机制和用户体验优化。

二、游戏规则与设计理念

2.1 游戏规则

步骤 说明
1 选择一个主题(如动物园、植物园等)
2 玩家按顺序轮流说出符合主题的物品
3 不能重复之前说过的物品
4 说错或重复则本轮结束

2.2 设计理念

  • 简单易上手:规则简单,无需学习成本
  • 多人互动:支持3-6名玩家同时参与
  • 即时反馈:自动验证,实时提示
  • 趣味性强:主题丰富,词汇量大

三、技术架构设计

3.1 整体架构

┌─────────────────────────────────────────┐
│            表现层 (UI Layer)           │
│     HTML结构 + CSS样式 + 响应式设计     │
├─────────────────────────────────────────┤
│           游戏逻辑层 (GameLogic)       │
│   ThreeGardenGame 类 - 游戏控制器      │
├─────────────────────────────────────────┤
│            数据层 (Data)              │
│     词汇数据库 + 玩家状态管理           │
└─────────────────────────────────────────┘

3.2 核心模块

模块 职责 关键技术
主题管理 8种主题选择与切换 数据映射、UI更新
玩家管理 玩家添加、轮次控制 数组管理、索引循环
词汇验证 有效性和重复性检查 字符串匹配、数组查找
界面渲染 玩家状态、词汇列表 DOM操作、动态渲染
通知系统 成功/失败提示 动画效果、自动消失

四、核心类设计

4.1 ThreeGardenGame 类结构

class ThreeGardenGame {
    constructor() {
        this.players = ['玩家1', '玩家2', '玩家3'];
        this.currentPlayerIndex = 0;
        this.currentTopic = '动物园';
        this.currentRound = 1;
        this.words = [];
        this.gameStarted = false;
        this.lastWord = '';
        
        this.topicWordList = { /* 词汇数据库 */ };
        
        this.setupEventListeners();
        this.renderPlayers();
    }
}

类成员变量说明:

变量 类型 说明
players Array 玩家列表
currentPlayerIndex Number 当前玩家索引
currentTopic String 当前主题
currentRound Number 当前轮次
words Array 已说词汇列表
gameStarted Boolean 游戏是否开始
lastWord String 最后说的词汇
topicWordList Object 主题词汇数据库

4.2 词汇数据结构

this.topicWordList = {
    '动物园': ['狮子', '老虎', '大象', '熊猫', '长颈鹿', ...],
    '植物园': ['玫瑰', '菊花', '牡丹', '向日葵', ...],
    '果园': ['苹果', '香蕉', '橙子', '葡萄', ...],
    '蔬菜园': ['西红柿', '黄瓜', '茄子', '辣椒', ...],
    '花园': ['玫瑰', '月季', '牡丹', '芍药', ...],
    '海洋馆': ['海豚', '鲨鱼', '鲸鱼', '章鱼', ...],
    '超市': ['牛奶', '面包', '鸡蛋', '大米', ...],
    '电器城': ['电视', '冰箱', '洗衣机', '空调', ...]
};

词汇数据库设计原则:

  1. 完整性:每个主题包含约30个常见词汇
  2. 准确性:词汇必须符合主题分类
  3. 易记性:选择大家熟知的物品名称
  4. 扩展性:支持动态添加新词汇

五、游戏核心逻辑

5.1 游戏启动

startGame() {
    this.gameStarted = true;
    this.words = [];
    this.currentPlayerIndex = 0;
    this.currentRound = 1;
    
    document.getElementById('current-round').textContent = this.currentRound;
    document.getElementById('current-word').textContent = `开始!主题:${this.currentTopic}`;
    
    this.renderWordList();
    this.renderPlayers();
    this.showNotification('游戏开始!轮到 ' + this.players[this.currentPlayerIndex], 'success');
}

启动流程:

  1. 初始化游戏状态
  2. 重置词汇列表和玩家索引
  3. 更新UI显示
  4. 渲染玩家状态
  5. 显示启动通知

5.2 词汇提交与验证

submitWord() {
    if (!this.gameStarted) {
        this.showNotification('请先点击"开始游戏"', 'warning');
        return;
    }
    
    const input = document.getElementById('word-input');
    const word = input.value.trim();
    
    if (!word) {
        this.showNotification('请输入物品名称', 'warning');
        input.focus();
        return;
    }
    
    if (this.isWordUsed(word)) {
        this.showNotification(`"${word}" 已经被说过了!`, 'error');
        input.focus();
        return;
    }
    
    if (!this.isWordValid(word)) {
        this.showNotification(`"${word}" 不属于${this.currentTopic}`, 'error');
        input.focus();
        return;
    }
    
    this.words.push({
        word: word,
        player: this.players[this.currentPlayerIndex]
    });
    
    this.lastWord = word;
    this.renderWordList();
    
    input.value = '';
    input.focus();
    
    this.showNotification(`${this.players[this.currentPlayerIndex]} 说出了:${word}`, 'success');
    
    this.nextPlayer();
}

验证流程:

用户输入 → 非空检查 → 重复检查 → 有效性检查 → 添加词汇 → 切换玩家

5.3 词汇重复检查

isWordUsed(word) {
    return this.words.some(w => w.word.toLowerCase() === word.toLowerCase());
}

检查逻辑:

  • 使用 toLowerCase() 进行大小写不敏感比较
  • 使用 Array.some() 方法遍历已说词汇
  • 返回布尔值表示是否重复

5.4 词汇有效性验证

isWordValid(word) {
    const validWords = this.topicWordList[this.currentTopic] || [];
    return validWords.some(w => w === word);
}

验证逻辑:

  • 根据当前主题获取有效词汇列表
  • 检查输入词汇是否在有效列表中
  • 精确匹配(区分大小写)

5.5 玩家轮次管理

nextPlayer() {
    this.currentPlayerIndex = (this.currentPlayerIndex + 1) % this.players.length;
    this.renderPlayers();
}

轮次计算:

使用取模运算实现循环:

玩家0 → 玩家1 → 玩家2 → 玩家0 → ...

六、界面渲染系统

6.1 玩家状态渲染

renderPlayers() {
    const section = document.getElementById('player-section');
    section.innerHTML = this.players.map((player, index) => 
        `<div class="player-tag ${index === this.currentPlayerIndex && this.gameStarted ? 'active' : 'inactive'}">${player}</div>`
    ).join('');
}

渲染逻辑:

状态 样式类 视觉效果
当前玩家 active 渐变背景 + 发光效果
其他玩家 inactive 灰色背景

6.2 词汇列表渲染

renderWordList() {
    const list = document.getElementById('word-list');
    
    if (this.words.length === 0) {
        list.innerHTML = `
            <div class="empty-state">
                <div class="icon">🎮</div>
                <h3>${this.gameStarted ? '等待玩家发言' : '游戏尚未开始'}</h3>
                <p>${this.gameStarted ? '输入符合主题的物品并提交' : '选择主题后点击开始游戏'}</p>
            </div>
        `;
        return;
    }
    
    list.innerHTML = this.words.map((item, index) => `
        <div class="word-item">
            <div class="word-number">${index + 1}</div>
            <div class="word-text">${item.word}</div>
            <div class="word-player">${item.player}</div>
        </div>
    `).join('');
    
    list.scrollTop = list.scrollHeight;
}

渲染特点:

  1. 空状态处理:显示友好提示
  2. 序号显示:每条词汇带有序号
  3. 归属标记:显示谁说的词汇
  4. 自动滚动:列表自动滚动到底部

6.3 主题选择渲染

document.querySelectorAll('.topic-tag').forEach(tag => {
    tag.addEventListener('click', (e) => {
        document.querySelectorAll('.topic-tag').forEach(t => t.classList.remove('active'));
        e.target.classList.add('active');
        this.currentTopic = e.target.dataset.topic;
        if (!this.gameStarted) {
            document.getElementById('current-word').textContent = `主题:${this.currentTopic}`;
        }
    });
});

交互逻辑:

  1. 点击主题标签
  2. 移除其他标签的激活状态
  3. 添加当前标签的激活状态
  4. 更新当前主题
  5. 如果游戏未开始,更新显示

七、玩家管理

7.1 添加玩家

addPlayer() {
    if (this.players.length >= 6) {
        this.showNotification('最多支持6名玩家', 'warning');
        return;
    }
    
    const newPlayer = `玩家${this.players.length + 1}`;
    this.players.push(newPlayer);
    this.renderPlayers();
    this.showNotification(`已添加 ${newPlayer}`, 'success');
}

限制条件:

  • 最多支持6名玩家
  • 玩家名称自动生成(玩家1、玩家2、…)
  • 添加后立即更新显示

7.2 玩家数据结构

players = ['玩家1', '玩家2', '玩家3']

设计考虑:

  • 使用简单数组存储玩家名称
  • 索引对应玩家顺序
  • 支持动态添加

八、通知系统

8.1 通知显示

showNotification(message, type = 'success') {
    const notification = document.getElementById('notification');
    const icon = document.getElementById('notification-icon');
    const msg = document.getElementById('notification-message');
    
    notification.className = `notification ${type}`;
    
    switch(type) {
        case 'success':
            icon.textContent = '✓';
            break;
        case 'error':
            icon.textContent = '✕';
            break;
        case 'warning':
            icon.textContent = '⚠';
            break;
    }
    
    msg.textContent = message;
    notification.classList.add('show');
    
    setTimeout(() => {
        notification.classList.remove('show');
    }, 3000);
}

通知类型:

类型 图标 颜色 用途
success 绿色 操作成功
error 红色 操作失败
warning 黄色 警告提示

九、游戏控制

9.1 重置游戏

resetGame() {
    this.gameStarted = false;
    this.words = [];
    this.currentPlayerIndex = 0;
    this.currentRound = 1;
    
    document.getElementById('current-round').textContent = 1;
    document.getElementById('current-word').textContent = '请选择主题开始游戏';
    document.getElementById('word-input').value = '';
    
    this.renderWordList();
    this.renderPlayers();
    
    document.querySelectorAll('.topic-tag').forEach(tag => tag.classList.remove('active'));
    document.querySelector('.topic-tag[data-topic="动物园"]').classList.add('active');
    this.currentTopic = '动物园';
    
    this.showNotification('游戏已重置', 'success');
}

重置内容:

  1. 游戏状态重置
  2. 词汇列表清空
  3. 玩家索引重置
  4. UI显示重置
  5. 默认主题恢复

9.2 再来一局

restartGame() {
    document.getElementById('game-over-modal').classList.remove('show');
    this.startGame();
}

流程:

  1. 关闭游戏结束弹窗
  2. 重新启动游戏

十、主题词汇数据库

10.1 动物园主题

'动物园': ['狮子', '老虎', '大象', '熊猫', '长颈鹿', '猴子', '斑马', '企鹅', 
          '海豚', '鳄鱼', '孔雀', '鹦鹉', '考拉', '袋鼠', '北极熊', '狼', 
          '狐狸', '熊', '蛇', '青蛙', '兔子', '猫', '狗', '马', '牛', 
          '羊', '猪', '鸡', '鸭', '鹅', '鸟']

10.2 植物园主题

'植物园': ['玫瑰', '菊花', '牡丹', '向日葵', '郁金香', '樱花', '荷花', '兰花', 
          '茉莉', '桂花', '梅花', '杜鹃', '百合', '康乃馨', '紫罗兰', '薰衣草', 
          '仙人掌', '绿萝', '吊兰', '多肉', '松树', '柳树', '杨树', '枫树', 
          '竹子', '银杏', '梧桐', '榕树', '椰子树', '棕榈树']

10.3 果园主题

'果园': ['苹果', '香蕉', '橙子', '葡萄', '西瓜', '草莓', '蓝莓', '樱桃', 
        '桃子', '李子', '梨子', '柿子', '石榴', '芒果', '榴莲', '菠萝', 
        '柚子', '柠檬', '猕猴桃', '火龙果', '荔枝', '龙眼', '木瓜', '哈密瓜', 
        '甜瓜', '山楂', '枣', '核桃', '栗子', '杏仁']

10.4 蔬菜园主题

'蔬菜园': ['西红柿', '黄瓜', '茄子', '辣椒', '胡萝卜', '土豆', '白菜', '菠菜', 
          '芹菜', '生菜', '西兰花', '菜花', '豆角', '豌豆', '玉米', '南瓜', 
          '冬瓜', '苦瓜', '丝瓜', '番茄', '洋葱', '大蒜', '生姜', '大葱', 
          '韭菜', '香菜', '蘑菇', '木耳', '海带', '紫菜']

10.5 花园主题

'花园': ['玫瑰', '月季', '牡丹', '芍药', '茉莉', '桂花', '荷花', '睡莲', 
        '郁金香', '风信子', '紫罗兰', '薰衣草', '向日葵', '雏菊', '康乃馨', 
        '百合', '兰花', '樱花', '梅花', '杜鹃', '海棠', '玉兰', '丁香', 
        '紫荆', '木槿', '芙蓉', '山茶', '栀子', '绣球', '鸢尾']

10.6 海洋馆主题

'海洋馆': ['海豚', '鲨鱼', '鲸鱼', '章鱼', '乌贼', '水母', '海龟', '海星', 
          '珊瑚', '海葵', '海马', '龙虾', '螃蟹', '贝类', '小丑鱼', '金鱼', 
          '鲤鱼', '三文鱼', '鳕鱼', '带鱼', '鳗鱼', '鱿鱼', '虾', '海蜇', 
          '海参', '鲍鱼', '扇贝', '牡蛎', '海螺', '海藻']

10.7 超市主题

'超市': ['牛奶', '面包', '鸡蛋', '大米', '面条', '食用油', '盐', '糖', 
        '酱油', '醋', '饮料', '零食', '水果', '蔬菜', '肉类', '海鲜', 
        '罐头', '方便面', '饼干', '巧克力', '薯片', '糖果', '坚果', '速冻食品', 
        '调味品', '日用品', '化妆品', '纸巾', '洗发水', '牙膏']

10.8 电器城主题

'电器城': ['电视', '冰箱', '洗衣机', '空调', '电脑', '手机', '平板', '耳机', 
          '音响', '微波炉', '烤箱', '电饭煲', '电磁炉', '电水壶', '豆浆机', 
          '榨汁机', '吸尘器', '电风扇', '加湿器', '空气净化器', '路由器', 
          '充电宝', '数据线', '充电器', '台灯', '手电筒', '游戏机', '相机', 
          '打印机', '扫描仪']

十一、响应式设计

11.1 媒体查询

@media (max-width: 600px) {
    .input-row {
        flex-direction: column;
    }

    .header h1 {
        font-size: 28px;
    }

    .btn-group {
        flex-wrap: wrap;
    }

    .btn-group .btn {
        flex: 1;
        min-width: calc(50% - 6px);
    }
}

适配策略:

屏幕宽度 调整内容
< 600px 输入框和按钮垂直排列
< 600px 标题字体缩小
< 600px 按钮组换行显示

11.2 布局特点

  • 弹性布局:使用 flexbox 实现响应式布局
  • 卡片设计:毛玻璃效果卡片
  • 渐变背景:深色渐变主题
  • 发光效果:当前玩家高亮

十二、性能优化

12.1 渲染优化

renderWordList() {
    const list = document.getElementById('word-list');
    
    if (this.words.length === 0) {
        list.innerHTML = `<div class="empty-state">...</div>`;
        return;
    }
    
    list.innerHTML = this.words.map(item => `...`).join('');
    list.scrollTop = list.scrollHeight;
}

优化措施:

  1. 一次性渲染:使用 innerHTML 批量更新
  2. 条件渲染:空状态提前返回
  3. 自动滚动:列表底部对齐

12.2 事件优化

setupEventListeners() {
    document.getElementById('word-input').addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
            this.submitWord();
        }
    });
}

优化策略:

  1. 键盘支持:Enter 键快捷提交
  2. 事件委托:减少事件监听器数量

十三、错误处理

13.1 输入验证

submitWord() {
    const word = input.value.trim();
    
    if (!word) {
        this.showNotification('请输入物品名称', 'warning');
        input.focus();
        return;
    }
    
    if (this.isWordUsed(word)) {
        this.showNotification(`"${word}" 已经被说过了!`, 'error');
        input.focus();
        return;
    }
    
    if (!this.isWordValid(word)) {
        this.showNotification(`"${word}" 不属于${this.currentTopic}`, 'error');
        input.focus();
        return;
    }
}

验证层次:

  1. 非空验证:检查输入是否为空
  2. 重复验证:检查是否已说过
  3. 有效性验证:检查是否符合主题

13.2 边界处理

addPlayer() {
    if (this.players.length >= 6) {
        this.showNotification('最多支持6名玩家', 'warning');
        return;
    }
}

边界条件:

  • 玩家数量上限检查
  • 游戏状态检查(未开始时不能提交)

十四、扩展功能设计

14.1 自定义主题

addCustomTopic(name, words) {
    if (!this.topicWordList[name]) {
        this.topicWordList[name] = words;
        // 更新UI添加新主题标签
    }
}

14.2 计分系统

// 为每个玩家添加分数
playerScores = {
    '玩家1': 0,
    '玩家2': 0,
    '玩家3': 0
};

// 正确回答加分
addScore(player) {
    this.playerScores[player]++;
}

14.3 时间限制

// 设置回答时间限制
setTimeout(() => {
    if (this.gameStarted) {
        this.showNotification(`${this.players[this.currentPlayerIndex]} 超时!`, 'warning');
        this.nextPlayer();
    }
}, 10000); // 10秒超时

十五、总结

逛三园游戏通过以下技术实现:

  1. 游戏状态管理:玩家轮次、词汇列表、主题选择
  2. 词汇验证系统:重复检查、有效性验证
  3. 界面渲染:实时更新玩家状态和词汇列表
  4. 通知系统:操作反馈和游戏提示
  5. 响应式设计:适配多种设备
  6. 性能优化:批量渲染、事件优化

该游戏展示了如何用简单的前端技术创建有趣的互动应用,适合聚会娱乐和团队活动使用。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐