Chris Evans
Chris Evans

Reputation: 993

A better way of writing (javascript)

Probably a lack of understanding of javascript here:

engine.keyboard = {};   // keyboard object

engine.keyboard.key = {
_pressed: {},

UP: 38,
DOWN: 40,
LEFT: 37,
RIGHT: 39,

isDown: function(keyCode)
{
    return this._pressed[keyCode];
},

onKeyDown: function(event)
{
    this._pressed[event.keyCode] = true;
},

onKeyUp: function(event)
{
    delete this._pressed[event.keyCode];
}

}

engine.keyboard.addListeners = function()
{
window.addEventListener('keydown', engine.keyboard.key.onKeyDown, false);
window.addEventListener('keyup', engine.keyboard.key.onKeyUp, false);
}

When I call, engine.keyboard.key.isDown(38), I get an error that this._pressed is undefined.

Perhaps there is a better way of defining all these? I'm working on a very basic game but just experimenting with different ways of splitting it all up. So at the moment, I have engine, engine.keyboard, engine.camera and engine.map which all do there own tiny bits. I've used the same engine.EXAMPLE = {} at the start of each one. Perhaps this is inefficient?

Cheers.

Upvotes: 3

Views: 225

Answers (2)

Felix Kling
Felix Kling

Reputation: 816462

The problem is that you are only passing the function as event handler. By doing so it has no relation to the engine.keyboard.key object anymore.

What this inside a function refers to depends on how it is called. In order for this to refer to engine.keyboard.key, the function has to be called like

engine.keyboard.key.onKeyDown()

So what you need is:

window.addEventListener('keydown', function(event) {
    engine.keyboard.key.onKeyDown(event);
}, false);

window.addEventListener('keyup', function(event) {
    engine.keyboard.key.onKeyUp(event);
}, false);

Also note that addEventListener is not available in up to IE8. There you have to use attachEvent.

I suggest to read the excellent articles about event handling on qurirksmode.org.


Further suggestion:

To decouple the function from the object in a way, you can create a closure:

engine.keyboard = {};  
engine.keyboard.key = (function() {
    var _pressed = {};

    var key = {
        UP: 38,
        DOWN: 40,
        LEFT: 37,
        RIGHT: 39,

        isDown: function(keyCode)  {
            return _pressed[keyCode];
        },

        onKeyDown: function(event) {
            _pressed[event.keyCode] = true;
        },

        onKeyUp: function(event) {
            delete _pressed[event.keyCode];
        }
    }
    return key;
}());

Here there is no problem to pass engine.keyboard.key.onKeyDown as the functions don't rely on this anymore. _pressed is now a variable in scope the functions are defined in, so they have all access to it.

This is just to show what can be done.

Upvotes: 3

Yserbius
Yserbius

Reputation: 1414

That's a standard key handler. I do not believe there is a better way to do things.

Upvotes: -1

Related Questions