Guian
Guian

Reputation: 4689

Flipped SpriteSheet animation using EaselJS after preloading the image

I'm trying to flip horizontally the sprites from a SpriteSheet animation. I'm starting from this example

I've added the flipped frames right after creating the SpriteSheet

    var ss = new createjs.SpriteSheet(spriteSheet);

    createjs.SpriteSheetUtils.addFlippedFrames(ss, true, false, false);

    grant = new createjs.BitmapAnimation(ss);
...

And I always get this error :

Uncaught TypeError: Cannot read property 'length' of null    (SpriteSheetUtils.js l.174)

I've seen that someone has got the same problem in this github thread And fixed it using the preload mecanism.

The example is also using the preload so I've tried to call the addFlippedFrames after the resource loading, but I'm still seeing the same error.

Does anyone have a clue for me ? how can I use addFlippedFrames ?

EDIT : here is the code I tried :

Init the stage with my spritesheet :

    spriteSheet = new createjs.SpriteSheet({
        "animations": {
            "none": [0, 0],
            "run": [0, 25],
            "jump": [26, 63]
        },
        "images": ["characters/grant/runningGrant.png"],
        "frames": {
            "height": h,
            "width": w,
            "regX": 0,
            "regY": 0,
            "count": 64
        }
    });



    sprite = new createjs.BitmapAnimation(spriteSheet);
    sprite.x = startPosition.x;
    sprite.y = startPosition.y;

// Add the sprite to the stage.
stage.addChild(this.sprite);

Then use the preload like this :

var manifest = [{
        src: "characters/grant/runningGrant.png",
        id: "grant"
    }
];

var loader = new createjs.LoadQueue(false);
loader.onFileLoad = handleFileLoad;
loader.onComplete = onResourcesLoaded;
loader.loadManifest(manifest);

and the callback functions :

handleFileLoad = function(event) {
    assets.push(event.item);
};

onResourcesLoaded = function() {

    for (var i = 0; i < assets.length; i++) {
        var item = assets[i];
        var id = item.id;
        var result = loader.getResult(id);

        if (item.type == createjs.LoadQueue.IMAGE) {
            var bmp = new createjs.Bitmap(result);
                //does this Bitmap creation trigger the real bitmap loading ?
                //is this loading asynchrous which would explain my problem.
                //in this case, how can I manage the loading callback ?
        }
    }

    //I would expect here to have the image fully loaded but its not
    //A timeout of 2 seconds makes the addFlippedFrames works.
    setTimeout(function(){
            createjs.SpriteSheetUtils.addFlippedFrames(spriteSheet, true, false, false);
            sprite.gotoAndPlay("run_h"); //I think "run_h" is used to launch the flipped version of "run"
    }, 2000);
};

Upvotes: 2

Views: 2477

Answers (2)

Xereoth
Xereoth

Reputation: 21

It's easy to do with scaleX

if(right == true)
    {
        //walking direction en sprite switch
        rogerWalk.scaleX = -1 * rogerWalk.scaleX;
        right = false;
    }

//code i used to make (in this case roger walk right(standard sprite direction)

if(right == false)
    {
        rogerWalk.scaleX = -1 * rogerWalk.scaleX;
        right = true;

//this is in the keyleft/keyright function i have

i know the post it old but still someone might be able to use it :)

Upvotes: 2

Olaf Horstmann
Olaf Horstmann

Reputation: 16882

Your issue was, that you created a SpriteSheet with an image-url, this triggered a loading process already, and the preload-js queue actually loaded nothing, because the loading for the image was already in progress, so the "onComplete"-event was allways triggered before the image was actually loaded - which makes sense, because there is no need to load an image twice

I've updaded your jsfiddle and added some comments: http://jsfiddle.net/K4TmS/1/ (full code)

spriteSheet = new createjs.SpriteSheet({
            "animations": {
                "none": [0, 0],
                "run": [0, 25],
                "jump": [26, 63]
            },
            //this line in YOUR version triggered an own loading process, independent from the queue
            "images": [result],  
            "frames": {
                "height": 292.5,
                "width":165.75,
                "regX": 0,
                "regY": 0,
                "count": 64
            }
        });

// this was executed instantly, because the image was already in another loading progress, and therefore wasn't even added to the queue
loader.onComplete = onResourcesLoaded;

The DOM Security Error18 can be ignored with this argument here (for development) Disable same origin policy in Chrome But for production you should just load the img from the same server, then image-operations won't give an error.

So in short: Your issue was due to the wrong order of executing things, remember: if you use preloading: Do preloading before EVERYTHING else, and do NOTHING else untill the preloading isn't done. (Except for a loading-graphic/animation/indicator).

Upvotes: 3

Related Questions