CreateJS / EaselJS 具有特定尺寸形状的奇怪性能
Posted
技术标签:
【中文标题】CreateJS / EaselJS 具有特定尺寸形状的奇怪性能【英文标题】:CreateJS / EaselJS Strange Performance with certain size shapes 【发布时间】:2013-01-21 07:10:23 【问题描述】:我目前正在开发一款游戏,它使用了一个大的平铺地图,可以拖动,并随着你的角色快速移动。
我已经创建了问题的简单版本 JSFiddle Example
每个图块都是一个Shape并且被缓存。 所有形状都放在一个容器中,容器会根据相机位置移动。
我注意到在某些缩放级别下 fps 出现了奇怪的下降。 缩放只是调整形状的大小。
如果你调整缩放,你会明白我的意思。
铬
缩放 1 = 良好的 fps 缩放 3 = 糟糕的 fps 缩放 5 = 良好的 fps
出现这个帧率问题的原因是什么?
请注意,我也在 createjs 社区论坛上发布了此内容。Community Question
这是 jsfiddle 示例中的代码
html
<canvas id="mainCanvas" ></canvas>
<span id="fps-container"><span id="fps">Loading</span> FPS</span>
JS
/*
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();
【问题讨论】:
+1 表示有据可查的问题,但我在 Windows 7 上的 Chrome 24 中根本看不到问题。 你的“游戏”完全崩溃了 firefox(latest,win7)。您可能希望在 chrome 以外的地方对其进行测试。 是的,抱歉,问题非常不一致。我会尝试进一步缩小范围。 [下面的固定示例]。 【参考方案1】:已解决。
我通过在刻度上循环遍历每个形状并应用visible = false;
解决了这个问题
如果超出范围Updated Fixed Example
//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;
【讨论】:
【参考方案2】:我注意到是,如果缓存方块小于某个大小,帧率会下降,所以我做了什么:
var cache_offset = 10 * Camera.zoom;
=>
var cache_offset = 10 * Camera.zoom + 77;
我稍微玩了一下 77,我最初的想法是缓存区域必须是 2 的幂,但是在zoom:3
,adding 77
导致缓存大小为 364x364px 和任意大小以上对于zoom:3
也适用,所以我不知道为什么,但是缓存矩形的大小会以某种方式导致帧率下降。
还有一个错字(不会真正影响这个问题):
mainStage.snameToPixelsEnabled = true;
=>
mainStage.snapToPixelEnabled = true;
这将帧率提高了大约 2-3fps
【讨论】:
[+1] 感谢您的错字!是的,它肯定是矩形的大小导致下降。欣赏输入,将调整缓存大小。这是仅在视图中缓存的更新版本。 jsfiddle.net/Bodman/28Jqa 有时仍然滞后。以上是关于CreateJS / EaselJS 具有特定尺寸形状的奇怪性能的主要内容,如果未能解决你的问题,请参考以下文章
我怎样才能用easeljs-0.8.0.js画一条线?(createJs)
canvas 动画库 CreateJs 之 EaselJS(上篇)
canvas 动画库 CreateJs 之 EaselJS(上篇)