Я экспериментировал с основным игровым циклом с 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), то я был бы радуслышать их в дополнение к решению моей проблемы.Не в изоляции.Я получил большую часть этого кода из неконтекстных, неконкретных онлайн-руководств, но я понимаю большую его часть, за исключением визуализации.
Кроме того, если вы уже сталкивались с подобными вопросами и находитесь на заборео высказывании "Возможного дубликата {Связанного с границей поста, связанного с тангенциальной связью, от четырехлетней давности}" , тогда вот вам несколько советов: просто ответьте на вопрос еще раз.Это буквально не делает ничего плохого для вас.