如何完全stop/reset/reinitializeMatter.jscanvas/world/engine/instance

How to completely stop/reset/reinitialize Matter.js canvas/world/engine/instance

我在屏幕上有一个 Matter.js 的实例,例如游戏,我想在 user/player 单击 "new game" 按钮时完全从头开始:

const { Engine, Render, Runner, World, Bodies, Mouse, MouseConstraint, Body, Events } = Matter;

    //movement setup
    const engine = Engine.create();
    const { world } = engine;

    let render;
    let runner;

const startGame = document.querySelector('#start');
startGame.addEventListener('click', event => {

    event.preventDefault();

    //hide 'choose difficulty' 
    const chooseDifficulty = document.querySelector('.options');
    chooseDifficulty.classList.add('hidden');

    //get selected difficulty
    const difficulty = document.querySelector('input[name=difficulty]:checked').value;

    //set number of horizontal/vertical cells based on difficulty selected
    switch(difficulty) {
        case 'easy':
            cellsHorizontal = 6;
            cellsVertical = 4;
            break;
        case 'medium':
            cellsHorizontal = 14;
            cellsVertical = 10;
            break;
        case 'hard':
            cellsHorizontal = 25;
            cellsVertical = 15;
            break;
    }

    createMaze();
});

const createMaze = () => {
        //show controls
        // document.querySelector('.controls').classList.remove('hidden');
        console.log(document.querySelector('.controls').scrollHeight)
        //set size of movement.js canvas/world
        const worldWidth = document.querySelector('.canvas').scrollWidth;
        const worldHeight = document.querySelector('.canvas').scrollHeight;

        console.log(document.querySelector('.canvas').scrollHeight)
        console.log(worldHeight);

        //length of one side of one cell
        const unitLengthX = worldWidth/cellsHorizontal;
        const unitLengthY = worldHeight/cellsVertical;

        //disable gravity & render the world
        engine.world.gravity.y = 0;
        world.gravity.x = 0;
        render = Render.create({
            element: document.querySelector('.canvas'),
            engine: engine,
            options: {
                width:worldWidth,
                height:worldHeight,
                wireframes:false
            }
        });

        Render.run(render);
        runner = Runner.create();
        Runner.run(runner, engine);

        //Outer edges
        const edges = [
            /*top*/Bodies.rectangle((worldWidth/2),0,worldWidth,5, {isStatic:true}),
            /*bottom*/Bodies.rectangle((worldWidth/2),worldHeight,worldWidth,5, {isStatic:true}),
            /*left*/Bodies.rectangle(0,(worldHeight/2),5,worldHeight, {isStatic:true}),
            /*right*/Bodies.rectangle(worldWidth,(worldHeight/2),5,worldHeight, {isStatic:true})
        ];

        World.add(world, edges);
}

这会在占据整个屏幕的页面上的 .canvas div 内创建一个 canvas,在外面有实心边缘,这样 Bodies 就不会从任何方向掉落.

在这个例子中(这里不包括),我创建了一个随机迷宫,其中一个矩形作为目标,一个圆圈使用 WASD 或箭头键四处移动,以及一个事件处理程序来处理这两者之间的碰撞它会弹出一个先前隐藏的 div,z-index 为 1 以转到地图顶部,其中包含一个 "Start Over" 按钮,单击该按钮将使玩家返回到难度选择,并且然后他们可以生成一个全新的迷宫。

这是 "Start Over" 按钮的代码,我想在其中清除整个问题 instance/canvas/world/engine,然后再提供选择难度和创建新迷宫的选项:

button.addEventListener('click', event => {
            event.preventDefault();
            World.clear(world);
            Engine.clear(engine);
            console.log('reset clicked');
            document.querySelector('.winner').classList.add('hidden');
            document.querySelector('.options').classList.remove('hidden');
        });

Here 是我找到 World.clearEngine.clear 方法建议的地方,它可以从当前 canvas.[=20= 中删除所有元素]

但是我 运行 喜欢的是,当玩家选择新难度并单击 "Go" 按钮时,现有 world 中的全新 canvas ] 被创建,接下来 to/below 旧的,现在是空的,canvas.

如何删除旧的 canvas 以便完全重新初始化?

我猜 Docs assume that devs can put two and two together from the documentation in order to figure this out, but it took me several hours to find/figure out that I needed to combine this other post 与最初引用的那个 "Start Over" 按钮事件:

button.addEventListener('click', event => {
            event.preventDefault();
            World.clear(world);
            Engine.clear(engine);
            Render.stop(render);
            Runner.stop(runner);
            render.canvas.remove();
            render.canvas = null;
            render.context = null;
            render.textures = {};
            console.log('reset clicked');
            document.querySelector('.winner').classList.add('hidden');
            document.querySelector('.options').classList.remove('hidden');
        });

特别是 RenderRunner class methods/property 清除。 您必须停止它们,然后删除 render 本身并清除 renderrunner.

的其他属性

需要注意的一个非常重要的事情是我必须全局声明 engineworldrenderrunner,然后在 createMaze函数。

同样重要的是,正如我在另一个 post 中发现的(无法找到它现在的位置),如果你不停止 Runner,runner/animation 将得到每次重新创建 canvas 时速度更快。

该函数最初在加载时是 运行,然后在使用 "Start Over" 按钮清除 World/canvas 后再次出现,因此这些变量需要是全局变量。


我必须诚实地承认 1) 我是新手,而不是 initializing/reinitializing 中的超级 knowledgeable/practiced,并且 2) 我不是 best/most 的彻底通读文档,所以这在某处可能很明显,我只是没有花时间找到它。

老实说,我一直相信没有人会完全阅读有关他们使用的所有内容的文档,对吗?也许我只是看到了太多 "being a developer means pasting from Whosebug all day" 表情包。