项目概述

这是一个基于Electron开发的剪刀石头布游戏应用,实现了经典的剪刀石头布对战游戏。本项目展示了如何在Electron环境中构建简洁的桌面游戏应用,包含游戏逻辑处理、AI决策系统、用户界面交互和分数记录等核心功能。游戏支持玩家与电脑进行对战,提供了直观的交互体验和实时的游戏反馈。
请添加图片描述

技术架构

项目采用Electron主进程-渲染进程架构,主要分为以下几个核心模块:

  1. 主进程模块:负责窗口管理和应用生命周期
  2. 渲染进程模块:包含游戏核心逻辑、UI渲染和用户交互
  3. 游戏逻辑引擎:处理剪刀石头布的核心规则和游戏流程
  4. AI决策系统:实现电脑对手的决策逻辑
  5. 分数记录系统:追踪和显示游戏历史记录
  6. UI渲染系统:负责游戏界面的绘制和动画效果

核心算法实现

1. 游戏核心逻辑

游戏实现了剪刀石头布的基本规则和游戏流程:

// 游戏选项定义
const OPTIONS = ['rock', 'paper', 'scissors'];

// 胜负判定逻辑
function determineWinner(playerChoice, computerChoice) {
  // 平局情况
  if (playerChoice === computerChoice) {
    return 'tie';
  }
  
  // 胜负判断规则
  // 石头击败剪刀
  // 剪刀击败布
  // 布击败石头
  const winConditions = {
    'rock': 'scissors',
    'scissors': 'paper',
    'paper': 'rock'
  };
  
  // 判断玩家是否获胜
  if (winConditions[playerChoice] === computerChoice) {
    return 'player';
  } else {
    return 'computer';
  }
}

游戏核心逻辑的特点:

  • 使用映射表实现胜负判定,提高代码可读性
  • 支持三种游戏选项:石头、剪刀、布
  • 处理平局、玩家胜利和电脑胜利三种情况
  • 易于扩展支持更多游戏选项(如剪刀石头布蜥蜴史波克)

2. AI决策系统

游戏实现了电脑对手的决策逻辑,提供不同难度级别:

// AI决策系统
function getComputerChoice(difficulty = 'normal') {
  switch (difficulty) {
    case 'easy':
      // 简单模式:有固定的偏好选择
      return easyAIStrategy();
    case 'normal':
      // 普通模式:随机选择
      return randomChoice();
    case 'hard':
      // 困难模式:学习玩家的选择模式
      return learningAIStrategy();
    default:
      return randomChoice();
  }
}

// 随机选择策略
function randomChoice() {
  const randomIndex = Math.floor(Math.random() * OPTIONS.length);
  return OPTIONS[randomIndex];
}

// 简单AI策略:有固定偏好
function easyAIStrategy() {
  // 60%概率选择石头,20%概率选择剪刀,20%概率选择布
  const rand = Math.random();
  if (rand < 0.6) return 'rock';
  if (rand < 0.8) return 'scissors';
  return 'paper';
}

// 学习型AI策略:根据玩家历史选择预测
function learningAIStrategy() {
  // 收集玩家的历史选择数据
  const playerHistory = gameState.playerHistory;
  
  // 如果历史数据不足,使用随机选择
  if (playerHistory.length < 3) {
    return randomChoice();
  }
  
  // 分析玩家最近的选择
  const lastChoice = playerHistory[playerHistory.length - 1];
  
  // 简单的预测策略:假设玩家会切换到下一个选项
  const choiceIndex = OPTIONS.indexOf(lastChoice);
  const predictedCounterChoice = OPTIONS[(choiceIndex + 1) % OPTIONS.length];
  
  // 选择克制预测选项的牌
  const counterChoice = {
    'rock': 'paper',
    'paper': 'scissors',
    'scissors': 'rock'
  }[predictedCounterChoice];
  
  return counterChoice;
}

AI决策系统的设计特点:

  • 实现三种难度级别:简单、普通、困难
  • 简单模式:有明显的选择偏好,容易被预测
  • 普通模式:完全随机选择,公平竞争
  • 困难模式:学习型AI,根据玩家历史选择调整策略
  • 使用马尔可夫链思想预测玩家行为模式

3. 游戏状态管理

游戏使用集中式状态管理,跟踪游戏进度和结果:

// 游戏状态
const gameState = {
  playerScore: 0,
  computerScore: 0,
  ties: 0,
  totalGames: 0,
  playerHistory: [],
  computerHistory: [],
  currentRound: 1,
  gameMode: 'bestOfThree', // bestOfThree, bestOfFive, singleGame
  difficulty: 'normal', // easy, normal, hard
  isAnimating: false
};

// 更新游戏状态
function updateGameState(result, playerChoice, computerChoice) {
  // 更新分数
  switch (result) {
    case 'player':
      gameState.playerScore++;
      break;
    case 'computer':
      gameState.computerScore++;
      break;
    case 'tie':
      gameState.ties++;
      break;
  }
  
  // 更新历史记录
  gameState.playerHistory.push(playerChoice);
  gameState.computerHistory.push(computerChoice);
  gameState.totalGames++;
  
  // 检查游戏结束条件
  checkGameEnd();
  
  // 更新UI
  updateScoreDisplay();
  updateHistoryDisplay();
}

状态管理的设计特点:

  • 跟踪玩家和电脑的分数统计
  • 记录游戏历史,用于AI学习和数据分析
  • 支持多种游戏模式:单局、三局两胜、五局三胜
  • 提供游戏进度和状态的实时更新

4. 动画与视觉反馈系统

游戏实现了流畅的动画和视觉反馈效果:

// 播放选择动画
function playChoiceAnimation(playerChoice, computerChoice) {
  gameState.isAnimating = true;
  
  // 禁用按钮防止重复点击
  disableButtons(true);
  
  // 显示倒计时动画
  const countdownElement = document.getElementById('countdown');
  countdownElement.textContent = '3';
  countdownElement.style.display = 'block';
  
  // 倒计时动画
  setTimeout(() => {
    countdownElement.textContent = '2';
    setTimeout(() => {
      countdownElement.textContent = '1';
      setTimeout(() => {
        countdownElement.textContent = 'Go!';
        
        // 显示双方选择
        showChoices(playerChoice, computerChoice);
        
        // 延迟后显示结果
        setTimeout(() => {
          showResult(result);
          
          // 更新状态
          updateGameState(result, playerChoice, computerChoice);
          
          // 重置UI为下一轮
          setTimeout(() => {
            resetRound();
            gameState.isAnimating = false;
            disableButtons(false);
          }, 2000);
        }, 1000);
      }, 1000);
    }, 1000);
  }, 1000);
}

动画系统的特点:

  • 实现倒计时动画增强游戏体验
  • 提供选择和结果的视觉反馈
  • 使用时间延迟创建流畅的动画序列
  • 在动画期间禁用交互防止误操作
  • 确保UI更新与状态同步

5. 用户交互处理

游戏实现了友好的用户交互系统:

// 初始化事件监听器
function initEventListeners() {
  // 选择按钮事件
  document.getElementById('rock-btn').addEventListener('click', () => makeChoice('rock'));
  document.getElementById('paper-btn').addEventListener('click', () => makeChoice('paper'));
  document.getElementById('scissors-btn').addEventListener('click', () => makeChoice('scissors'));
  
  // 重新开始按钮
  document.getElementById('restart-btn').addEventListener('click', restartGame);
  
  // 难度选择
  document.getElementById('difficulty-easy').addEventListener('change', () => {
    if (this.checked) gameState.difficulty = 'easy';
  });
  document.getElementById('difficulty-normal').addEventListener('change', () => {
    if (this.checked) gameState.difficulty = 'normal';
  });
  document.getElementById('difficulty-hard').addEventListener('change', () => {
    if (this.checked) gameState.difficulty = 'hard';
  });
  
  // 游戏模式选择
  document.getElementById('mode-single').addEventListener('change', () => {
    if (this.checked) gameState.gameMode = 'singleGame';
  });
  document.getElementById('mode-bestOfThree').addEventListener('change', () => {
    if (this.checked) gameState.gameMode = 'bestOfThree';
  });
  document.getElementById('mode-bestOfFive').addEventListener('change', () => {
    if (this.checked) gameState.gameMode = 'bestOfFive';
  });
}

// 玩家做出选择
function makeChoice(choice) {
  // 防止在动画期间重复点击
  if (gameState.isAnimating) return;
  
  // 获取电脑选择
  const computerChoice = getComputerChoice(gameState.difficulty);
  
  // 确定胜负
  const result = determineWinner(choice, computerChoice);
  
  // 播放动画并显示结果
  playChoiceAnimation(choice, computerChoice);
}

用户交互系统的特点:

  • 提供直观的按钮界面进行选择
  • 支持难度和游戏模式的自定义设置
  • 实现防误触机制避免游戏中断
  • 使用事件委托优化事件处理

游戏模式与功能

游戏模式

游戏支持多种对战模式:

  1. 单局模式:每局独立计分,适合快速游戏
  2. 三局两胜:先赢两局者获胜,增加游戏策略性
  3. 五局三胜:先赢三局者获胜,提供更长的游戏体验

难度设置

游戏提供三种难度级别:

难度 特点 实现方式 适合人群
简单 AI有明显选择偏好 加权随机选择,倾向于石头 初学者、儿童
普通 AI完全随机选择 等概率随机选择 休闲玩家
困难 AI会学习玩家模式 分析历史数据,预测玩家行为 有经验玩家

统计与分析

游戏提供详细的统计功能:

// 计算胜率
function calculateStats() {
  const totalGames = gameState.totalGames;
  if (totalGames === 0) return { winRate: 0, choiceDistribution: {} };
  
  // 计算胜率
  const winRate = (gameState.playerScore / totalGames) * 100;
  
  // 分析玩家选择分布
  const choiceDistribution = {};
  OPTIONS.forEach(option => {
    const count = gameState.playerHistory.filter(choice => choice === option).length;
    choiceDistribution[option] = {
      count,
      percentage: ((count / totalGames) * 100).toFixed(1)
    };
  });
  
  return { winRate: winRate.toFixed(1), choiceDistribution };
}

统计功能的特点:

  • 计算玩家的胜率和游戏数据
  • 分析玩家的选择偏好和模式
  • 提供可视化的统计图表
  • 帮助玩家改进游戏策略

Electron应用架构

主进程实现

应用的主进程负责窗口管理和应用生命周期:

// Electron主进程代码
const { app, BrowserWindow } = require('electron');
const path = require('path');

// 保持对window对象的全局引用
let mainWindow;

function createWindow() {
  // 创建浏览器窗口
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    title: '剪刀石头布游戏',
    resizable: true,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  // 加载应用的index.html
  mainWindow.loadFile(path.join(__dirname, 'index.html'));
  
  // 窗口关闭时触发
  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

// 应用事件处理
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

渲染进程与UI设计

渲染进程负责游戏逻辑和用户界面:

// 更新分数显示
function updateScoreDisplay() {
  document.getElementById('player-score').textContent = gameState.playerScore;
  document.getElementById('computer-score').textContent = gameState.computerScore;
  document.getElementById('ties-count').textContent = gameState.ties;
  document.getElementById('total-games').textContent = gameState.totalGames;
}

// 显示选择结果
function showResult(result) {
  const resultElement = document.getElementById('result');
  
  switch (result) {
    case 'player':
      resultElement.textContent = '你赢了!';
      resultElement.className = 'result win';
      break;
    case 'computer':
      resultElement.textContent = '电脑赢了!';
      resultElement.className = 'result lose';
      break;
    case 'tie':
      resultElement.textContent = '平局!';
      resultElement.className = 'result tie';
      break;
  }
  
  resultElement.style.display = 'block';
}

UI设计的特点:

  • 简洁直观的用户界面
  • 使用CSS动画增强视觉体验
  • 响应式设计适配不同屏幕尺寸
  • 清晰的结果反馈和状态显示

性能优化策略

  1. 动画性能优化

    • 使用CSS transition和transform实现流畅动画
    • 避免在动画期间进行复杂计算
    • 使用requestAnimationFrame优化动画性能
  2. 内存管理

    • 合理管理历史数据,避免无限增长
    • 及时移除不再需要的事件监听器
    • 使用WeakMap/WeakSet存储非关键引用
  3. 渲染优化

    • 最小化DOM操作频率
    • 使用CSS类切换替代直接样式修改
    • 采用批处理方式更新UI
  4. 代码结构优化

    • 模块化设计提高代码可维护性
    • 避免全局状态污染
    • 使用闭包保护私有数据

错误处理与容错机制

应用实现了完善的错误处理机制:

// 错误处理函数
function handleError(error) {
  console.error('游戏错误:', error);
  
  // 尝试恢复游戏状态
  try {
    resetGame();
    showNotification('游戏发生错误,已重置。', 'error');
  } catch (err) {
    // 显示错误对话框
    electronAPI.dialog.showMessageBox({
      type: 'error',
      title: '游戏错误',
      message: '游戏发生错误,请尝试重启应用。'
    });
  }
}

// 初始化错误处理
window.addEventListener('error', (event) => {
  handleError(event.error);
  event.preventDefault();
});

window.addEventListener('unhandledrejection', (event) => {
  handleError(event.reason);
  event.preventDefault();
});

容错机制的特点:

  • 捕获并处理运行时错误
  • 实现优雅的错误恢复机制
  • 提供用户友好的错误提示
  • 防止应用崩溃影响用户体验

开发与构建

安装依赖

npm install

开发模式运行

npm start

打包构建

npm run build

鸿蒙适配后结构(需整合到 Electron 鸿蒙项目模板中):


ohos_hap/
├── electron/
│   ├── libs/
│   │   └── arm64-v8a/  # 鸿蒙核心库文件
│   │       ├── libelectron.so
│   │       ├── libadapter.so
│   │       ├── libffmpeg.so
│   │       └── libc++_shared.so
├── web_engine/
│   └── src/
│       └── main/
│           └── resources/
│               └── resfile/
│                   └── resources/
│                       └── app/  # 放置electron应用代码
│                           ├── main.js
│                           ├── package.json
│                           └── src/
└── module.json5        # 鸿蒙应用配置文件

鸿蒙PC适配改造指南

1. 环境准备

  • 系统要求:Windows 10/11、8GB RAM以上、20GB可用空间

  • 工具安装
    DevEco Studio 5.0+(安装鸿蒙SDK API 20+)

  • Node.js 18.x+

2. 获取Electron鸿蒙编译产物

  1. 登录Electron 鸿蒙官方仓库

  2. 下载Electron 34+版本的Release包(.zip格式)

  3. 解压到项目目录,确认electron/libs/arm64-v8a/下包含核心.so库

3. 部署应用代码

将Electron应用代码按以下目录结构放置:
在这里插入图片描述


web_engine/src/main/resources/resfile/resources/app/
├── main.js
├── package.json
└── src/
    ├── index.html
    ├── preload.js
    ├── renderer.js
    └── style.css

4. 配置与运行

  1. 打开项目:在DevEco Studio中打开ohos_hap目录

  2. 配置签名
    进入File → Project Structure → Signing Configs

  3. 自动生成调试签名或导入已有签名

  4. 连接设备
    启用鸿蒙设备开发者模式和USB调试

  5. 通过USB Type-C连接电脑

  6. 编译运行:点击Run按钮或按Shift+F10

5. 验证检查项

  • ✅ 应用窗口正常显示

  • ✅ 窗口大小可调整,响应式布局生效

  • ✅ 控制台无"SysCap不匹配"或"找不到.so文件"错误

  • ✅ 动画效果正常播放

跨平台兼容性

平台 适配策略 特殊处理
Windows 标准Electron运行 无特殊配置
macOS 标准Electron运行 保留dock图标激活逻辑
Linux 标准Electron运行 确保系统依赖库完整
鸿蒙PC 通过Electron鸿蒙适配层 禁用硬件加速,使用特定目录结构

鸿蒙开发调试技巧

1. 日志查看

在DevEco Studio的Log面板中过滤"Electron"关键词,查看应用运行日志和错误信息。

2. 常见问题解决

  • "SysCap不匹配"错误:检查module.json5中的reqSysCapabilities,只保留必要系统能力

  • "找不到.so文件"错误:确认arm64-v8a目录下四个核心库文件完整

  • 窗口不显示:在main.js中添加app.disableHardwareAcceleration()

  • 动画卡顿:简化CSS动画效果,减少重绘频率

总结

这个剪刀石头布游戏项目展示了如何在Electron环境中构建简单而完整的桌面游戏应用。核心技术亮点包括:

  1. 游戏引擎设计:实现了剪刀石头布的核心规则和胜负判定算法
  2. AI决策系统:提供三种难度级别的AI对手,包括学习型AI
  3. 动画与视觉反馈:创建流畅的游戏动画和直观的结果显示
  4. 用户体验优化:提供多种游戏模式和自定义选项
  5. 性能与错误处理:确保应用稳定运行和良好性能
Logo

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

更多推荐