getSize() on sprites
rickierich
var titlesprite = new Sprite('shareimage.png', 0);

var title = new TextSprite('Tipoff of Flappyballs, Basketball or Football?');

var titleobject = new SceneObject([ titlesprite, title ]);

var titlespritesize = titlesprite.getSize();

console.log("title size x  " + titlespritesize.x);

this returns  an x value of 1. 

Can anyone see why.

 

for some reason this gives me a size of (1,1)

All 14 Comments
rickierich

Solved it, if you do not load the image first before setting up the sprite, you will not set the size object in the sprite. So it returns a nominal size. of {x:1, y:1}. I do not think it should behave like that. I suspect something in the constructor is not right. The sprite is not acting in a polymorphic way.

Gio

Usually you would either:

 - load an image first, and then create a sprite with that image so the sprite size will be set to the image size

- or set the sprite size explicitly with Sprite.setSize(x,y) and then assign an image to it; if that image has not been loaded, this will initiate the loading process and when the image is ready it will be used by the sprite. Note that you can do this without setting the size too, but until the image is ready it will not know how big it is, so it will default to 1x1.

I'm open to suggestions... what size would you expect it to return if it hasn't been set explicitly and it's using an image that has not been loaded yet?

 

rickierich

I do try and use load image array. But it does not seem to work. The size object should be set at the same time the image is created. It should not be possible to return a size of {1,1} unless that is the actual size of the image preloaded or not. It just is not predictable behaviour.

Gio

Loading images certainly does work, so it's probably worth finding out why it doesn't seem to work in your case.

One of the features of Wade is that you can use sprites even when related assets are not ready, so you can load things in the background and still be able to use your sprites while they are loading (for example something like Google maps). So throwing an error when you call getSize() on a sprite whose size has yet to be determined is not really an option. Returning undefined would be better, but still a bit annoying in some cases.

It does give you a warning in the console if you try to use a sprite with an image that has not been loaded yet.

But... the beauty of it is that you can override anything to suit your specific needs.

You know if an image has been loaded and is ready to use or not (using wade.getLoadingStatus). And in fact you can use this to change how getSize works if you like. Just add the following code after wade.js is loaded (and before your app is initialized), if this is what you want:

var getSize = Sprite.prototype.getSize;
Sprite.prototype.getSize = function() {
    if (wade.getLoadingStatus(this.getImageName()) != 'ok') {
         throw new Error('Calling getSize before loading image');
    }
    return getSize.call(this);
};

 

rickierich

Whether or not it is loaded does not necessarily relate to whether you have called it or not. I have called it, but html5 carries on executing code while it fetches it and sorts it out. So when you come to use it if size is not there it returns {1,1}. It is completely none deterministic. Sometimes it gives you the size sometimes it does not.

Gio

Yes that's right, you should wait for images (and other assets) to load before you create sprites etc.

App = function() {

    // load all your assets here
    this.load = function() {
        wade.loadImage('myImage.png');
    };

    // when this function is called, all your assets are ready to use
    this.init = function() {
        var mySprite = new Sprite('myImage.png');
    };
};

 

rickierich

The problem with this approach is that if you are doing a facebook game. and use this.load, you will not be able to correlate it to the progress bar of facebook.

Assuming this.load is run by wade first. 

Gio

I understand why it may seem that way, but that is not correct. You can update the progress bar with that approach, let me explain how it works:

1. wade executes the load function, where you start to load your assets

2. normal javascript execution of your code continues normally

3. when all assets have finished loading, wade executes the init function

So after the load function has been executed, and before the init function is executed, you can (and should) update your facebook progress bar.

For example:

App = function() {

    var updateProrgessBarInterval;
    var updateFacebookProgressBar = function() {
        var percentLoaded = wade.getLoadingPercentage();        
        // use percentLoaded to update facebook bar

        if (percentLoaded == 100) {
            clearInterval(updateProgressBarInterval);
        }
    };


    // load all your assets here
    this.load = function() {
        wade.loadImage('myImage.png');
        wade.loadAudio('myMusic.mp3');

        updateProgressBarInterval = setInterval(updateFacebookProgressBar);
    };

    // when this function is called, all your assets are ready to use
    this.init = function() {
        var mySprite = new Sprite('myImage.png');
    };
};

This will work if you load all your assets in the load function.

You don't have to do that, but then it gets more complicated to keep track of what's been loaded and is ready to use. But it's still possible and no too difficult.

rickierich
App = function() {

    var updateProgressBarInterval;
    var updateFacebookProgressBar = function() {
        var percentLoaded = wade.getLoadingPercentage();        
        // use percentLoaded to update facebook bar

        if (percentLoaded == 100) {
            clearInterval(updateProgressBarInterval);
        }
    };


    // load all your assets here
    this.load = function() {
        wade.loadImage('myImage.png');
        wade.loadAudio('myMusic.mp3');

        updateProgressBarInterval = setInterval(updateFacebookProgressBar);
    };

    // when this function is called, all your assets are ready to use
    this.init = function() {
        var mySprite = new Sprite('myImage.png');
    };
};
rickierich

does this.load resolve before this.init starts?

 

rickierich

FBInstant.initializeAsync().then(function () 

        {

makes it clunky, you need to set the progress bar after this is called and completed.

You endup having to drop your abstraction, either you use load or init. You cannot really use both as Async functions mean the code will carry on executing out of the order you want. Unless you put it in the then part. That breaks from the flow of your abstraction.

rickierich
App = function() {

    var updateProgressBarInterval;
    var updateFacebookProgressBar = function() {
    var percentLoaded = wade.getLoadingPercentage();   
         
        // use percentLoaded to update facebook bar

         if (percentLoaded == 100)
        {
            clearInterval(updateProgressBarInterval);
            FBInstant.startGameAsync().then(function ()
            {
               ... run actual game.

            });

        }
    
    };


    // load all your assets here
    this.load = function() {
        wade.loadImage('myImage.png');
        wade.loadAudio('myMusic.mp3');

        
    };

    // when this function is called, all your assets are ready to use
    this.init = function() 
    {
        FBInstant.initializeAsync().then(function () 
        {
           updateProgressBarInterval = setInterval(updateFacebookProgressBar, 100);
           var mySprite = new Sprite('myImage.png');
        }
      // this feels messy, I probably want to define another function in init and pass in //updatefacebookprogressbar

    };
};
Gio

Don't call FBInstant.initializeAsync from App.init.

If you want to initialize the facebook sdk before starting wade, you could do it for example in your index.html file

FBInstant.initializeAsync().then(function() {
    wade.init('app.js');
});

 

rickierich

Thanks, I completely blanked on that one.

Post a reply
Add Attachment
Submit Reply
Login to Reply