Electron for鸿蒙PC实战项目之多功能迷宫生成器
这是一个基于 Electron 开发的多功能迷宫生成器应用,为开发者提供了算法可视化与桌面应用开发的优质案例。项目支持多种经典迷宫生成算法(DFS、BFS、Prim 等)和智能求解算法(A*),用户可自定义迷宫参数、可视化观察生成与求解过程,并支持迷宫导出功能。同时,本项目已完成鸿蒙 PC 平台适配改造,可在鸿蒙 PC 系统上稳定运行,兼顾算法学习、Electron 开发与跨平台实践需求,适合进阶
项目概述
这是一个基于 Electron 开发的多功能迷宫生成器应用,为开发者提供了算法可视化与桌面应用开发的优质案例。项目支持多种经典迷宫生成算法(DFS、BFS、Prim 等)和智能求解算法(A*),用户可自定义迷宫参数、可视化观察生成与求解过程,并支持迷宫导出功能。同时,本项目已完成鸿蒙 PC 平台适配改造,可在鸿蒙 PC 系统上稳定运行,兼顾算法学习、Electron 开发与跨平台实践需求,适合进阶开发者深入研究。

功能特性
- 🧠 多种迷宫生成算法:深度优先搜索 (DFS)、广度优先搜索 (BFS)、Prim 算法、Kruskal 算法、Aldous-Broder 算法、Wilson 算法,覆盖不同迷宫特性需求
- 🎯 智能路径求解:A * 算法实现最优路径寻找,可视化展示搜索与路径生成过程
- 🎨 丰富交互功能:自定义迷宫尺寸 / 单元格大小、调节动画速度、手动设置起点 / 终点、迷宫重置 / 路径清除
- 💾 灵活导出功能:支持迷宫保存为图片、导出迷宫数据为 JSON 格式
- 📊 全面性能统计:生成时间、求解时间、路径长度实时统计与展示
- 🖥️ 跨平台兼容:Windows、macOS、Linux 及鸿蒙 PC 系统,支持响应式布局与全屏模式
- 🛠️ 鸿蒙 PC 适配优化:针对鸿蒙系统特性优化渲染性能、适配系统权限与交互机制
目录结构
原始 Electron 目录结构
plaintext
49-maze-generator/
├── README.md # 项目文档
├── main.js # Electron主进程
├── package.json # 项目配置和依赖
└── src/ # 渲染进程源码
├── index.html # 应用主页面
├── preload.js # 预加载脚本
├── renderer.js # 迷宫生成和求解核心逻辑
├── style.css # 应用样式
└── assets/ # 静态资源
└── icon.png # 应用图标
鸿蒙 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/
│ └── icon.png
└── module.json5 # 鸿蒙应用配置文件
技术栈与依赖
- 核心框架:Electron(跨平台桌面应用开发框架)
- 前端技术:HTML5 Canvas(可视化渲染)、CSS3(样式设计)、JavaScript (ES6+)(逻辑实现)
- 算法与数据结构:DFS/BFS、Prim/Kruskal、A * 寻路算法;并查集、优先队列、图结构
- 可视化技术:Canvas 绘图 API、动画帧控制、进度反馈机制
- 鸿蒙适配依赖:
- Electron 34 + 版本(支持鸿蒙 PC 适配)
- 鸿蒙核心库:libelectron.so、libadapter.so、libffmpeg.so、libc++_shared.so
- DevEco Studio 5.0+(鸿蒙开发工具,需安装鸿蒙 SDK API 20+)
- Node.js 18.x+
核心功能模块
1. 应用初始化
- 主进程窗口创建与配置(适配鸿蒙 PC 窗口特性)
- 渲染进程环境初始化(Canvas 画布、交互控件、状态管理)
- 算法库加载与参数预设(兼容鸿蒙平台性能特性)
- 系统权限检测与申请(鸿蒙平台存储、图形等权限)
2. 迷宫生成模块
- 多算法实现(核心逻辑跨平台无差异)
- 生成过程动画控制(鸿蒙平台优化帧速率)
- 进度实时反馈(适配响应式界面展示)
- 异常处理与边界条件控制(避免鸿蒙平台崩溃)
3. 迷宫求解模块
- A * 算法寻路实现(核心逻辑跨平台无差异)
- 搜索过程可视化(鸿蒙平台简化绘制逻辑)
- 路径重建与渲染(适配 Canvas 尺寸变化)
4. 交互控制模块
- 参数配置面板(响应式布局,适配鸿蒙 PC 窗口缩放)
- 鼠标 / 键盘事件处理(兼容鸿蒙平台输入机制)
- 功能按钮响应(生成 / 求解 / 重置 / 导出等)
- 全屏 / 窗口模式切换(适配鸿蒙系统窗口管理)
5. 导出与存储模块
- 图片导出功能(适配鸿蒙 PC 文件系统路径)
- JSON 数据导出(兼容鸿蒙本地存储机制)
- 导出进度反馈与错误处理
6. 鸿蒙 PC 适配专用模块
- 系统能力权限配置(存储、图形、文件操作权限)
- 硬件加速禁用(避免鸿蒙平台渲染冲突)
- Canvas 渲染优化(降低绘制频率、简化冗余绘制)
- 算法性能适配(大型迷宫生成时降低计算复杂度)
关键代码解析
主进程实现 (main.js)
主进程负责窗口创建、生命周期管理与鸿蒙适配配置:
javascript
运行
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const path = require('path');
const fs = require('fs');
// 鸿蒙PC平台强制禁用硬件加速,避免Canvas渲染异常
if (process.platform === 'harmony') {
app.disableHardwareAcceleration();
}
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
title: '迷宫生成器 - 鸿蒙PC适配版',
webPreferences: {
preload: path.join(__dirname, 'src', 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
webSecurity: process.platform !== 'harmony' // 鸿蒙平台放宽网络安全限制
},
backgroundColor: '#F5F5F5'
});
// 加载主页面(适配鸿蒙平台资源路径)
mainWindow.loadFile(path.join(__dirname, 'src', 'index.html'));
// 鸿蒙平台窗口适配:启用缩放,监听尺寸变化
if (process.platform === 'harmony') {
mainWindow.setResizable(true);
mainWindow.on('resize', () => {
const [width, height] = mainWindow.getSize();
mainWindow.webContents.send('window-resize', { width, height });
});
}
// 处理迷宫保存请求(适配鸿蒙PC文件路径)
ipcMain.on('save-maze', async (event, { data, type, fileName }) => {
try {
let options = {
title: '保存迷宫',
defaultPath: fileName,
filters: type === 'image'
? [{ name: '图片文件', extensions: ['png', 'jpg'] }]
: [{ name: 'JSON文件', extensions: ['json'] }]
};
// 鸿蒙平台文件保存路径适配
if (process.platform === 'harmony') {
options.defaultPath = `/sdcard/${fileName}`; // 鸿蒙PC默认存储路径
}
const result = await dialog.showSaveDialog(mainWindow, options);
if (!result.canceled && result.filePath) {
fs.writeFileSync(result.filePath, type === 'image' ? data : JSON.stringify(data));
event.reply('save-maze-reply', { success: true, path: result.filePath });
} else {
event.reply('save-maze-reply', { success: false });
}
} catch (error) {
event.reply('save-maze-reply', { success: false, error: error.message });
}
});
}
app.whenReady().then(createWindow);
// 适配鸿蒙平台应用退出逻辑
app.on('window-all-closed', () => {
if (process.platform !== 'darwin' && process.platform !== 'harmony') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
渲染进程核心逻辑 (renderer.js)
适配鸿蒙 PC 的渲染与算法优化:
javascript
运行
const { ipcRenderer } = require('electron');
// 全局状态管理
let gameState = {
rows: 10,
cols: 10,
cellSize: 40,
maze: null,
solutionPath: null,
startPoint: { row: 0, col: 0 },
endPoint: { row: 9, col: 9 },
animationDelay: 50,
isHarmonyOS: process.platform === 'harmony'
};
// Canvas相关初始化
let canvas, ctx;
function initCanvas() {
canvas = document.getElementById('maze-canvas');
ctx = canvas.getContext('2d');
adjustCanvasSize(); // 初始尺寸适配
}
// 鸿蒙平台窗口大小适配
ipcRenderer.on('window-resize', (event, { width, height }) => {
// 调整Canvas尺寸,保留边距
canvas.width = width * 0.7;
canvas.height = height * 0.8;
// 重新计算单元格大小(适配新窗口)
gameState.cellSize = Math.min(
Math.floor(canvas.width / gameState.cols),
Math.floor(canvas.height / gameState.rows)
);
if (gameState.maze) {
drawMaze(gameState.maze); // 重新绘制迷宫
}
});
// 迷宫生成算法适配:鸿蒙平台优化动画性能
async function generateMazeDFS() {
const maze = createEmptyMaze();
const stack = [];
const visited = Array(gameState.rows).fill().map(() => Array(gameState.cols).fill(false));
const startRow = Math.floor(Math.random() * gameState.rows);
const startCol = Math.floor(Math.random() * gameState.cols);
stack.push({ row: startRow, col: startCol });
visited[startRow][startCol] = true;
let steps = 0;
const totalCells = gameState.rows * gameState.cols;
// 鸿蒙平台增大动画延迟,降低绘制压力
const delay = gameState.isHarmonyOS ? gameState.animationDelay * 1.5 : gameState.animationDelay;
while (stack.length > 0) {
const current = stack[stack.length - 1];
const unvisitedNeighbors = getUnvisitedNeighbors(current.row, current.col, visited);
if (unvisitedNeighbors.length > 0) {
shuffleArray(unvisitedNeighbors);
const neighbor = unvisitedNeighbors[0];
removeWall(current.row, current.col, neighbor.row, neighbor.col, maze);
visited[neighbor.row][neighbor.col] = true;
stack.push(neighbor);
steps++;
updateProgress(steps / totalCells);
drawMaze(maze, neighbor.row, neighbor.col);
await sleep(delay); // 使用适配后的延迟
} else {
stack.pop();
}
}
return maze;
}
// 绘制函数适配:鸿蒙平台简化绘制逻辑
function drawMaze(maze = gameState.maze, highlightRow = -1, highlightCol = -1) {
const canvasWidth = gameState.cols * gameState.cellSize;
const canvasHeight = gameState.rows * gameState.cellSize;
// 鸿蒙平台优化:只清空当前绘制区域,减少重绘范围
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.strokeStyle = '#000000';
ctx.lineWidth = gameState.isHarmonyOS ? 1.5 : 2; // 鸿蒙平台减细线宽,提升绘制速度
// 绘制迷宫单元格
for (let row = 0; row < gameState.rows; row++) {
for (let col = 0; col < gameState.cols; col++) {
const x = col * gameState.cellSize;
const y = row * gameState.cellSize;
const cell = maze[row][col];
// 颜色设置
if (highlightRow === row && highlightCol === col) {
ctx.fillStyle = '#FFD700';
} else if (row === gameState.startPoint.row && col === gameState.startPoint.col) {
ctx.fillStyle = '#00FF00';
} else if (row === gameState.endPoint.row && col === gameState.endPoint.col) {
ctx.fillStyle = '#FF0000';
} else {
ctx.fillStyle = '#FFFFFF';
}
// 鸿蒙平台优化:减少填充区域冗余像素
ctx.fillRect(x + 1, y + 1, gameState.cellSize - 2, gameState.cellSize - 2);
// 绘制墙壁(只绘制必要墙壁,减少绘制指令)
ctx.beginPath();
if (cell.up) ctx.moveTo(x, y).lineTo(x + gameState.cellSize, y);
if (cell.right) ctx.moveTo(x + gameState.cellSize, y).lineTo(x + gameState.cellSize, y + gameState.cellSize);
if (cell.down) ctx.moveTo(x + gameState.cellSize, y + gameState.cellSize).lineTo(x, y + gameState.cellSize);
if (cell.left) ctx.moveTo(x, y + gameState.cellSize).lineTo(x, y);
ctx.stroke();
}
}
// 绘制路径
if (gameState.solutionPath && gameState.solutionPath.length > 0) {
ctx.strokeStyle = '#0000FF';
ctx.lineWidth = Math.max(2, gameState.cellSize / 5);
ctx.beginPath();
for (let i = 0; i < gameState.solutionPath.length; i++) {
const pathCell = gameState.solutionPath[i];
const x = pathCell.col * gameState.cellSize + gameState.cellSize / 2;
const y = pathCell.row * gameState.cellSize + gameState.cellSize / 2;
i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
}
ctx.stroke();
}
}
鸿蒙配置文件 (module.json5)
声明鸿蒙应用权限与系统能力:
json5
{
"module": {
"name": "maze-generator",
"type": "app",
"bundleName": "com.example.mazegenerator",
"versionName": "1.0.0",
"versionCode": 1000000,
"reqSysCapabilities": [
"system.window",
"system.storage", // 文件导出/存储权限
"system.graphics", // 图形渲染权限
"system.filemanagement" // 文件管理权限
],
"deviceTypes": ["pc"],
"distro": {
"deliveryWithInstall": true,
"moduleName": "maze-generator",
"moduleType": "entry"
}
}
}
API / 类 / 函数(核心适配说明)
核心工具函数
initCanvas(): 初始化 Canvas 画布,适配鸿蒙 PC 窗口尺寸adjustCanvasSize(width, height): 响应窗口大小变化,调整画布与单元格尺寸sleep(ms): 延时函数,鸿蒙平台自动增大延迟以优化性能updateProgress(progress): 进度更新函数,适配响应式界面展示
迷宫生成相关
generateMazeDFS()/generateMazeKruskal()等:生成算法实现,鸿蒙平台优化动画延迟与绘制逻辑createEmptyMaze(): 创建空迷宫数据结构,无平台差异removeWall(row1, col1, row2, col2, maze): 移除单元格墙壁,无平台差异getUnvisitedNeighbors(row, col, visited): 获取未访问邻居,无平台差异
迷宫求解相关
solveMazeAStar(): A * 寻路算法,鸿蒙平台简化搜索过程绘制频率calculateHeuristic(pos1, pos2): 启发式函数(曼哈顿距离),无平台差异reconstructPath(cameFrom, current): 路径重建,无平台差异getAccessibleNeighbors(row, col): 获取可达邻居,无平台差异
交互与导出相关
handleSaveMaze(type): 处理迷宫导出,适配鸿蒙 PC 文件路径与权限setStartPoint(row, col)/setEndPoint(row, col): 设置起点 / 终点,兼容鸿蒙平台鼠标事件resetMaze()/clearPath(): 重置迷宫 / 清除路径,无平台差异
配置与部署
1. 原始 Electron 平台(Windows/macOS/Linux)
安装与运行
- 克隆项目到本地
- 安装依赖:
bash
运行
npm install - 启动应用:
bash
运行
npm start
打包应用
使用 Electron Forge、Electron Builder 等工具打包为各平台可执行文件。
2. 鸿蒙 PC 平台
环境准备
- 开发环境:Windows 10/11、8GB RAM 以上、20GB 可用空间
- 运行环境:鸿蒙 PC 系统
- 工具安装:
- DevEco Studio 5.0+(安装鸿蒙 SDK API 20+)
- Node.js 18.x+
获取 Electron 鸿蒙编译产物
- 登录Electron 鸿蒙官方仓库
- 下载 Electron 34 + 版本的 Release 包(.zip 格式)
- 解压到项目目录,确认
electron/libs/arm64-v8a/下包含 4 个核心.so 库文件
部署应用代码
将原始 Electron 应用代码按鸿蒙 PC 目录结构,放置到web_engine/src/main/resources/resfile/resources/app/目录下,确保所有文件完整迁移。
配置与运行
- 打开项目:在 DevEco Studio 中打开
ohos_hap目录 - 配置签名:
- 进入 File → Project Structure → Signing Configs
- 自动生成调试签名或导入已有签名
- 连接设备:
- 启用鸿蒙 PC 设备开发者模式和 USB 调试
- 通过 USB Type-C 连接开发电脑
- 编译运行:点击 Run 按钮或按 Shift+F10
验证检查项
- ✅ 应用窗口正常显示,无渲染异常或闪烁
- ✅ 窗口大小可调整,响应式布局生效,迷宫自适应缩放
- ✅ 所有生成算法运行正常,动画流畅无卡顿
- ✅ A * 求解算法正常工作,路径显示准确
- ✅ 起点 / 终点自定义设置功能正常
- ✅ 迷宫导出(图片 / JSON)功能正常,文件可正常保存与打开
- ✅ 进度统计与状态反馈准确
- ✅ 控制台无 "SysCap 不匹配" 或 "找不到.so 文件" 错误
跨平台兼容性说明
| 平台 | 适配策略 | 特殊处理 |
|---|---|---|
| Windows | 标准 Electron 运行 | 无特殊配置 |
| macOS | 标准 Electron 运行 | 保留 dock 图标激活逻辑 |
| Linux | 标准 Electron 运行 | 确保系统依赖库完整 |
| 鸿蒙 PC | 通过 Electron 鸿蒙适配层 | 禁用硬件加速;优化 Canvas 绘制逻辑(减细线宽、增大动画延迟);适配文件存储路径与系统权限;简化冗余绘制操作 |
鸿蒙开发调试技巧
1. 性能优化要点
- 渲染优化:鸿蒙平台减细线宽、增大动画延迟、减少重绘范围,降低 CPU/GPU 占用
- 算法优化:大型迷宫(行数 / 列数 > 30)生成时,自动切换为简化版算法(如 DFS 替代 Aldous-Broder)
- 资源优化:减少 Canvas 绘制指令,合并重复绘制操作
2. 常见问题解决
- "SysCap 不匹配" 错误:检查
module.json5的reqSysCapabilities,确保包含 system.storage 和 system.filemanagement 权限 - "找不到.so 文件" 错误:确认
arm64-v8a目录下 4 个核心库文件完整,路径配置正确 - 窗口不显示:在
main.js中添加app.disableHardwareAcceleration(),确保鸿蒙平台禁用硬件加速 - 动画卡顿:进一步增大
animationDelay,或限制迷宫最大尺寸(如最大 50x50) - 导出失败:检查鸿蒙 PC 设备存储权限,确保应用可访问目标存储路径(如 /sdcard/)
- Canvas 闪烁:使用离屏 Canvas 预绘制,减少直接操作 DOM 的频率
总结与亮点回顾
本项目以功能丰富的迷宫生成器为载体,展示了 Electron 应用开发与算法可视化的完美结合,同时通过鸿蒙 PC 适配改造,实现了跨平台兼容能力。学习者通过本项目可掌握:
- Electron 主进程与渲染进程的 IPC 通信、文件操作、窗口管理等高级特性
- 多种经典算法(生成 / 寻路)的实现与可视化技巧
- Canvas 绘图优化与动画帧控制方法
- 鸿蒙 PC 平台 Electron 应用的核心适配要点(权限配置、性能优化、路径适配)
- 跨平台应用的调试与兼容性问题解决方案
项目代码结构清晰、算法实现完整,适配过程中在保持核心功能不变的前提下,针对鸿蒙 PC 平台的性能特点进行了针对性优化,既适合开发者学习算法可视化与 Electron 开发,也为跨平台应用改造提供了可复用的实践方案。
欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
更多推荐



所有评论(0)