基于Electron开发的跨平台鸿蒙PC剪刀石头布游戏应用
这个剪刀石头布游戏项目展示了如何在Electron环境中构建简单而完整的桌面游戏应用。游戏引擎设计:实现了剪刀石头布的核心规则和胜负判定算法AI决策系统:提供三种难度级别的AI对手,包括学习型AI动画与视觉反馈:创建流畅的游戏动画和直观的结果显示用户体验优化:提供多种游戏模式和自定义选项性能与错误处理:确保应用稳定运行和良好性能。
项目概述
这是一个基于Electron开发的剪刀石头布游戏应用,实现了经典的剪刀石头布对战游戏。本项目展示了如何在Electron环境中构建简洁的桌面游戏应用,包含游戏逻辑处理、AI决策系统、用户界面交互和分数记录等核心功能。游戏支持玩家与电脑进行对战,提供了直观的交互体验和实时的游戏反馈。
技术架构
项目采用Electron主进程-渲染进程架构,主要分为以下几个核心模块:
- 主进程模块:负责窗口管理和应用生命周期
- 渲染进程模块:包含游戏核心逻辑、UI渲染和用户交互
- 游戏逻辑引擎:处理剪刀石头布的核心规则和游戏流程
- AI决策系统:实现电脑对手的决策逻辑
- 分数记录系统:追踪和显示游戏历史记录
- 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);
}
用户交互系统的特点:
- 提供直观的按钮界面进行选择
- 支持难度和游戏模式的自定义设置
- 实现防误触机制避免游戏中断
- 使用事件委托优化事件处理
游戏模式与功能
游戏模式
游戏支持多种对战模式:
- 单局模式:每局独立计分,适合快速游戏
- 三局两胜:先赢两局者获胜,增加游戏策略性
- 五局三胜:先赢三局者获胜,提供更长的游戏体验
难度设置
游戏提供三种难度级别:
| 难度 | 特点 | 实现方式 | 适合人群 |
|---|---|---|---|
| 简单 | 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动画增强视觉体验
- 响应式设计适配不同屏幕尺寸
- 清晰的结果反馈和状态显示
性能优化策略
-
动画性能优化:
- 使用CSS transition和transform实现流畅动画
- 避免在动画期间进行复杂计算
- 使用requestAnimationFrame优化动画性能
-
内存管理:
- 合理管理历史数据,避免无限增长
- 及时移除不再需要的事件监听器
- 使用WeakMap/WeakSet存储非关键引用
-
渲染优化:
- 最小化DOM操作频率
- 使用CSS类切换替代直接样式修改
- 采用批处理方式更新UI
-
代码结构优化:
- 模块化设计提高代码可维护性
- 避免全局状态污染
- 使用闭包保护私有数据
错误处理与容错机制
应用实现了完善的错误处理机制:
// 错误处理函数
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鸿蒙编译产物
-
下载Electron 34+版本的Release包(.zip格式)
-
解压到项目目录,确认
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. 配置与运行
-
打开项目:在DevEco Studio中打开ohos_hap目录
-
配置签名:
进入File → Project Structure → Signing Configs -
自动生成调试签名或导入已有签名
-
连接设备:
启用鸿蒙设备开发者模式和USB调试 -
通过USB Type-C连接电脑
-
编译运行:点击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环境中构建简单而完整的桌面游戏应用。核心技术亮点包括:
- 游戏引擎设计:实现了剪刀石头布的核心规则和胜负判定算法
- AI决策系统:提供三种难度级别的AI对手,包括学习型AI
- 动画与视觉反馈:创建流畅的游戏动画和直观的结果显示
- 用户体验优化:提供多种游戏模式和自定义选项
- 性能与错误处理:确保应用稳定运行和良好性能
更多推荐
所有评论(0)