项目概述

这是一个基于 Electron 开发的经典大富翁游戏桌面应用,完整实现了地块购买、房产建设、租金计算、机会卡 / 社区基金卡、监狱系统、拍卖交易等核心机制,支持 2-6 人多人对战及人机混合模式。本项目在保留所有原生功能的基础上,新增了鸿蒙 PC 平台专属适配方案,通过 Electron 鸿蒙适配层实现跨平台无缝运行,同时针对鸿蒙系统特性优化了性能、交互体验和系统集成能力,成为 Electron 迁移鸿蒙 PC 的实战标杆案例。

功能特性

  • 完整核心玩法:覆盖标准大富翁所有规则,包括地块管理、金融系统、监狱机制、随机事件等
  • 多人对战支持:2-6 名玩家参与,支持人机混合对战,AI 玩家智能决策
  • 丰富地产系统:普通地产、铁路、公共设施等多类型地块,支持房屋 / 酒店建设与抵押
  • 随机事件体系:机会卡与社区基金卡系统,触发多样化游戏事件
  • 交易与拍卖:玩家间资金 / 地产交易,未售出地块拍卖功能
  • 游戏存档加载:支持保存游戏进度,随时恢复对战状态
  • 响应式界面:适配不同窗口尺寸,鸿蒙 PC 端优化显示布局
  • 鸿蒙 PC 专属特性
    • 系统权限适配与安全存储
    • 鸿蒙窗口管理与快捷键兼容
    • 性能优化适配鸿蒙硬件架构
    • 系统通知与状态同步
    • 多窗口与分屏显示支持

技术栈

技术 / 组件 用途 相关代码位置 鸿蒙适配说明
Electron 跨平台桌面应用框架 <mcfile name="main.js" path="f:\0 demo\electron\electron-examples\54-monopoly\main.js"></mcfile> 采用 Electron 34 + 版本,兼容鸿蒙编译产物
JavaScript 游戏核心逻辑实现 <mcfile name="renderer.js" path="f:\0 demo\electron\electron-examples\54-monopoly\src\renderer.js"></mcfile> 核心逻辑不变,新增鸿蒙平台条件判断
HTML5/CSS3 游戏界面构建 <mcfile name="index.html" path="f:\0 demo\electron\electron-examples\54-monopoly\src\index.html"></mcfile>, <mcfile name="style.css" path="f:\0 demo\electron\electron-examples\54-monopoly\src\style.css"></mcfile> 优化鸿蒙端样式适配,支持系统主题切换
IPC 通信 主进程与渲染进程通信 <mcfile name="main.js" path="f:\0 demo\electron\electron-examples\54-monopoly\main.js"></mcfile> 扩展鸿蒙平台专属通信事件,支持系统交互
状态管理 游戏状态维护 <mcfile name="renderer.js" path="f:\0 demo\electron\electron-examples\54-monopoly\src\renderer.js"></mcfile> 新增鸿蒙平台状态字段,优化状态同步
鸿蒙适配层 系统兼容接口 ohos_hap/electron/libs/arm64-v8a/ 提供.so 核心库,实现 Electron 到鸿蒙 API 转换
DevEco Studio 鸿蒙开发工具 - 用于项目编译、调试、签名与部署

核心代码解析(含鸿蒙适配优化)

1. Electron 主进程(鸿蒙专属配置)

javascript

运行

function createMainWindow() {
    // 鸿蒙平台基础配置:禁用硬件加速避免兼容性问题
    if (process.platform === 'ohos') {
        app.disableHardwareAcceleration();
    }

    mainWindow = new BrowserWindow({
        width: 1200,
        height: 800,
        minWidth: 1000,
        minHeight: 700,
        title: '大富翁游戏 - Electron for 鸿蒙PC项目实战案例',
        webPreferences: {
            preload: path.join(__dirname, 'src', 'preload.js'),
            nodeIntegration: false,
            contextIsolation: true,
            enableRemoteModule: false
        },
        icon: path.join(__dirname, 'src', 'assets', 'icon.png'),
        backgroundColor: '#1a1a1a',
        show: false,
        frame: true,
        autoHideMenuBar: false,
        // 鸿蒙平台窗口行为优化
        skipTaskbar: process.platform === 'ohos' ? false : true,
        titleBarStyle: process.platform === 'ohos' ? 'default' : 'hidden'
    });

    // 鸿蒙平台窗口事件适配
    if (process.platform === 'ohos') {
        // 窗口最大化/还原适配鸿蒙系统规则
        mainWindow.on('maximize', () => {
            mainWindow.webContents.send('window-state-changed', 'maximized');
        });
        mainWindow.on('unmaximize', () => {
            mainWindow.webContents.send('window-state-changed', 'normal');
        });
        // 鸿蒙系统关闭确认
        mainWindow.on('close', (e) => {
            if (gameState.gameStarted && !gameState.gameOver) {
                e.preventDefault();
                mainWindow.webContents.send('confirm-exit', (confirmExit) => {
                    if (confirmExit) mainWindow.destroy();
                });
            }
        });
    }

    mainWindow.loadFile(path.join(__dirname, 'src', 'index.html'));
    mainWindow.once('ready-to-show', () => mainWindow.show());
}

// 扩展IPC通信:处理鸿蒙平台专属事件
ipcMain.on('game-action', (event, action, data) => {
    switch (action) {
        case 'new-game':
            initializeGame(data);
            break;
        case 'save-game':
            if (process.platform === 'ohos') {
                saveGameHarmony(data); // 鸿蒙专属存档逻辑
            } else {
                saveGameDefault(data); // 原生存档逻辑
            }
            break;
        case 'load-game':
            const gameData = process.platform === 'ohos' ? loadGameHarmony() : loadGameDefault();
            event.reply('game-loaded', gameData);
            break;
        // 其他游戏操作...
    }
});

// 鸿蒙平台游戏存档实现(使用系统安全存储目录)
function saveGameHarmony(gameData) {
    const savePath = path.join('/data/storage/el2/base/haps/', app.getName(), 'game-saves');
    try {
        // 确保目录存在
        fs.mkdirSync(savePath, { recursive: true });
        // 存档数据压缩(优化鸿蒙存储效率)
        const compressedData = Buffer.from(JSON.stringify(gameData)).toString('base64');
        fs.writeFileSync(path.join(savePath, `save_${Date.now()}.json`), compressedData);
        return true;
    } catch (err) {
        console.error('鸿蒙平台存档失败:', err);
        return false;
    }
}

// 鸿蒙平台游戏加载实现
function loadGameHarmony() {
    const savePath = path.join('/data/storage/el2/base/haps/', app.getName(), 'game-saves');
    try {
        if (!fs.existsSync(savePath)) return null;
        // 获取最新存档文件
        const files = fs.readdirSync(savePath).sort((a, b) => b.localeCompare(a));
        if (files.length === 0) return null;
        // 解压存档数据
        const compressedData = fs.readFileSync(path.join(savePath, files[0]), 'utf8');
        return JSON.parse(Buffer.from(compressedData, 'base64').toString());
    } catch (err) {
        console.error('鸿蒙平台加载存档失败:', err);
        return null;
    }
}

2. 游戏状态管理(新增鸿蒙适配字段)

javascript

运行

// 游戏状态(扩展鸿蒙平台专属配置)
const gameState = {
    players: [],                // 玩家列表
    currentPlayerIndex: 0,      // 当前玩家索引
    currentPlayer: null,        // 当前玩家
    board: [],                  // 棋盘数据
    gameStarted: false,         // 游戏是否开始
    gameOver: false,            // 游戏是否结束
    turnsInJail: {},            // 玩家在监狱的回合数
    doublesRolled: 0,           // 连续掷出对子的次数
    inJail: {},                 // 玩家是否在监狱
    getOutOfJailCards: {},      // 玩家持有的出狱卡数量
    chanceDeck: [],             // 机会卡 deck
    communityChestDeck: [],     // 社区基金卡 deck
    freeParkingMoney: 0,        // 免费停车区的钱
    currentDice: [1, 1],        // 当前骰子值
    diceRolled: false,          // 是否已掷骰子
    modalHandlers: {},          // 模态框处理器
    // 鸿蒙平台专属字段
    isHarmonyOS: process.platform === 'ohos', // 标识鸿蒙平台
    windowState: 'normal',      // 窗口状态(normal/maximized)
    systemTheme: 'light',       // 鸿蒙系统主题(跟随系统)
    saveSlot: 0                 // 当前存档槽位
};

// 初始化时同步鸿蒙系统主题
if (gameState.isHarmonyOS) {
    ipcRenderer.send('get-system-theme');
    ipcRenderer.on('system-theme-change', (event, theme) => {
        gameState.systemTheme = theme;
        document.documentElement.setAttribute('data-theme', theme);
        updateUITheme(); // 同步更新UI主题
    });
}

3. 渲染优化(鸿蒙平台性能适配)

javascript

运行

// 玩家棋子渲染(鸿蒙平台优化重绘逻辑)
function renderPlayersPieces() {
    const boardSpaces = document.querySelectorAll('.board-space');
    
    // 鸿蒙平台使用requestAnimationFrame优化动画流畅度
    if (gameState.isHarmonyOS) {
        requestAnimationFrame(() => {
            renderPiecesInternal(boardSpaces);
        });
    } else {
        renderPiecesInternal(boardSpaces);
    }
}

function renderPiecesInternal(boardSpaces) {
    // 清除现有棋子
    document.querySelectorAll('.player-piece').forEach(piece => piece.remove());
    
    // 渲染每个玩家的棋子
    gameState.players.forEach(player => {
        const spaceElement = boardSpaces[player.position];
        if (spaceElement) {
            const piece = document.createElement('div');
            piece.className = `player-piece player-${player.id}`;
            piece.style.backgroundColor = player.color;
            // 鸿蒙平台优化棋子大小和间距
            if (gameState.isHarmonyOS) {
                piece.style.width = '24px';
                piece.style.height = '24px';
                piece.style.margin = '2px';
                piece.style.borderWidth = '2px';
            }
            piece.title = player.name;
            spaceElement.appendChild(piece);
        }
    });
}

// 鸿蒙平台UI主题同步函数
function updateUITheme() {
    const root = document.documentElement;
    if (gameState.systemTheme === 'dark') {
        root.style.setProperty('--background-color', '#121212');
        root.style.setProperty('--text-color', '#ffffff');
        root.style.setProperty('--card-background', '#1e1e1e');
    } else {
        root.style.setProperty('--background-color', '#f5f5f5');
        root.style.setProperty('--text-color', '#333333');
        root.style.setProperty('--card-background', '#ffffff');
    }
}

4. AI 决策优化(适配鸿蒙设备性能)

javascript

运行

// AI玩家决策逻辑(鸿蒙平台优化计算效率)
function aiMakeDecision(player) {
    // 鸿蒙平台降低AI决策深度,提升响应速度
    const decisionDepth = gameState.isHarmonyOS ? 2 : 3;
    
    setTimeout(() => {
        const decision = gameState.isHarmonyOS 
            ? aiDecideOptimized(player, decisionDepth) 
            : aiDecideFull(player, decisionDepth);
        
        executeAIDecision(player, decision);
    }, gameState.isHarmonyOS ? 300 : 500);
}

// 鸿蒙平台优化版AI决策
function aiDecideOptimized(player, depth) {
    // 简化决策树,优先处理核心操作
    const currentSpace = gameState.board[player.position];
    
    // 1. 处理可购买的地产
    if (currentSpace.type === GAME_CONSTANTS.SPACE_TYPES.PROPERTY && 
        !currentSpace.owner && player.money >= currentSpace.price) {
        // 鸿蒙平台AI更倾向于购买颜色组地产
        const groupProperties = gameState.board.filter(
            s => s.group === currentSpace.group && s.type === GAME_CONSTANTS.SPACE_TYPES.PROPERTY
        );
        const ownedInGroup = groupProperties.filter(s => s.owner === player.id).length;
        
        if (ownedInGroup > 0 || currentSpace.price < player.money * 0.3) {
            return { action: 'buy' };
        }
    }
    
    // 2. 处理监狱状态
    if (gameState.inJail[player.id]) {
        return aiHandleJail(player);
    }
    
    // 3. 其他决策逻辑(简化版)
    return { action: 'end-turn' };
}

5. 鸿蒙系统集成(通知与权限)

javascript

运行

// 游戏事件通知(集成鸿蒙系统通知)
function showGameMessage(message, type = 'info') {
    const messageElement = document.createElement('div');
    messageElement.className = `game-message game-message-${type}`;
    messageElement.textContent = message;
    document.getElementById('message-container').appendChild(messageElement);
    
    // 鸿蒙平台发送系统通知
    if (gameState.isHarmonyOS && type === 'important') {
        ipcRenderer.send('show-system-notification', {
            title: '大富翁游戏',
            body: message
        });
    }
    
    // 自动移除消息
    setTimeout(() => {
        messageElement.classList.add('fade-out');
        setTimeout(() => messageElement.remove(), 500);
    }, 3000);
}

// 鸿蒙平台权限检查(存档/读取权限)
ipcRenderer.on('check-permission', (event, permissionType) => {
    if (permissionType === 'storage') {
        // 检查鸿蒙存储权限
        const hasPermission = checkHarmonyStoragePermission();
        event.reply('permission-result', hasPermission);
    }
});

function checkHarmonyStoragePermission() {
    try {
        const testPath = path.join('/data/storage/el2/base/haps/', app.getName(), 'test.txt');
        fs.writeFileSync(testPath, 'test');
        fs.unlinkSync(testPath);
        return true;
    } catch (err) {
        console.error('鸿蒙存储权限不足:', err);
        return false;
    }
}

项目结构(鸿蒙 PC 适配版)

原始 Electron 项目结构

plaintext

54-monopoly/
├── main.js          # Electron主进程脚本(含鸿蒙适配代码)
├── package.json     # 项目配置和依赖
└── src/             # 渲染进程相关文件
    ├── index.html   # 游戏界面HTML
    ├── preload.js   # 预加载脚本
    ├── renderer.js  # 游戏逻辑实现(含鸿蒙优化)
    ├── style.css    # 样式文件(适配鸿蒙主题)
    └── assets/      # 图像资源目录

鸿蒙 PC 适配后项目结构

plaintext

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/
│                               ├── index.html
│                               ├── preload.js
│                               ├── renderer.js
│                               ├── style.css
│                               └── assets/
└── module.json5        # 鸿蒙应用配置文件

鸿蒙 PC 适配改造指南

1. 环境准备

  • 开发环境:Windows 10/11、8GB RAM 以上、20GB 可用空间
  • 运行环境:鸿蒙 PC 系统(API 20+)
  • 工具安装
    • DevEco Studio 5.0+(安装鸿蒙 SDK API 20+)
    • Node.js 18.x+
    • Electron 34+(兼容鸿蒙的版本)
    • 鸿蒙系统设备(开启开发者模式)

2. 改造步骤

步骤 1:获取 Electron 鸿蒙编译产物
  1. 登录Electron 鸿蒙官方仓库
  2. 下载 Electron 34 + 版本的 Release 包(.zip 格式)
  3. 解压到项目目录,确认electron/libs/arm64-v8a/下包含 4 个核心.so 库文件
步骤 2:应用代码适配改造
  1. 主进程改造(main.js):

    • 添加鸿蒙平台判断(process.platform === 'ohos'
    • 禁用硬件加速(app.disableHardwareAcceleration()
    • 优化窗口行为与系统事件处理
    • 实现鸿蒙专属存档 / 加载逻辑(使用系统安全存储目录)
  2. 渲染进程改造(renderer.js):

    • 扩展游戏状态,添加鸿蒙平台标识字段
    • 优化渲染逻辑,使用requestAnimationFrame提升动画流畅度
    • 简化 AI 决策深度,适配鸿蒙设备性能
    • 集成鸿蒙系统主题同步功能
  3. 样式适配(style.css):

    • 添加鸿蒙系统主题支持(明 / 暗模式)
    • 优化控件尺寸与间距,适配鸿蒙窗口
    • 简化复杂 CSS 动画,减少重绘开销
  4. 配置文件改造

    • 编辑package.json,添加鸿蒙平台依赖声明
    • 配置module.json5,声明应用权限与系统能力
步骤 3:部署应用代码

按鸿蒙项目目录结构,将适配后的 Electron 应用代码放置到以下路径:

plaintext

web_engine/src/main/resources/resfile/resources/app/

确保目录结构完整,包含所有核心文件(main.js、package.json、src 文件夹等)

步骤 4:鸿蒙应用配置(module.json5)

json5

{
  "module": {
    "name": "monopoly-game",
    "type": "app",
    "srcPath": "./",
    "deviceTypes": ["pc"],
    "reqSysCapabilities": [
      "internet",
      "storage",
      "window",
      "notification",
      "file.access"
    ],
    "version": {
      "code": 10000,
      "name": "1.0.0"
    },
    "distro": {
      "deliveryWithInstall": true,
      "moduleName": "monopoly-game",
      "moduleType": "entry"
    },
    "abilities": [
      {
        "name": "MainAbility",
        "srcPath": "./web_engine",
        "icon": "$media:icon",
        "description": "$string:main_ability_description",
        "formsEnabled": false,
        "visible": true,
        "skills": [
          {
            "entities": ["entity.system.launcher"],
            "actions": ["action.system.home"]
          }
        ]
      }
    ]
  }
}
步骤 5:编译运行
  1. 打开项目:在 DevEco Studio 中打开 ohos_hap 目录
  2. 配置签名:进入 File → Project Structure → Signing Configs,生成或导入调试签名
  3. 连接设备:启用鸿蒙 PC 开发者模式和 USB 调试,通过 USB Type-C 连接电脑
  4. 编译运行:点击 Run 按钮或按 Shift+F10,等待应用安装启动

3. 验证检查项

  • ✅ 应用在鸿蒙 PC 上正常启动,窗口显示完整无异常
  • ✅ 响应式布局生效,窗口缩放时 UI 组件自适应
  • ✅ 所有游戏功能(掷骰子、购买、建设、交易等)正常工作
  • ✅ AI 玩家决策逻辑正常,无卡顿或卡死现象
  • ✅ 游戏存档 / 加载功能正常,数据持久化可靠
  • ✅ 鸿蒙系统主题同步生效,明 / 暗模式切换正常
  • ✅ 系统通知功能正常,重要事件触发通知
  • ✅ 控制台无 "SysCap 不匹配" 或 "找不到.so 文件" 等错误
  • ✅ 长时间运行无内存泄漏,性能稳定

跨平台兼容性说明

平台 适配策略 特殊处理
Windows 标准 Electron 运行 无特殊配置,保留原生功能
macOS 标准 Electron 运行 保留 dock 图标激活逻辑
Linux 标准 Electron 运行 确保系统依赖库完整
鸿蒙 PC 通过 Electron 鸿蒙适配层 1. 禁用硬件加速;2. 系统安全存储;3. 渲染性能优化;4. 主题同步;5. 权限管理;6. AI 决策简化

鸿蒙开发调试技巧

1. 日志调试

  • 在 DevEco Studio 的 Log 面板中过滤 "Electron" 或 "Monopoly" 关键词,查看应用运行日志
  • 鸿蒙平台专属日志使用console.log('[HarmonyOS]', message)标识,便于区分
  • 利用鸿蒙系统日志工具(hdc logcat)查看底层运行日志

2. 常见问题解决

  • "SysCap 不匹配" 错误:检查 module.json5 中的 reqSysCapabilities,仅保留必要系统能力
  • "找不到.so 文件" 错误:确认 arm64-v8a 目录下 4 个核心库文件完整,版本与 Electron 匹配
  • 窗口不显示:确保已添加app.disableHardwareAcceleration(),检查窗口尺寸配置
  • 动画卡顿:简化 CSS 动画,减少同时渲染的元素数量,优化 AI 决策逻辑
  • 存档失败:检查存储权限配置,确保应用拥有file.access系统能力
  • 主题切换异常:确认系统主题监听事件正确注册,UI 样式使用 CSS 变量实现

3. 性能调试工具

  • 使用 DevEco Studio 的 Performance 面板分析渲染性能
  • 开启 Electron 开发者工具(Ctrl+Shift+I)查看控制台错误与性能瓶颈
  • 利用鸿蒙系统的内存监控工具,检查内存泄漏问题

性能优化建议(鸿蒙平台专属)

  1. 渲染优化

    • 采用事件委托机制,减少棋盘地块的事件监听器数量
    • 仅在状态变化时更新必要的 UI 组件,避免全量重绘
    • 使用 CSS 变量替代动态样式修改,提升渲染效率
  2. AI 决策优化

    • 实现 AI 决策结果缓存,避免重复计算
    • 按游戏阶段动态调整决策深度(前期简化,后期增强)
    • 优先处理核心决策(购买、建设),次要决策使用默认策略
  3. 存储优化

    • 存档数据压缩(Base64 或 LZ77 算法),减少存储空间占用
    • 实现存档自动清理机制,保留最近 3 个存档文件
    • 使用 IndexedDB 存储大量游戏数据,提升读取速度
  4. 内存管理

    • 及时清理未使用的 DOM 元素和事件监听器
    • 限制同时显示的游戏消息数量(最多保留 5 条)
    • 优化玩家棋子渲染,避免重复创建 DOM 节点

总结

项目代码结构清晰、游戏机制完整,适配过程中在保持核心玩法不变的前提下,针对鸿蒙 PC 平台的性能特点进行了针对性优化,既适合开发者学习 Electron 游戏开发,也为跨平台应用改造提供了可复用的实践方案。

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐