如何在P5JS多画布实例间共享数据?迷宫生成报错求助
解决P5JS多Canvas实例共享迷宫数据的问题
错误原因分析
你遇到的Uncaught ReferenceError: Maze is not defined主要有两个核心原因:
- 全局作用域代码优先执行,此时
width、height、cols、rows、res这些参数变量还未定义(它们仅在p5Maze的sketch内部声明),直接传入new Maze()会导致参数无效;同时如果Maze类未在全局作用域暴露,JS引擎会找不到这个类。 - 你试图在p5实例初始化前生成迷宫,但此时p5环境未准备就绪,必要的参数和类都不可用。
解决方案:全局变量共享迷宫数据
核心思路是在全局作用域声明共享变量,在第一个p5实例的setup方法中生成迷宫并赋值给全局变量,让所有p5实例都能访问到迷宫数据。
步骤1:确保Maze类全局可访问
先把Maze类定义在全局作用域(比如放在sketch.js最开头,或者单独文件中提前加载):
class Maze { constructor(width, height, cols, rows, res) { this.width = width; this.height = height; this.cols = cols; this.rows = rows; this.res = res; // 你的回溯算法初始化逻辑 } grid() { // 返回你的迷宫网格数据结构 // ...你的实现代码 } }
步骤2:修改sketch.js代码,实现全局共享
// 全局作用域声明共享变量,用于存储迷宫数据 let globalMaze; let globalMazeGrid; const p5Maze = ( sketch ) => { const width = 100; const height = 100; const res = 10; const cols = height / res; const rows = width / res; let maze; let mazeGrid; sketch.setup = () => { sketch.createCanvas(width, height); // 在p5实例内部生成迷宫,并赋值给全局变量 maze = new Maze(width, height, cols, rows, res); mazeGrid = maze.grid(); globalMaze = maze; globalMazeGrid = mazeGrid; }; sketch.draw = () => { sketch.background(255); for (let r = 0; r < maze.rows; r++) { for (let c = 0; c < maze.cols; c++) { let tile = mazeGrid[r][c].tile; let x1 = tile.x; let x2 = tile.x + maze.res; let y1 = tile.y; let y2 = tile.y + maze.res; if (tile.top) sketch.line(x1, y1, x2, y1); if (tile.bottom) sketch.line(x1, y2, x2, y2); if (tile.left) sketch.line(x1, y1, x1, y2); if (tile.right) sketch.line(x2, y1, x2, y2); } } }; } let map = new p5(p5Maze, 'container'); const p5PlayArea = ( sketch ) => { const width = 400; const height = 400; const scale = width / 100; // 适配第二个画布的缩放比例 sketch.setup = () => { sketch.createCanvas(width, height); }; sketch.draw = () => { sketch.background(200); // 先判断全局迷宫数据是否已生成,避免未初始化时报错 if (globalMazeGrid) { sketch.stroke(0); // 示例:将迷宫绘制到第二个画布(带缩放) for (let r = 0; r < globalMaze.rows; r++) { for (let c = 0; c < globalMaze.cols; c++) { let tile = globalMazeGrid[r][c].tile; let x1 = tile.x * scale; let x2 = (tile.x + globalMaze.res) * scale; let y1 = tile.y * scale; let y2 = (tile.y + globalMaze.res) * scale; if (tile.top) sketch.line(x1, y1, x2, y1); if (tile.bottom) sketch.line(x1, y2, x2, y2); if (tile.left) sketch.line(x1, y1, x1, y2); if (tile.right) sketch.line(x2, y1, x2, y2); } } } }; } let playArea = new p5(p5PlayArea, 'screen');
关键注意点
- 全局变量
globalMaze和globalMazeGrid是所有实例共享数据的桥梁,必须在第一个实例的setup中完成赋值后再被其他实例使用。 - 在第二个实例的
draw方法中要先判断全局数据是否存在,因为p5实例的setup是异步执行的,可能第二个实例的draw会先于第一个实例的setup运行。 - 必须确保
Maze类在全局作用域定义,否则所有实例都无法访问这个类。
内容的提问来源于stack exchange,提问作者Eben Rayworth
相关产品推荐
相关产品推荐

