【发布时间】:2019-09-27 05:36:58
【问题描述】:
我一直在用 HTML 的 Canvas 元素试验一个基本的游戏循环。许多在线教程都没有详细介绍渲染和 canvas.ctx(上下文)的概念。
我正在尝试做的事情非常简单:在画布元素上渲染图像,然后在 keydown 时更新其位置并将其渲染到新位置,使其在屏幕上移动。 基本上,每个视频游戏都用它的 sprite 做什么。
通过这些教程告诉我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
如果您对这个项目的设置方式有任何疑虑(例如,使用 each Sprite 的 state.position),那么除了解决我的问题。不是孤立的。我从无上下文、非特定的在线教程中获得了大部分代码,但我理解了大部分代码,除了渲染。
另外,如果您以前见过这类问题,并且对说“可能重复 {Borderline Tangentially-Related Post from Four Years A}”,那么这里有一些建议: 再次回答问题。它实际上对你没有任何负面影响。
【问题讨论】:
标签: javascript loops rendering sprite