Canvas Context.drawImage () оставляет дубликаты Sprite на UpdatePosition () - PullRequest
0 голосов
/ 27 сентября 2019

Я экспериментировал с основным игровым циклом с HTML-элементом Canvas.Многочисленные учебные пособия онлайн не дают достаточно подробных сведений о концепциях рендеринга и canvas.ctx (контекст).

Я пытаюсь сделать что-то очень простое: Рендеринг изображения на элементе canvas и, при нажатии клавиши, обновляют его положение и отображают его в новом месте, заставляя его перемещаться по экрану.. По сути, то, что делает каждая видеоигра со своими спрайтами.

В этих уроках мне говорили, что ctx.drawImage(image, x, y, ...) будет работать для этого.Однако в моей версии происходит то, что происходит, по сути, когда вы выигрываете пасьянс на Windows. Он повторяет изображение спрайта, как будто он создает новый спрайт каждый раз, когда игра зацикливается. Сам спрайт не двигается, кажется, что новый спрайт генерируется слева / справа / и т.д. оригиналаодин.Я понимаю, что звоню ctx.drawImage(...) каждый раз, когда перебираю игровой цикл.Однако этого не произошло, когда я использовал ctx.clearRect(...).Это сработало именно так, как я ожидал.Я не совсем уверен, почему создание прямоугольника с помощью ctx работает, а создание изображения - нет.

Мой вопрос: Есть ли способ просто обновить позицию спрайта, не создавая новую версию его в каждом цикле?

Вот мой соответствующий код:

let lastRender = 0; // For the general loop

let image = new Image();
image.src = "/img/image.png";

let state = {
    pressedKeys: {
        // left, right, up, down: false
    },

    position: {
        x: canvas.width / 2,
        y: canvas.width / 2
    },

    speed: 20
}

let pepsi = new Sprite({
    img: image,
    width: 100,
    height: 100
)};


function Sprite (options) {
    this.img = options.img;
    this.width = options.width;
    this.height = options.height;

    this.render = function(){
        ctx.drawImage(
        this.img,
        state.position.x,
        state.position.y
        )
    }
}

function updatePosition(progress) {
        //pressedKeys is just an object that relates WASD to the key codes 
        //     and their respective directions, it's ignorable

        if (state.pressedKeys.left) {
            state.position.x -= state.speed;
        }

        if (state.pressedKeys.right) {
            state.position.x += state.speed;
        }

        if (state.pressedKeys.up) {
            state.position.y -= state.speed;
        }

        if (state.pressedKeys.down) {
            state.position.y += state.speed;
        }
}


function draw() {
    pepsi.render();
}

function loop(timestamp) {
    let progress = timestamp - lastRender;

    update(progress) // <-- Updates position, doesn't touch draw()

    draw(); // <-- Runs pepsi.render(); each loop

    lastRender = timestamp;             
    window.requestAnimationFrame(loop); 
}

window.requestAnimationFrame(loop); // for the general loop 

Если у вас есть какие-либо сомнения по поводу настройки этого проекта (например, использование state.position для каждого Sprite), то я был бы радуслышать их в дополнение к решению моей проблемы.Не в изоляции.Я получил большую часть этого кода из неконтекстных, неконкретных онлайн-руководств, но я понимаю большую его часть, за исключением визуализации.

Кроме того, если вы уже сталкивались с подобными вопросами и находитесь на заборео высказывании "Возможного дубликата {Связанного с границей поста, связанного с тангенциальной связью, от четырехлетней давности}" , тогда вот вам несколько советов: просто ответьте на вопрос еще раз.Это буквально не делает ничего плохого для вас.

1 Ответ

0 голосов
/ 27 сентября 2019

Эффект размытия пасьянса, который вы получаете, проистекает из того факта, что каждый кадр рисуется поверх последнего.Холст не очищается автоматически между кадрами.

Вы упомянули, что использовали clearRect, использование clearRect - очистить все пиксели в указанном прямоугольнике.

Так что если вы поставитеctx.clearRect(0, 0, canvas.width, canvas.height) в функции рисования до pepsi.render(), которая должна очистить холст перед рисованием следующего кадра.

...