You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:05:58