JavaScript 游戏循环

发布于 2024-12-15 11:16:04 字数 737 浏览 2 评论 0原文

我有一些关于 JavaScript 循环的问题。

问题:

  • 为什么 JavaScript 循环会冻结浏览器
  • 为什么绘制速度很慢,即使它以每 1 毫秒绘制 1 次的速度运行,而且它正在绘制最简单的东西!
  • 解决办法是什么?闪存即将消亡,我们现在该怎么办?

这是您自己尝试的画布代码:

<!doctype html>
<html>
<head>
</head>
<body>
    <canvas id="c" width="400" height="400"></canvas>
    <script type="text/javascript">

        var c = document.getElementById( 'c' );

        ctx = c.getContext( '2d' );

        var x = 100;

        ctx.fillStyle= '#f00';

        function loop()
        {
            ctx.fillRect( x, 100, 20, 20 );

            ++x;
        }

        setInterval( loop, 1 );
    </script>
</body>
</html>

I have some questions concerning JavaScript loops.

Questions :

  • Why does a JavaScript loop freeze the browser
  • Why is the drawing slow even do it's running at 1 draw every 1ms and it's drawing the simplest thing!
  • What's the solution? flash is dying, what do we do now?

Here is the canvas code to try for yourself :

<!doctype html>
<html>
<head>
</head>
<body>
    <canvas id="c" width="400" height="400"></canvas>
    <script type="text/javascript">

        var c = document.getElementById( 'c' );

        ctx = c.getContext( '2d' );

        var x = 100;

        ctx.fillStyle= '#f00';

        function loop()
        {
            ctx.fillRect( x, 100, 20, 20 );

            ++x;
        }

        setInterval( loop, 1 );
    </script>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情徒 2024-12-22 11:16:04

为什么 JavaScript 循环会冻结浏览器(在 C++ 中不会发生)

JavaScript 是单线程的。当 JavaScript 代码运行时,DOM 的状态不能改变,否则会发生竞争条件。这意味着没有绘图/回流。

为什么绘制速度很慢,即使它以每 1 毫秒绘制 1 次的速度运行,而且它绘制的是最简单的东西!

它不是以 1 毫秒运行,而是以 10 毫秒运行,因为浏览器不允许你如此紧密地循环。

解决办法是什么?闪存即将消亡,我们现在该怎么办?

使用 requestAnimationFrame 并以 60 FPS 运行游戏,为什么还需要更多?

使用(webkit)requestAnimationFrame的示例对我来说运行顺利。

Why does a JavaScript loop freeze the browser ( does not happen in C++ )

JavaScript is single threaded. The state of the DOM cannot change whilst javascript code is running or race conditions would occur. This means no drawing / reflow.

Why is the drawing slow even do it's running at 1 draw every 1ms and it's drawing the simplest thing!

It's not running at 1ms, it's running at 10ms because browsers do not allow you to loop that tightly.

What's the solution? flash is dying, what do we do now?

Use requestAnimationFrame and run your game at 60 FPS, why do you need more?

Example using (webkit) requestAnimationFrame which runs smoothly for me.

梦开始←不甜 2024-12-22 11:16:04

一毫秒是一个极短的间隔。
由于时间间隔非常短,您的代码几乎会在 UI 线程中持续运行,导致浏览器无响应。

您需要留出停顿,以便为用户提供与页面交互的时间。

使用至少十毫秒、最好一百毫秒的间隔。

One millisecond is an extremely short interval.
It's such a short interval that your code will be running in the UI thread almost continually, leaving the browser unresponsive.

You need to leave pauses to give the user time to interact with the page.

Use an interval of at least ten, and preferably one hundred, milliseconds.

待天淡蓝洁白时 2024-12-22 11:16:04

帧率下降并最终导致浏览器冻结的原因是由于canvas元素占用了内存。我已经回答过这个问题了。您可以在此处找到该主题。

每次您在画布上绘制内容时,该操作都会保存到画布的路径中。每次在画布上绘制内容时,此路径都会占用更多内存。如果您不清空画布的路径,帧率将会下降。例如,查看您的 javascript 和下面清除画布路径的 javascript 之间的执行时间差异,

var c = document.getElementById( 'c' );
ctx = c.getContext( '2d' );
var x = 100;
ctx.fillStyle= '#f00';

function loop()
{
    ctx.beginPath(); 
    ctx.fillRect( x, 100, 20, 20 );

    ++x;
}
setInterval( loop, 1 );

The reason of the framerate drop and eventually the browser freeze occurs because of the memory occupied by the canvas element. I already answered this question. You can find the thread here.

Each time you draw something to the canvas that operation is saved to the path of the canvas. This path occupies more memory each time you draw something on the canvas. If you don't empty the path of the canvas you will have framerate drops. For example look at the execution time difference between your javascript and the javascript below which clears the canvas path,

var c = document.getElementById( 'c' );
ctx = c.getContext( '2d' );
var x = 100;
ctx.fillStyle= '#f00';

function loop()
{
    ctx.beginPath(); 
    ctx.fillRect( x, 100, 20, 20 );

    ++x;
}
setInterval( loop, 1 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文