程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了优化 HTML5 画布游戏循环大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决优化 HTML5 画布游戏循环?

开发过程中遇到优化 HTML5 画布游戏循环的问题如何解决?下面主要结合日常开发的经验,给出你关于优化 HTML5 画布游戏循环的解决方法建议,希望对你解决优化 HTML5 画布游戏循环有所启发或帮助;

我目前正在制作一个 HTML5 游戏,我正在尝试在画布上绘制各种东西。我的游戏基本上就是你在无限区域内移动的地方,但我不知道如何优化我的代码以在屏幕上绘制灌木丛。它工作正常,但滞后很多,我知道有一些方法可以优化它。这是我当前的代码:

    for(var x=offset[0];x<(offset[0]+canvas.wIDth)+300;x++) {
        for(var y=offset[1];y<(offset[1]+canvas.height)+300;y++) {
            if(x % 85 == 0 && y % 85 == 0 && noise.simplex2(x,y) == 0) {
                ctx.drawImage(treeimage,((x-offset[0])*-1)+canvas.wIDth,((y-offset[1])*-1)+canvas.height);
            }
        }
    }

treeimage 定义如下:

var treeimage = new Image(); treeimage.src = 'images/mapobjects/tree2.png';

offset[] 是一个数组,其值分别是对象相对于玩家的偏移量(因此当玩家向左移动时,它会上升)分别在水平和垂直方向。我使用单纯形噪声来生成灌木丛,因为我喜欢它们成群结队。使 FPS 如此低的问题是,在我的屏幕分辨率下,我每帧运行 2 个模函数 2137104,而在更高的分辨率下,情况变得更糟。我试图通过循环遍历游戏的每个图块而不是每个像素(每个图块为 85x85,因此将 y 和 x 增加 85 而不是 1)然后添加玩家偏移 % 85 来使其更快,但是我遇到了问题跳来跳去是因为偏移 % 85 在跳到下一个图块时没有立即变为 0,我尝试并尝试以多种不同的方式使其工作,但这是我让它工作的唯一方法。这就是它的外观,除了代码超慢之外,一切正常。

优化 HTML5 画布游戏循环

我在尝试优化它时是否遗漏了什么,或者是否有一种完全不同的方法可以解决它。我从来没有真正需要优化代码,所以这对我来说是一件新鲜事。我可以说所有的滞后都来自这段代码,因为没有它,只需增加 85,它就可以正常工作。谢谢!

解决方法

很多年前,由于计算机没有今天那么快,您必须进行一些繁重的数学运算,例如计算正弦或余弦 - 甚至是模 - 只有一种选择:

不是每次需要时都计算它,计算一次并将其存储在一个巨大的查找表中。查找值当然比计算要快得多。

因此,在您的情况下,我建议为 x 和 y 的模生成两个数组

let xModulo = [];
let ymodulo = [];
for (let a = 0; a < canvas.width; a++) {
  xModulo.push(a % 85);
}
for (let a = 0; a < canvas.height; a++) {
  ymodulo.push(a % 85);
}

并在您的渲染循环中查找数组中的值,例如:

if (xModulo[x] == 0 && ymodulo[y] == 0 && noise.simplex2(x,y) == 0) {
  ctx.drawImage(treeimage,((x - offset[0]) * -1) + canvas.width,((y - offset[1]) * -1) + canvas.height);
}

这应该会显着提升性能。根据您的需要,您可能需要将 canvas.width / canvas.height 更改为更高的值。 您甚至可以虑为单纯形噪声生成一个查找表。

,

每张图像 7225 次无意义操作

条件会减慢代码速度。如果可能,您应该尽量避免它们。

例如线...

if(x % 85 == 0 && y % 85 == 0 && noise.simplex2(x,y) == 0) {

... 意味着您正在为每棵少于一棵树评估 if 语句 85 * 85 (7225) 次,这是大量不需要的开销。

  • 删除那些 7224 次无用的迭代。

  • 通过在变量中存储重复的数组查找,尽可能避免索引数组。

  • 简化你的数学。例如,((x-offset[0])*-1)+canvas.width 可以简化为 canvas.width - x + offset[0]

  • 尽可能多地将负载卸载到 GPU。默认情况下,所有位置计算都是通过在 GPU 上完成的变换进行的,因此上述数学运算可以在循环之前完成一次。

  • 性能的一般规则,通过将你能做的移到循环外来减少循环内的代码量。

下面的代码片段实现了以上几点。

由于您尚未提供有关偏移量和画布大小范围的详细信息,因此可以进一步优化以下代码

    var x,y;
    const STEP = 85;
    const offsetX = offset[0];
    const offsetY = offset[1];
    const startX =  Math.floor(offsetX / STEp) * STEP;
    const startY = Math.floor(offsetY / STEp) * STEP;
    const endX = startX + canvas.width;
    const endY = startY + canvas.height;
    ctx.setTransform(1,1,canvas.width - offsetX,canvas.height - offsetY);
    
    for (x = startX; x < endX; x += STEp) {
        for (y = startY; y < endY; y += STEp) {
            if (noise.simplex2(x,y) == 0) {
                ctx.drawImage(treeimage,x,y);
            }
        }
    }
    // reset transform
    ctx.setTransform(1,0);

虑quad tree

我怀疑对 simplex2 的调用会很慢。我见过的所有实现都做得很差。由于单纯形的结果对于任何坐标都是常数,因此在游戏开始之前(在生产代码之外)每个坐标只能执行一次。

由于您想要一个无限(类似)的游戏场(无限是不可能的),因此 RAM 要求太大了。我没有什么可以建议的,除了...放弃无限并为游戏场地大小设置一个实际限制,这将允许您创建一个quad tree地图,让它飞起来。

大佬总结

以上是大佬教程为你收集整理的优化 HTML5 画布游戏循环全部内容,希望文章能够帮你解决优化 HTML5 画布游戏循环所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:优化