项目概述

这是一个基于 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)

安装与运行
  1. 克隆项目到本地
  2. 安装依赖:

    bash

    运行

    npm install
    
  3. 启动应用:

    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 鸿蒙编译产物
  1. 登录Electron 鸿蒙官方仓库
  2. 下载 Electron 34 + 版本的 Release 包(.zip 格式)
  3. 解压到项目目录,确认electron/libs/arm64-v8a/下包含 4 个核心.so 库文件
部署应用代码

将原始 Electron 应用代码按鸿蒙 PC 目录结构,放置到web_engine/src/main/resources/resfile/resources/app/目录下,确保所有文件完整迁移。

配置与运行
  1. 打开项目:在 DevEco Studio 中打开ohos_hap目录
  2. 配置签名:
    • 进入 File → Project Structure → Signing Configs
    • 自动生成调试签名或导入已有签名
  3. 连接设备:
    • 启用鸿蒙 PC 设备开发者模式和 USB 调试
    • 通过 USB Type-C 连接开发电脑
  4. 编译运行:点击 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.json5reqSysCapabilities,确保包含 system.storage 和 system.filemanagement 权限
  • "找不到.so 文件" 错误:确认arm64-v8a目录下 4 个核心库文件完整,路径配置正确
  • 窗口不显示:在main.js中添加app.disableHardwareAcceleration(),确保鸿蒙平台禁用硬件加速
  • 动画卡顿:进一步增大animationDelay,或限制迷宫最大尺寸(如最大 50x50)
  • 导出失败:检查鸿蒙 PC 设备存储权限,确保应用可访问目标存储路径(如 /sdcard/)
  • Canvas 闪烁:使用离屏 Canvas 预绘制,减少直接操作 DOM 的频率

总结与亮点回顾

本项目以功能丰富的迷宫生成器为载体,展示了 Electron 应用开发与算法可视化的完美结合,同时通过鸿蒙 PC 适配改造,实现了跨平台兼容能力。学习者通过本项目可掌握:

  1. Electron 主进程与渲染进程的 IPC 通信、文件操作、窗口管理等高级特性
  2. 多种经典算法(生成 / 寻路)的实现与可视化技巧
  3. Canvas 绘图优化与动画帧控制方法
  4. 鸿蒙 PC 平台 Electron 应用的核心适配要点(权限配置、性能优化、路径适配)
  5. 跨平台应用的调试与兼容性问题解决方案

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

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

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐