Object input events

Detect input events occurring on specific objects

Sometimes you want to do different things depending on which objects have been clicked. Of course, you could use the event data and test it against all the objects that you have in the scene, but WADE provides a much easier and more efficient way of doing this.

With an App.onMouseDown function we were responding to mouse events that occurred anywhere in the App. In a similar way, if we define an onMouseDown function for a SceneObject, we can then respond to mouse events that occur on that particular object. We can do this in our init function for now, right after creating our clubs object:

    ....
    // create a clubs sprite
    var clubsSprite = new Sprite('data/clubs.png');
    clubsSprite.setSize(64, 64);
    this.clubsObject = new SceneObject(clubsSprite);
    wade.addSceneObject(this.clubsObject);
    this.clubsObject.setPosition(-130, 0);
    this.clickCount = 1;
    this.clubsObject.onMouseDown = function()
    {
        wade.app.helloObject.getSprite(0).setText('Click ' + wade.app.clickCount);
        wade.app.clickCount++;
    };
    wade.addEventListener(this.clubsObject, 'onMouseDown');

Let's see exactly what's going on: at line 8 we are declaring a (privileged) member variable for our App object, called clickCount. The next few lines (9 to 13) define a function to execute when our clubs object is clicked.

This function is going to be a member of our clubs object, so it would normally only be able to access the properties and methods that are declared in the clubs object's scope. In other words, the helloObject, which is a privileged member of the App function, would be inaccessible. WADE, however, provides an easy way to reference our main App object, simply using wade.app. This means that we can access the helloObject, for example, with wade.app.helloObject.

This is exactly what we're doing at line 11. We're using the helloObject, then accessing its text sprite object (with a call to getSprite()), then changing the text in the text sprite.

Line 12 is simply incrementing a counter, so we know how many times we've clicked. And at line 14 we're doing an important thing, that shouldn't be overlooked: we're telling WADE that we want our clubs object to receive mouse events.

You could try this now, and observe that whenever you click anywhere on the screen the clubs object moves, and when you click the clubs object itself, the hello object displays the number of clicks.

There is, however, one thing that is not working as one might have expected: when you click the clubs object, it still moves. This is because the onMouseDown event is propagating: it's first received by the clubs object, and it's later received by the App object. So both the clubsObject.onMouseDown and the App.onMouseDown functions are being executed.

This would also happen if there were more objects overlapping each other at the event's location: the event would be received by the object on top first, and it would then propagate to all the other objects.

You can stop the event propagation at any time by returning true in an event handling function. So let's insert this line at the end of the clubs object's onMouseDown function:

        return true;

Try it right here

As a slightly more difficult exercise, do you want to try to make the clubs object itself a bit larger every time it's clicked?

(Hint: clubsObject.onMouseDown is a member of clubsObject. This means that inside that function, you can refer to the clubs object as this. Access its sprite object and use its getSize and setSize methods).

App = function() { this.load = function() { wade.loadImage('/assets/tutorial/clubs.png'); }; this.init = function() { // create some text var helloText = new TextSprite('Hello World!', '32px Verdana', 'red', 'center'); this.helloObject = new SceneObject(helloText); wade.addSceneObject(this.helloObject); // create a clubs sprite var clubsSprite = new Sprite('/assets/tutorial/clubs.png'); clubsSprite.setSize(64, 64); this.clubsObject = new SceneObject(clubsSprite); wade.addSceneObject(this.clubsObject); this.clubsObject.setPosition(-130, 0); this.clickCount = 1; this.clubsObject.onMouseDown = function() { wade.app.helloObject.getSprite(0).setText('Click ' + wade.app.clickCount); wade.app.clickCount++; return true; }; wade.addEventListener(this.clubsObject, 'onMouseDown'); }; this.onMouseDown = function(eventData) { this.clubsObject.moveTo(eventData.screenPosition.x, eventData.screenPosition.y, 400); }; };