Wednesday, June 23, 2010

Faking Click Events

‹prev | My Chain | next›

Last night I got document.elementFromPoint working, even with scrolling, for detecting collisions in my (fab) game. While I was working through scrollTops, scrollLefts, and offsets, it occurred to me that there might be a better way to detect collisions using something that browsers do best: events. Specifically, if I can generate an event on collision, then I ought to be able to use event bubbling to find all items at a given coordinate.

For tonight, I just want to see if I can generate click events from javascript. I know that I can call click handlers, but I'd like to create a click even at 250,250 on the web browser. In my (fab) game, this will result in a player moving to that coordinate.

Try #1:
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 1, 250, 250, 250, 250, false, false, false, 0, null);
window.dispatchEvent(evt);
But nothing happens. Maybe I need to send the event to the canvas element of the raphaël.js paper:
p = player_list.get_player('bob');
p.avatar.paper.canvas.dispatchEvent(evt);
Still nothing!

Ooh! Wait a second. The player did not move on the screen, but the backend recorded an event so maybe something is working.

Ah, fer crying out loud! My player was already at 250,250 in the room. What made me think to send an event to the current location? Even if it worked, the player would not visibly move. So let's try moving to 50,50 instead:
evt.initMouseEvent("click", true, true, window, 1, 50, 50, 50, 50, false, false, false, 0, null);
p.avatar.paper.canvas.dispatchEvent(evt);
Gah! Nothing.

This time, however, I check the event in Chrome's Javascript console and see that the event that I sent is still going to 250,250. I must need to re-initialize the event with document.createEvent(). So...
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 1, 50, 50, 50, 50, false, false, false, 0, null);
p.avatar.paper.canvas.dispatchEvent(evt);
Success! Finally my player moves.

I spend a little more time fiddle with the screenX/screenY and clientX/clientY coordinates in the evt.initMouseEvent call (arguments 6/7 and 8/9 respectively). Eventually I boil it down to simply needing to send clientX/clientY to make things work as desired:
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 1, 0, 0, 50, 450, false, false, false, 0, null);
p.avatar.paper.canvas.dispatchEvent(evt);
Since I am sending clientX/clientY, I do need to account for page offsets. Luckily, I learned all about that last night.

Up tomorrow, I will see if I can decorate click events so that real events will result in player movement, but others can be used to detect collisions.


Day #143

No comments:

Post a Comment