0

我试图在 js/jquery 中实现一个基本的蛇游戏。这是我到目前为止所拥有的:

$('document').ready(function() {

    Game = {
        Snake: function(startingLength) {
            this.snakeComponents = [], this.direction = 'right', this.length = startingLength;

            growSnake = function() {
                this.length += 1;
            }
        },

        gameSnake: {},

        gameSpeed: 0,

        init: function(startingSnakeLength, gameSpeedParam) {


            $.extend(this.gameSnake, new Game.Snake(startingSnakeLength));
            this.gameSpeed = gameSpeedParam;

            for (var i = 0; i < startingSnakeLength; i++) {
                this.gameSnake.snakeComponents.push({
                    x: i,
                    y: 0
                });
            }
            setInterval(Game.update, this.gameSpeed);
        },

        update: function() {
            dx = {
                right: 1,
                left: -1,
                up: 0,
                down: 0
            };
            dy = {
                right: 0,
                left: 0,
                up: 1,
                down: -1
            };

            var snakeLength = this.gameSnake.snakeComponents.length;
            var newSnakeHeadX = this.gameSnake.snakeComponents[snakeLength - 1].x + dx[this.gameSnake.direction];
            var newSnakeHeadY = this.gameSnake.snakeComponents[snakeLength - 1].y + dy[this.gameSnake.direction];

            //update snake components
            this.gameSnake.snakeComponents[snakeLength - 1].x = newSnakeHeadX;
            this.gameSnake.snakeComponents[snakeLength - 1].y = newSnakeHeadY;

            for (var i = 0; i < snakeLength - 1; i++) {
                this.gameSnake.snakeComponents[i].x = this.gameSnake.snakeComponents[i + 1].x;
                this.gameSnake.snakeComponents[i].y = this.gameSnake.snakeComponents[i + 1].y;
            }

            Game.render();
        },

        render: function() {
            for (var i = 0; i < this.gameSnake.length; i++) {
                console.log('Snake position: (' + this.gameSnake.snakeComponents[0].x + ',' + this.gameSnake.snakeComponents[0].y + '), ' + '(' + gameSnake.snakeComponents[1].x + ',' + gameSnake.snakeComponents[1].y + '), (' + gameSnake.snakeComponents[1].x + ',' + gameSnake.snakeComponents[1].y + ')')
            };
        }

    };


    Game.init(3, 1000);


});

现在,我可以在 init 方法中访问 Snake 实例 (this.gameSnake),但是当代码在 update 方法上时,它变得未定义。我错过了什么/做错了什么?

4

1 回答 1

1

使用 setInterval 时,您将面临执行上下文不正确的老问题。将代码更改render为:

    render: function() {
        for (var i = 0; i < Game.gameSnake.length; i++) {
            console.log('Snake position: (' + Game.gameSnake.snakeComponents[0].x + ',' + Game.gameSnake.snakeComponents[0].y + '), ' + '(' + Game.gameSnake.snakeComponents[1].x + ',' + Game.gameSnake.snakeComponents[1].y + '), (' + Game.gameSnake.snakeComponents[1].x + ',' + Game.gameSnake.snakeComponents[1].y + ')')
        };
    }

this不起作用的原因是您没有像这样调用函数: Game.update();.

相反,您所做的是将函数作为参数传递给setInterval,它在全局范围内执行它(意味着update运行时,this是窗口对象)。由于this不再引用Game,因此我们决定Game显式引用。

有很多关于 JS 范围的好教程,你可能想看看它们。祝你好运!

于 2012-12-01T11:10:21.593 回答