KeyListener in TypeScript and "this" context

I am writing a Snake game in TypeScript and cannot determine the KeyListener (arrow keys to change the direction of the snake).

I have a 4-layer architecture, and key events are handled in the Gui class. This holds the Snake object, draws a snake, and processes key events.

I tried the usual path, but inside the handleEvt the snake object is undefined.

document.addEventListener("keydown", handleEvt)

So, I tried the thick arrow method, but now the function is not called at all. I suspect that the key listener has changed context and is no longer working on the window

document.addEventListener("keydown", () => handleEvt)

Can anyone explain what the problem is? It would be very grateful!

Below is my Gui class:

/// <reference path="../model/Snake.ts" />
/// <reference path="../model/Direction.ts" />
/// <reference path="../model/Part.ts" />
/// <reference path="../dao/Dao.ts" />
/// <reference path="../service/Service.ts" />
/// <reference path="../model/IPosObject.ts" />

module gui {

    export class Gui {
        snake:model.Snake;
        canvas:HTMLCanvasElement;
        ctx:CanvasRenderingContext2D;
        loop:any;

        lineWidth:number;
        canvasSize:number;
        loopSpeed:number;
        unitLength:number;

        constructor(snake:model.Snake) {
            // init constants
            this.snake = snake;
            this.lineWidth = 3;
            this.canvasSize = 200;
            this.loopSpeed = 1000/60;
            this.unitLength = 5;

            // init canvas
            this.canvas = document.getElementsByTagName("canvas")[0];
            this.canvas.width = this.canvasSize;
            this.canvas.height = this.canvasSize;
            this.ctx = this.canvas.getContext("2d");

            // Attach key event
//            document.addEventListener("keydown", this.handleEvt);
            document.addEventListener("keydown", () => this.handleEvt);

            // activate game loop
            this.loop = setInterval( () => this.gameLoop(), this.loopSpeed );
        }

        handleEvt(e):void {
            var direction:model.Direction;

            if (e) {
                switch (e.which) {
                    case 37:
                        console.log("left");
                        direction = model.Direction.Left;
                        break;
                    case 38:
                        console.log("up");
                        direction = model.Direction.Up;
                        break;
                    case 39:
                        console.log("right");
                        direction = model.Direction.Right;
                        break;
                    case 40:
                        console.log("down");
                        direction = model.Direction.Down;
                        break;
                }

                this.snake.changeDirection(direction);
            }
        }

        gameLoop():void {
            if (this.snake) {
                this.drawSnake();
            }
        }

        drawSnake() {
          // draw parts
        }
    }

}
+4
source share
1 answer

, addEventListener, , setInterval. keyDown handleEvt, () => this.handleEvt().

, , , : document.addEventListener("keydown", this.handleEvt);

handleEvt :

handleEvt = (e) => {
    var direction:model.Direction;
    ...<snip>
}

: document.addEventListener("keydown", this.handleEvt.bind(this));

, , , . this , , ( ) JavaScript.

+5

All Articles