wizardzeb
wizardzeb

Reputation: 1596

addEventListener with requestAnimationFrame

I'm using window.requestAnimationFrame to create a game loop.

Everything works great, but when I try to add an event listener it fires hundreds of times really fast.

I've tried using a closure, but that doesn't seem to work.

game.update = function(){
   //code that runs every frame
   window.addEventListener('keydown', function(){
      console.log("message");
   },false);
}

I want to call a function ONCE on the keydown event not multiple times.

Upvotes: 2

Views: 2429

Answers (2)

jdmayfield
jdmayfield

Reputation: 1527

Maybe A bit late, but this doesnt quite make sense to me. The listener should not be added inside the RAF. If you put it outside, and assign the handler's result to a variable, then have the RAF get the result and clear the variable, you will have both faster and more stable/predictable performance. This becomes really obvious for similar tasks, such as using device orientation listeners for controller input on mobile. Events dont need to be looped. Set it once, it'll fire once every time a key is downed. The RAF should only be used to update graphics. Any other logic should be outside it. For example, movement and game mechanics should bein a setInterval pointing their results to variables and objects outside but accessible to the RAF. The RAF should only pick up the new position values and set the transforms. Then it'll run more smoothly, and 'time' will not speed up or slow down, and be consistent on different devices, regardless of frame-rate.

Upvotes: 0

Marat Tanalin
Marat Tanalin

Reputation: 14123

Event listener is only added if a new listener is added. Adding the same listener more than once has no effect by design.

Move your listener function out of the function you’re assigning to game.update so that a new copy of listener wouldn’t be created each time you call addEventListener():

var updateListener = function() {
    console.log('message');
};

game.update = function() {
    //code that runs every frame
    window.addEventListener('keydown', updateListener, false);
};

Upvotes: 1

Related Questions