2012-12-01 137 views
0

我试图在js/jquery中实现一个基本的蛇游戏。这里是我到目前为止有:在javascript中的蛇 - 无法访问方法中的属性?

$('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方法访问蛇实例(this.gameSnake),但是当代码是关于更新方法就变得不确定。我错过了什么/做错了什么?

+1

对不起,这..新的在这里,我的代码实际上正确地缩进文本编辑器即时通讯使用(notepad ++),但我似乎无法“完全复制并粘贴”我的源代码在粘贴堆栈溢出文章 –

回答

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是window对象)。由于this不再涉及Game,我们决定明确引用Game

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

+0

+1,根据你的解决方案,我认为还需要在'update:'函数中将'this'全部替换为'Game',这样小提琴才能工作。 – Nelson

+0

@Nelson最初的问题是'setInterval'中的'render'方法,因为他已经将它更改为'update',所以在那种情况下'update'就是你需要避免使用'this'的那个。 –

+0

谢谢..我认为它解决了这个问题,但是你能否提供Game.gameSnake工作的原因,而这个.gameSnake不是。基于我对JavaScript的理解(虽然我是一个新手),但后者应该工作。 –