如何提高 JavaScript 画布模式性能

Posted

技术标签:

【中文标题】如何提高 JavaScript 画布模式性能【英文标题】:How to improve javascript canvas pattern performance 【发布时间】:2021-12-10 05:32:04 【问题描述】:

我正在使用画布创建一个 2D html5 游戏。我目前正在制作非常大的地图(25000px x 25000px)。我现在正在尝试为地图形状添加纹理

代码如下:

let snowPattern;
let sandPattern;
let junglePattern;

const jungleTexture = new Image();
jungleTexture.src = "./assets/game/map/jungleTexture.png";

jungleTexture.onload = function() 
    junglePattern = ctx.createPattern(jungleTexture, "repeat");
;


const snowTexture = new Image();
snowTexture.src = "./assets/game/map/snowTexture.png";

snowTexture.onload = function() 
    snowPattern = ctx.createPattern(snowTexture, "repeat");
;


const sandTexture = new Image();
sandTexture.src = "./assets/game/map/sandTexture.png";

sandTexture.onload = function() 
    sandPattern = ctx.createPattern(sandTexture, "repeat");
;



//Function to draw map shapes
function animate() 

    mapX = document.documentElement.clientWidth / 2 - camera.x * zoom;
    mapY = document.documentElement.clientHeight / 2 - camera.y * zoom;


    ctx.setTransform(1, 0, 0, 1, mapX, mapY);

    //Arctic
    if (document.getElementById("3").checked === true) 
        ctx.fillStyle = snowPattern;
    

    else 
        ctx.fillStyle = "#EFF4F6";
    

    ctx.fillRect(0, 0, 12500 * zoom, 12500 * zoom);



    //Desert

    if (document.getElementById("3").checked === true) 
        ctx.fillStyle = sandPattern;
    

    else 
        ctx.fillStyle = "#E5C068";
    

    ctx.fillRect(12499 * zoom, 0 * zoom, 12500 * zoom, 12500 * zoom);



    //Jungle

    if (document.getElementById("3").checked === true) 
        ctx.fillStyle = junglePattern;
    

    else 
        ctx.fillStyle = "#0F7F2A";
    

    ctx.fillRect(0, 12500 * zoom, 25000 * zoom, 12500 * zoom);

    window.requestAnimationFrame(animate);


animate();

因此,当我只在形状的背景上添加颜色时,它可以完美运行(恒定 144 fps),但使用图案时,我的 fps 会降低到 20。

有人知道如何提高性能吗?

【问题讨论】:

【参考方案1】:

您正在尝试绘制一个巨大的矩形,它会产生预期的开销。这取决于浏览器,但画布有一些限制。当您达到这些限制时,您将遭受性能或崩溃。你可以看到限制here 同样绘制一个巨大的矩形总是会以糟糕的性能结束。

我的建议是:画一个较小的矩形(可能比你的游戏屏幕大一点)并将它移动到矩形的末端,在图案结束之前,再次将它移回。

【讨论】:

谢谢,这是个好主意,我会试试的 如果你觉得这个建议有点难以实现,你可以考虑使用几个矩形而不是一个。在某些情况下,它会更容易实现。 最后,问题不在于尺寸,即使是 50px x 50px 像素的矩形,性能也很糟糕。您需要使用 ctx.beginPath()、ctx.rect、ctx.closePath() 和 ctx.fill() 才能获得正常的性能。【参考方案2】:

最后,问题不在于尺寸,即使是 50px x 50px 像素的矩形,性能也很糟糕。您需要使用 ctx.beginPath()、ctx.rect、ctx.closePath() 和 ctx.fill() 才能获得正常的性能。

【讨论】:

以上是关于如何提高 JavaScript 画布模式性能的主要内容,如果未能解决你的问题,请参考以下文章

缩放 HTML5 画布宽度保留 w/h 纵横比

画布粒子、碰撞和性能

JavaScript知识点总结之如何提高性能

如何将 MB 的数据从 PHP 传递到 Javascript [关闭]

JS 严格模式

如何使用WebAssembly将Web应用的速度提高20倍(案例研究)