Javascript 中简单游戏循环的最佳方法?
有没有一种简单的方法可以用 JavaScript 制作游戏循环?像...
onTimerTick() {
// update game state
}
Is there a simple way to make a game loop in JavaScript? something like...
onTimerTick() {
// update game state
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
根据您的应用程序,使用 JavaScript 有多种方法可以实现此目的。一个 setInterval() 甚至一个 while() 语句就可以解决问题。这不适用于游戏循环。 JavaScript 由浏览器解释,因此很容易出现中断。中断会让你的游戏回放感觉紧张。
CSS3 的 webkitRequestAnimationFrame 属性旨在通过管理渲染循环本身来纠正此问题。然而,这仍然不是最有效的方法,并且如果您有大量对象正在更新,则很容易出现抖动。
这是一个很好的入门网站:
http:// nokarma.org/2011/02/02/javascript-game-development-the-game-loop/index.html
该网站提供了一些有关制作游戏循环的基础知识的有用信息。它不以任何方式涉及任何类型的面向对象设计。
实现精确计时的最准确方法是使用日期函数。
这没有考虑 setTimeout 在高频下如何漂移。这也会导致事情变得不同步并变得紧张。 JavaScript 每秒会漂移 +/- 18 毫秒。
现在让我们将所有这些放入一个工作示例中。我们希望将游戏循环注入到 WebKit 的托管渲染循环中。这将有助于平滑渲染的图形。我们还想拆分绘制和更新功能。这将在计算何时绘制下一帧之前更新渲染场景中的对象。如果更新时间过长,游戏循环也应该跳过绘制帧。
您可以在此处找到完整的工作示例以及所有代码。我已将此答案转换为可下载的 JavaScript 框架,您可以从中构建游戏。
https://code.google.com/p/twod-js/
There are a varied amount of ways to achieve this using JavaScript depending on your application. A setInterval() or even with a while() statement would do the trick. This will not work for a game loop. JavaScript interpreted by the browser, so it is prone to interrupts. Interrupts will make the play back of your game feel jittery.
The webkitRequestAnimationFrame properties of CSS3 aims to correct this by managing the rendering loop itself. However this is still not the most efficient way to do this and will be prone to jitters if you have alot of objects being updated.
This is a good website to get started with:
http://nokarma.org/2011/02/02/javascript-game-development-the-game-loop/index.html
This site has some good information on the basics of making a game loop. It does not touch upon any sort of object oriented design by any means.
The most accurate way to achieve precise timings is by using the date function.
This does not take into account how setTimeout drifts at high frequencies. This will also lead to things getting out of sync and becoming jittery. JavaScript will drift +/- 18ms per second.
Now lets put all of this into a working example. We want to inject our game loop into WebKit’s managed rendering loop. This will help smooth out the rendered graphics. We also want to split up the draw and update functions. This will update the objects in our rendering scene before calculating when the next frame should be drawn. The game loop should also skip draw frames if updating takes to long.
You can find a full working example, and all of the code here. I have convert this answer into a downloadable javascript framework you can build your games off from.
https://code.google.com/p/twod-js/
requestAnimationFrame 是现在大多数浏览器中可用的一个很好的替代方案。它完成了您使用 setInterval 所做的事情,但以一种烘焙的方式进行。也许它最好的一点是它只在您的选项卡聚焦时运行。如果您希望在后台运行,这可能是不使用它的一个原因,但通常(特别是对于仅在可见时才重要的渲染循环),当选项卡不可用时不使用资源是很好的。积极的。
用法非常简单:
我讨厌在旧线程上发帖,但这是“javascript 游戏循环”的最佳谷歌结果,因此它确实需要包含 requestAnimationFrame。
适用于旧浏览器的 Pollyfill 复制自 paulirish:
关于 creativeJS
requestAnimationFrame is a great alternative available in most browsers now. It does what you're doing with setInterval, but in a baked in way. Probably the nicest thing about it is that it only runs while your tab is focused. That could be a reason not to use it if you want things to run in the background, but often (especially for render loops that only matter when seen) it's great to not be using resources when the tab's not active.
Usage is pretty simple:
I hate to post on old threads, but this is a top google result for "javascript game loop" so it really needs to include requestAnimationFrame.
Pollyfill for old browsers copied from paulirish:
Deeper explanation and usage tips on creativeJS
其中许多答案已经过时且不是最佳的。现在推荐的方法是使用 requestAnimationFrame 。
例如:
固定时间步长
如果您想实现固定时间步长,只需累积增量时间直到达到某个阈值,然后更新您的游戏。
Many of these answers are outdated and suboptimal. The recommended way to do this now is using
requestAnimationFrame
.For example:
Fixed time-step
If you want to achieve a fixed time-step, simply accumulate delta-time until it reaches some threshold, then update your game.
是的。您需要
setInterval
:Yep. You want
setInterval
:这样可以吗?
其中 25 是您想要的 FPS。您还可以输入帧之间的毫秒数,在 25 fps 下为 40 毫秒 (1000 / 25 = 40)。
Would this do?
Where 25 is your desired FPS. You could also put there the amount of milliseconds between frames, which at 25 fps would be 40ms (1000 / 25 = 40).
不确定这效果如何,但这是一种使用 while 循环并使线程休眠的方法。这只是一个示例,您可以根据您在任何其他语言中的操作方式,将下面的游戏循环替换为更好的游戏循环。您还可以此处找到更好的 while 循环
not sure how well this will work, but here is one method that uses a while loop and sleeps the thread. This is just an example, you can replace the game loop below with a better one, based on how you would do it in any other language. You can also find a better while loop here