Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by alexandre

I'd like to insert entities at runtime, adding their (incoming from a remote server) images to the cache on the fly. Because image paths are not known in advance, they cannot be hard coded into the class.

Best way might be to extend the loader with one or 2 new functions:
ig.Loader.addResource (path)
ig.Loader.addResource (data)

and to make said loader accessible from every instance in a game, e.g.,
this.game.loader.addResource(incomingPath);

Thanks
Alex

1 decade ago by dominic

What should this function do exactly?

If you create an ig.Image instance at runtime, the browser immediately begins to download the resource. The problem is, that you Internet connection is not as fast as your Browser&039;s JavaScript engine, so if you check in the next line of code whether the image is loaded or not, it will report #false. Loading images is "non blocking". JavaScript execution does not stop until the image is loaded.

// This ultimately instructs the browser to download the image
// It will be loaded in the background/another thread
var img = new ig.Image( 'some/path/image.jpg' );

// This, in most cases, will report false. 
// The download of the image resource has just begun and continues to 
// download while JavaScript is still executing.
img.loaded;

If you want to get notified when an image resource has been loaded, you can use the pre-loader again, as described in this thread or use the undocumented load() method of the image and provide a callback:
var img = new ig.Image( 'some/path/image.jpg' );

// This callback function will execute asynchronously, whenever the 
// browser has finished downloading the file.
img.load( function( path, success ) {
	if( success ) {
		ig.log( 'Image successfully loaded: ', path );
	}
	else {
		ig.log( 'Error loading the image: ', path );
	}
});

1 decade ago by alexandre

I couldn't find a way to access my EntityButton instance's context from inside img.load(). I needed that to create my instance's animation sheet. So I ended up doing this:

EntityButton = ig.Entity.extend (
{
	img: null,
	owner: null,
	callback: null,
	needsPostinit: true,
	
	init: function (x, y, settings)
	{
		this.img = new ig.Image (settings.path);
		this.owner = settings.owner;
		this.callback = settings.callback;
		ig.input.bind (ig.KEY.MOUSE1, 'mouse1');
		this.parent (x, y, settings);
	},

	update: function()
	{
		if (this.needsPostinit && this.img.loaded)
		{
			this.animSheet = new ig.AnimationSheet (this.img.path, this.img.width, this.img.height);
			this.addAnim ('idle', 1, [0]);
			this.needsPostinit = false;
		}

		// TODO: respond to mouse1 released and invoke owner's callback

		this.parent();
	}
});
});

1 decade ago by alexandre

On a related matter, more JS than Impact specific, how would I invoke a callback, e.g., something like "this.owner.apply(this.callback)"?

In context:
update: function()
{
	...

	if (ig.input.released('mouse1') && this.boundsInclude(ig.input.mouse.x, ig.input.mouse.y))
	{
		// callback owner
		this.owner.apply(this.callback);
	}

	this.parent();
}

1 decade ago by dominic

Callbacks are no different from any other function. You just call them:
this.callback(); // invoke the callback

If you want to access the EntityButton instance from within the callback, you can use Function.bind() to bind the this.

EntityButton = ig.Entity.extend ({    
    init: function (x, y, settings)
    {
        ...
		var img = new ig.Image( 'some/path/image.jpg' );
		img.load( this.imageLoaded.bind(this) );
    },
	
	imageLoaded: function( path, success ) {
		// this = the EntityButton instance
		if( success ) {
			ig.log( 'Image successfully loaded: ', path );
		}
		else {
			ig.log( 'Error loading the image: ', path );
		}
	},
});

1 decade ago by alexandre

Perfect. Thanks a lot for the hands-on. Much appreciated.

1 decade ago by alexandre

Oops. Except that if "this" is bound to my EntityButton instance, how can I then access the image's width and height from within "imageLoaded", something I must do to set my animation sheet and size?

imageLoaded: function (path, success)
{
	if (success)
	{
		ig.log("image loaded");
		width = ???;
		height = ???;
		this.animSheet = new ig.AnimationSheet (path, width, height);
		this.size = {x:width, y:height};
		this.pos = {x: this.pos.x - this.size.x/2, y:this.pos.y - this.size.y/2};
		this.addAnim ('idle', 1, [0]);
	}
},

1 decade ago by dominic

Set the image as a property of your button instance:
// in init()
this.img = new ig.Image( ... );

// in imageLoaded:
this.img.width;

Btw.: if you don&039;t prefix your variables with the #var keyword (as you did with width and height in your last code snippet), these variable will be global.

1 decade ago by alexandre

Thanks (and I think it's time to brush up on JS some).
Page 1 of 1
« first « previous next › last »