仅在可见区域绘制画布

时间:2017-06-09 11:29:47

标签: javascript performance canvas viewport

我正在开发简单的迷你游戏,我开始注意到一些性能下降。游戏的制作方式是你拥有5000 x 5000大小的大房间(画布),并且玩家配备了可以在鼠标拖动时移动的视口相机。现在的问题是,如果我为整个房间绘制2000个对象,它会导致显着的性能下降。我在想是否有办法只绘制当前相机区域中可见的物体,而不是整个房间中玩家显然看不到的物体。

我试图将扇区划分为扇区(区域),但这种方法效果不佳。也许有人对这个问题有一些想法。

这是渲染最大数量对象的代码:

for(var i = 0; i < game.objects.stars.pool.length; i++) {
    var current = game.objects.stars.pool[i];
    game.components.star.apply(i);
    game.mechanics.draw.circle(current.x, current.y, current.r);
}

可以采取哪些措施以我所描述的方式改善表现?

2 个答案:

答案 0 :(得分:0)

我的建议是检查当前对象是否在边界内,如果是,则只绘制它,所以:

for(var i = 0; i < game.objects.stars.pool.length; i++) {
    var current = game.objects.stars.pool[i];
    if (withinBounds(current)){
        game.components.star.apply(i);
        game.mechanics.draw.circle(current.x, current.y, current.r);    
    }
}

function withinBounds(gameObject){
    if (gameObject.x + gameObject.r < viewPort.x && viewPort.x - gameObject.r > viewPort.x + viewPort.width) {
        if ( gameObject.y + gameObject.r < viewPort.y && gameObject.y - gameObject.y > viewPort.y + viewPort.height){
            return false;
        } else {
            return true;
        }
    } else {
        return true;
    }
}

其中视口与5000 x 5000区域相关。

这没有看到您的所有代码,因此您可能需要针对您的数据类型进行调整。

答案 1 :(得分:0)

我遇到过这种问题,我就这样解决了:

var in_viewport = function(x, y, margin) {
    if(
        x >= cam.x - margin &&
        x <= cam.x + cam.w + margin &&
        y >= cam.y - margin &&
        y <= cam.y + cam.h + margin
    ) {
       return true;
    }

    return false;
};

它可以像你这样实现在你的逻辑中:

for(var i = 0; i < game.objects.stars.pool.length; i++) {
    var current = game.objects.stars.pool[i];
    if( in_viewport(current.x, current.y, 100) === true ) {
        game.components.star.apply(i);
        game.mechanics.draw.circle(current.x, current.y, current.r);
    }
}

现在几句解释:

建议将保证金参数设置为100,因为这样可以帮助解决出现问题的问题。#34;它只会渲染摄像机外部100范围内的物体,因此即使您快速移动相机,事情应该已经存在,但性能应该非常好。

如果您已经拥有cam.xcam.ycam.wcam.h内部in_viewport功能,则应更改以匹配您的相机对象命名你的右边和底部绑定在相机对象内,你可以用正确的参数替换x + wy + h