More events

An overview of some more events provided by WADE

WADE provides quite a few events that your scene objects can listen to. However, since they all work in the same way, I'm only going to demonstrate one more type of event here. But it's still worth mentioning a couple of useful ones: the onResize event, that fires whenever the app's window is resized, and the onAppTimer event, that fires once a second by default, unless you change that with a call to wade.setAppTimerInterval. This is useful to execute some scripts that deal with high-level logic of your app, that need to be updated periodically, but not too often.

The nice thing about WADE is that, unlike other engines that are written in a specific programming language and then support a different scripting language to handle the high-level logic, it's entirely written in javascript. Since both the engine and the app share the same dynamic language, and you can access the engine object from your app, you can override any part of it, even its handling of internal events.

For example, scene objects in WADE are simulated 30 times per second by default; this happens because scene objects listen to 'onSimulationStep' events, that fire 30 times per second. WADE manages this internally, temporarily disabling the simulation for some objects when it knows that simulating them will have no effect, in order to be as efficient as possible. However, nothing is stopping you from overriding any scene object's step function with your own function, and manually listen to 'onSimulationStep' events, if you need complete low-level control over that scene object's behavior.

The last event that we're going to demonstrate to complete this chapter is the onMoveComplete event. Just for fun, when our symbol object reaches its destination, we're going to make it play its animation again. This will cause the onAnimationEnd event to fire after some time, which will in turn call the moveTo method of the object, and so on. Let's add these lines at the end of our init function, right after defining the onAnimationEnd function:

    // handle onMoveCompleteEvent
    this.symbolObject.onMoveComplete = function()
    {
        this.playAnimation('test animation');
    };

Now you can save and try the app, it's good fun. No, not really, but it's interesting anyway.

You'll notice that we used this.playAnimation there. Being inside a function that is a member of symbolObject, this refers to the symbolObject, which is a SceneObject. Previously, you may remember that we called playAnimation for a Sprite object instead. This is basically the same thing, but there is a subtle difference: calling playAnimation on the SceneObject will play that animation for all the sprites that belong to the scene object, if they have an animation with that name.

So far we've only used one sprite for each scene object, but to demonstrate this point, we'll create another one, and pass both sprites (as an array), to the scene object's constructor. So let's go back to our init function, where we created our sprite and our scene object:

    this.init = function()
    {
        // create a sprite
        var sprite = new Sprite();
        sprite.setSize(80, 80)
        var animation = new Animation('data/symbols.png', 4, 1, 1.5, 0, 0, 2);
        sprite.addAnimation('test animation', animation);

        // create another sprite
        var anotherSprite = new Sprite();
        anotherSprite.setSize(32, 32);
        var anotherAnimation = new Animation('data/symbols.png', 4, 1, 3, true, 0, 3);
        anotherSprite.addAnimation('second animation', anotherAnimation);

        // create a scene object with both sprites
        this.symbolObject = new SceneObject([sprite, anotherSprite]);
        wade.addSceneObject(this.symbolObject);
        sprite.playAnimation('test animation');
        anotherSprite.playAnimation('second animation');

        ....

If you run your application now, you'll see that although the scene object is now made of 2 sprites, that move together, calling symbolObject.playAnimation('test animation') has no effect on the second sprite's animation, because the second sprite has no animations with that name.

This is pretty much all you need to know about the fundamentals of WADE. In the following chapter we'll look at some more advanced stuff, and we'll start building a simple game. Simple but fun, I promise.

 

Try it right here

 

Consider this as a final an exercise: the second animation that we created is looping. If you set it to not loop, when it's over the onAnimationEnd event will fire. That is, the same event will fire twice for the same scene object, once for the first sprite's animation, and once for the second sprite's animation. However, remember what we said about event data? You can accept an argument in the onAnimationEnd function, that is an object whose 'name' field will tell you which animation the event is firing for.

So can you make the symbol object do different things depending on which animation is finished playing?

App = function() { this.load = function() { wade.loadImage('/assets/tutorial/symbols.png'); }; this.init = function() { // create a sprite var sprite = new Sprite(); sprite.setSize(80, 80); var animation = new Animation('/assets/tutorial/symbols.png', 4, 1, 1.5, 0, 0, 2); sprite.addAnimation('test animation', animation); // create another sprite var anotherSprite = new Sprite(); anotherSprite.setSize(32, 32); var anotherAnimation = new Animation('/assets/tutorial/symbols.png', 4, 1, 3, true, 0, 3); anotherSprite.addAnimation('second animation', anotherAnimation); // create a scene object with both sprites this.symbolObject = new SceneObject([sprite, anotherSprite]); wade.addSceneObject(this.symbolObject); sprite.playAnimation('test animation'); anotherSprite.playAnimation('second animation'); // handle onAnimationEnd event this.symbolObject.onAnimationEnd = function() { var posX = (Math.random() - 0.5) * wade.getScreenWidth(); var posY = (Math.random() - 0.5) * wade.getScreenHeight(); this.moveTo(posX, posY, 400); }; // handle onMoveCompleteEvent this.symbolObject.onMoveComplete = function() { this.playAnimation('test animation'); }; }; };