Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CreateJS caching object - object now does not animate on stage

I am using CreateJS to add graphics (shapes) and bitmaps to my stage, and add that to my HTML5 canvas.

After moving the circle graphic around the screen (20px in size), there was severe lag after a little while.

I followed this article to figure out performance issues: http://blog.toggl.com/2013/05/6-performance-tips-for-html-canvas-and-createjs/

So I tried caching... now when I press the keys, the circle does not move. Am I caching incorrectly?

world = new createjs.Container();   

segment = new createjs.Shape();
segment.graphics.beginFill("red").drawCircle(0, 0, 20);
segment.x = 100;
segment.y = 100;

segment2 = new createjs.Shape();
segment2.graphics.beginFill("black").drawCircle(0, 0, 20);
segment2.x = 150;
segment2.y = 150;

ContainerOfPeople = new createjs.Container();   
ContainerOfPeople.addChild(segment, segment2);

world.addChild(ContainerOfPeople); //add container of people to world container (which will contain all objects in a container)
world.cache(0, 0, 1000, 1000); //cache all objects within world container

stage.addChild(world);

Edit:

If I don't cache the tiles after creating the map, I can see them rendered to the canvas:

function createWorld() {
    background = new createjs.Container();      

    for (var y = 0; y < mapWidth; y++) {
        for (var x = 0; x < mapHeight; x++) {
            var tile = new createjs.Bitmap('images/tile.png');
            tile.x = x * 28;
            tile.y = y * 30;
            background.addChild(tile);
        }
    }
    //background.cache(0, 0, mapWidth, mapHeight);
    stage.addChild(background); 
}

enter image description here

If I do cache the background container of tile children, it won't render

function createWorld() {
    background = new createjs.Container();      

    for (var y = 0; y < mapWidth; y++) {
        for (var x = 0; x < mapHeight; x++) {
            var tile = new createjs.Bitmap('images/tile.png');
            tile.x = x * 28;
            tile.y = y * 30;
            background.addChild(tile);
        }
    }
    background.cache(0, 0, mapWidth, mapHeight);
    stage.addChild(background); 
}

enter image description here

Why?

like image 494
user3871 Avatar asked Jan 23 '26 13:01

user3871


1 Answers

You wouldn't want to cache the whole world if you are animating/moving its child objects. Think of caching as taking a snapshot of the DisplayObject and all of its children. While an item is cached, you won't see any changes you make to the children until you update the cache again as explained in the EaselJS docs:

http://www.createjs.com/Docs/EaselJS/classes/DisplayObject.html#method_cache

cache ( x y width height [scale=1] )

Defined in cache:735

Draws the display object into a new canvas, which is then used for subsequent draws. For complex content that does not change frequently (ex. a Container with many children that do not move, or a complex vector Shape), this can provide for much faster rendering because the content does not need to be re-rendered each tick. The cached display object can be moved, rotated, faded, etc freely, however if its content changes, you must manually update the cache by calling updateCache() or cache() again. You must specify the cache area via the x, y, w, and h parameters. This defines the rectangle that will be rendered and cached using this display object's coordinates.

To expand on the explanation, let's say you have a game character that is a Container made up of 6 child shapes, 2 arms, 2 legs, a body and a head. During gameplay, the character's arms and legs flail around. In this scenario, you DON'T want to cache the character as you would be forced to update the cache each time the arms and legs moved, removing any performance gain from caching.

However, let's say once the character dies, he freezes in a dead position, and alpha fades off the screen. In this case you WOULD cache the character. This is because alpha animations become increasingly CPU intensive with the greater number of shapes it has to consider. By caching the character, you are effectively telling the CPU to tween just one shape instead of 6. You can then uncache once your alpha tween is complete and you want to return the player for round 2.

Update

easeljs loads images asynchronously when they are first referenced. Because you aren't preloading your image, the image data isn't yet loaded into memory when you are caching your background.

http://jsfiddle.net/8EvUX/

Here's a fiddle where the image is embedded as a base64 encoded string and is therefore available to cache immediately to prove the caching works as expected. My suggestion would be to use the preloadjs library to load your image first before adding it to the stage.

like image 96
Andrew Avatar answered Jan 26 '26 02:01

Andrew



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!