Как полностью остановить / сбросить / повторно инициализировать Matter. js canvas / world / engine / instance - PullRequest
1 голос
/ 12 февраля 2020

У меня есть экземпляр Matter. js на экране, например, в игре, и я хочу полностью начать все заново, когда пользователь / игрок нажимает кнопку "новая игра":

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 на странице, занимающей весь экран, с solid краями снаружи, поэтому тела не могут падать в любом направлении.

В этом случае (не включенный здесь), я создал случайный лабиринт с прямоугольником в качестве цели и кругом, чтобы перемещаться, используя WASD или клавиши со стрелками, и обработчик событий для столкновения между этими двумя, которое выскакивает ранее скрытый div с z -индекс от 1 до go в верхней части карты, которая содержит кнопку «Начать сначала», которая при нажатии возвращает игрока к выбору сложности, а затем он может создать новый лабиринт.

Вот код для этой кнопки «Начать сначала», где я хочу очистить весь экземпляр Matter / canvas / world / engine, прежде чем дать возможность выбрать сложность и создать новый лабиринт. e:

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');
        });

Здесь , где я нашел рекомендации по методам World.clear и Engine.clear, и это помогло удалить все элементы из текущего холста.

Однако я сталкиваюсь с тем, что когда игрок выбирает новую сложность и нажимает кнопку «Go», создается новый холст внутри существующего world, рядом с / под старым, теперь пустым. , canvas.

Как мне избавиться от этого старого холста, чтобы полностью переинициализировать?

1 Ответ

1 голос
/ 12 февраля 2020

Я предполагаю, что Docs предполагают, что разработчики могут соединить два и два из документации, чтобы понять это, но мне потребовалось несколько часов, чтобы найти / выяснить, что мне нужно было объединить этот другой пост с тем, на который изначально ссылались, чтобы получить это для события кнопки «Начать заново»:

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');
        });

В частности, методы / свойства классов Render и Runner. Вы должны остановить их обоих, затем удалить сам render и очистить другие свойства для render и runner.

Одна ОЧЕНЬ важная вещь, на которую следует обратить внимание, это то, что мне пришлось объявить engine, world, render и runner глобально, а затем назначьте их в функции createMaze.

Также важно, как я обнаружил в другом посте (не могу найти, где это было теперь) что если вы не остановите Runner, бегунок / анимация будет ускоряться при каждом воссоздании холста.

Функция запускается сначала при загрузке, а затем снова после очистки Мир / холст с кнопкой «Начать сначала», поэтому эти переменные должны быть глобальными.


Я должен быть честным и признать, что 1) Я новичок, а не супер-знающий / опытный в инициализации / повторной инициализации, и 2) я не самый лучший / самый тщательный в чтении документов, так что это могло быть где-то очевидно, и я просто не нашел времени, чтобы найти его.

Честно говоря, меня убеждают, что никто не читает полностью документы по всему, что они используют, верно? Возможно, я только что видел слишком много мемов «быть разработчиком - значит вставлять из стека overflow весь день».

...