Javascript CreateJS/EaselJS具有特定大小形状的奇怪性能

Javascript CreateJS/EaselJS具有特定大小形状的奇怪性能,javascript,html,canvas,easeljs,createjs,Javascript,Html,Canvas,Easeljs,Createjs,我目前正在开发一个游戏,它使用一个大的平铺地图,可以在周围拖动,并与您的角色快速移动 我已经创建了问题的简单版本 每个磁贴都是一个形状,并且被缓存。 所有形状都位于容器内,容器根据相机位置移动 我注意到某些缩放级别的fps出现了奇怪的下降。 缩放只是调整形状的大小 如果调整缩放,您将看到我的意思。 铬 缩放1=良好的fps 缩放3=错误的fps 缩放5=良好的fps 这个帧速率问题的原因是什么? 注意,我也在createjs社区论坛上发布了这篇文章。 下面是JSFIDLE示例中的代码 HTM

我目前正在开发一个游戏,它使用一个大的平铺地图,可以在周围拖动,并与您的角色快速移动

我已经创建了问题的简单版本

每个磁贴都是一个形状,并且被缓存。 所有形状都位于容器内,容器根据相机位置移动

我注意到某些缩放级别的fps出现了奇怪的下降。 缩放只是调整形状的大小

如果调整缩放,您将看到我的意思。

铬 缩放1=良好的fps
缩放3=错误的fps
缩放5=良好的fps

这个帧速率问题的原因是什么? 注意,我也在createjs社区论坛上发布了这篇文章。

下面是JSFIDLE示例中的代码

HTML

装载FPS
JS
/*
这是我正在创建的大型应用程序/游戏的一个非常简单的版本
使用在扇区中绘制的大型地图(createjs形状)
我还没有找到最好的缓存方式,因为如果我一次缓存所有的数据,会产生很大的开销。
我的主要问题是缩放级别,缩放只是调整扇区大小。
问题在于,在某些缩放级别上似乎存在wierd性能问题。
要对此进行测试,请调整“摄影机缩放”属性。我不推荐任何超过6的东西。
*/
//一般设置
变量设置={
砌块尺寸:50,
行:50,
科尔斯:50
}
//创建摄影机
var摄像机={
/*
这里是缩放问题
铬
缩放:1=良好的fps
缩放:2-4=错误的fps
缩放:5-6=再次获得良好的fps…wtf
游猎
缩放:7=良好的fps
*/
x:0,,
y:0,
缩放:1
}
//创建短别名
var Stage=createjs.Stage;
var Ticker=createjs.Ticker;
var Container=createjs.Container;
var Graphics=createjs.Graphics;
var Shape=createjs.Shape;
//全屏画布
var canvas=document.getElementById(“mainCanvas”);
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//创造舞台
var主干=新阶段(画布);
mainStage.snameToPixelsEnabled=true;
mainStage.autoClear=true;
//启动计时器
Ticker.addListener(这个);
Ticker.useRAF=true;
股票代码setFPS(30);
//创建容器;
var mainContainer=新容器();
maincainer.snapToPixel=true;
//将容器添加到后台
mainStage.addChild(主容器);
//创建许多形状
var size=Settings.block\u size*Camera.zoom;
//为了演示,我只创建了一个正方形
//我的实际应用程序有更复杂的绘图
var graphics=新图形();
graphics.setStrokeStyle(1*Camera.zoom,“圆形”);
图.Beginull(图.getRGB(230230,0.5));
graphics.beginStroke(空);
图形.rect(-10,-10,大小+10,大小+10);
var cols=Settings.cols;
var rows=Settings.rows;
对于(var x=0;x
已解决

我解决了这个问题,通过循环遍历勾号上的每个形状,并应用
visible=false
如果它是出界的

//根据摄影机位置和缩放更新容器位置
updatePosition=函数(){
var floor=Math.floor;
var min_x=0+Camera.x*Camera.zoom-size;
var min_y=0+Camera.y*Camera.zoom-size;
var max_x=屏幕宽度+摄影机.x*摄影机.zoom+大小
var max_y=Screen.height+Camera.y*Camera.zoom+size;
mainContainer.x=-Camera.x*Camera.zoom;
mainContainer.y=-Camera.y*Camera.zoom;
var shape_count=mainContainer.getNumChildren()-1;
对于(var i=0;i max_x){
shape.visible=false;
}
else if(shape.ymax_y){
shape.visible=false;
}
否则{
shape.visible=true;
}
}
}

我注意到的是,如果缓存方块小于某个大小,则帧速率会下降,因此我所做的是:

var cache_offset = 10 * Camera.zoom;
=>
var cache_offset = 10 * Camera.zoom + 77;
我对77做了一点尝试,我最初的想法是缓存区域必须是2的幂,但是在
zoom:3
添加77
会导致缓存大小为364x364px,并且任何大于该大小的缓存都适用于
zoom:3
,所以我不知道为什么,但是缓存矩形的大小会导致帧速率下降


还有一个打字错误(并没有真正影响这个问题):


这使帧速率提高了2-3fps,这是一个有充分证明的问题,但我在Windows7.0上的Chrome24中根本看不到这个问题
/*
This is a very simple version of a larger app/game i am creating
uses a large map that is drawn in sectors (createjs shapes)
I have not figured out the best way to cache, because if i cache all at once, its a lot of overhead.

My main issue is the zoom levels, the zoom simply adjusts the sectorsize.
The problem with this is that there seems to be a wierd performance problem at certain zoom levels.

To test this out, adjust the camera zoom property. I do not recommend anything more that 6.
*/

//Generic Settings
var Settings = {
    block_size: 50,
    rows: 50,
    cols: 50
}

//Create Camera
var Camera = {
    /*

    HERE IS THE ZOOM PROBLEM

      Chrome
      zoom : 1 = good fps
      zoom : 2 - 4 = bad fps
      zoom : 5 - 6 = good fps again ... wtf

      Safari
      Zoom: 7 = Good fps

  */
    x: 0,
    y: 0,
    zoom:1
}

//Create Short Alias
var Stage = createjs.Stage;
var Ticker = createjs.Ticker;
var Container = createjs.Container;
var Graphics = createjs.Graphics;
var Shape = createjs.Shape;


//Full Screen Canvas
var canvas = document.getElementById("mainCanvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

//Create Stage
var mainStage = new Stage(canvas);
mainStage.snameToPixelsEnabled = true;
mainStage.autoClear = true;

//Start Ticker
Ticker.addListener(this);
Ticker.useRAF = true;
Ticker.setFPS(30);

//Create Container;
var mainContainer = new Container();
mainContainer.snapToPixel = true;

//Add Container to Stage
mainStage.addChild(mainContainer);


//Create Lots of Shapes
var size = Settings.block_size * Camera.zoom;

//For the purpose of demonstration, I am only creating a square
//My actual app has much more complex drawings
var graphics = new Graphics();
graphics.setStrokeStyle(1 * Camera.zoom, "round");
graphics.beginFill(Graphics.getRGB(230,230,230,0.5));
graphics.beginStroke(null);
graphics.rect(-10, -10, size+10, size+10);


var cols = Settings.cols;
var rows = Settings.rows;
for (var x = 0; x < cols; x++) {
    for (var y = 0; y < rows; y++) {

        var shape = new Shape(graphics);
        shape.x = x * size;
        shape.y = y * size;

        //Cache the shape, (the offset is to prevent the cache from chopping off complex shapes)
        var cache_offset = 10 * Camera.zoom;
        shape.cache(-cache_offset,-cache_offset, size + cache_offset, size + cache_offset);

        //Add shape to container
        mainContainer.addChild(shape);
    }
}

//Make map draggable
var lastX,lastY;

mainStage.onMouseDown = function(evt){
    lastX = evt.stageX;
    lastY = evt.stageY;
}

mainStage.onMouseMove = function(evt){
    if(lastX && lastY){
        var stageX = evt.stageX;
        var stageY = evt.stageY;
        var diffX = lastX - stageX;
        var diffY = lastY - stageY;
        lastX = stageX;
        lastY = stageY;
        Camera.x += diffX / Camera.zoom;
        Camera.y += diffY / Camera.zoom;
    }    
}

mainStage.onMouseUp = function(evt){
    lastX = null;
    lastY = null;
}

//Update the container position based on camera position and zoom
updatePosition = function(){
    mainContainer.x = -Camera.x * Camera.zoom;
    mainContainer.y = -Camera.y * Camera.zoom;
}


tick = function(){
    updatePosition();
    mainStage.update();
    var fps = document.getElementById('fps');
    fps.innerHTML = Ticker.getMeasuredFPS();
}
//Update the container position based on camera position and zoom
updatePosition = function () {

    var floor = Math.floor;

    var min_x = 0 + Camera.x * Camera.zoom - size;
    var min_y = 0 + Camera.y * Camera.zoom - size;
    var max_x = Screen.width + Camera.x * Camera.zoom + size
    var max_y = Screen.height + Camera.y * Camera.zoom + size;



    mainContainer.x = -Camera.x * Camera.zoom;
    mainContainer.y = -Camera.y * Camera.zoom;

    var shape_count = mainContainer.getNumChildren() - 1;

    for (var i = 0; i <= shape_count; i++) {
        var shape = mainContainer.getChildAt(i);

        if(shape.x < min_x || shape.x > max_x){
            shape.visible = false;
        }
        else if(shape.y < min_y || shape.y > max_y){
           shape.visible = false; 
        }
        else {
            shape.visible = true;
        }

    }

}
var cache_offset = 10 * Camera.zoom;
=>
var cache_offset = 10 * Camera.zoom + 77;
mainStage.snameToPixelsEnabled = true;
=>
mainStage.snapToPixelEnabled = true;