在游戏关卡结束时从setInterval中逃脱

时间:2015-04-24 17:12:21

标签: javascript html5 canvas setinterval

我正在使用HTML5 canvas和Javascript编写游戏。我使用setInterval为游戏制作动画并定期检查事件。我已经为游戏编写了多个级别,但是当给定级别结束以便启动下一个级别时,我似乎无法逃脱setInterval。代码可以准确地检测某个级别何时获胜或丢失,并成功清除间隔并呈现按钮,但该按钮不会触发。

添加按钮是我最新的想法。我还尝试使用jQuery删除画布并插入一个新画布。我也尝试在画布上使用clearRect,但它也没有。或者

鉴于我无法从setInterval返回值,我有哪些选择?还有另一种方法可以完成同样的事情吗?我的代码是否有单独的错误,我忽略了?谢谢!

Game.prototype.win = function(int) {
    clearInterval(int);
    var content = "<p style='color:white;'>You win</p><br><button id='next-level'>Next Level</button></menu>"
    $('#controls').append(content)
};

Game.prototype.lose = function(int) {
    clearInterval(int);
    var content = "<p style='color:white;'>You Lose</p><br><button id='next-level'>Start Over?</button></menu>"
    $('#controls').append(content)
};

Game.prototype.run = funtion () {    
    $('#start').click( function () {
      $('#controls').empty();
      var waveOne = new window.CrystalQuest.Wave(this.X_DIM, this.Y_DIM, this, Game.WAVE_ONE)
      var game = this

      var int = setInterval( function () {
        if (waveOne.step() === "lost" ) {
          game.lose(int);
        } else if (waveOne.step() === "won") {
          game.win(int);
        }
        waveOne.draw(this.ctx)
      }, 20)
      this.bindKeyHandlers(waveOne);
   }.bind(this));

   $('#next-level').click( function () {
      $('#controls').empty();
      ...more code...
   });
};

1 个答案:

答案 0 :(得分:1)

要停止setInterval(),您必须将原始调用中返回的值存储到某个持久位置的setInterval(),然后针对该值调用clearInterval()

因为您在var中声明了var int的时间间隔,所以它仅在该方法中是本地的,并且在代码中的任何其他地方都无法使用。

在您的代码中有很多方法可以做到这一点。我可能建议将它存储为像这样的实例变量:

Game.prototype.run = funtion () {    
    $('#start').click( function () {
      $('#controls').empty();
      var waveOne = new window.CrystalQuest.Wave(this.X_DIM, this.Y_DIM, this, Game.WAVE_ONE)
      var game = this;

      this.stop();
      this.interval = setInterval( function () {
        if (waveOne.step() === "lost" ) {
          game.lose(int);
        } else if (waveOne.step() === "won") {
          game.win(int);
        }
        waveOne.draw(this.ctx)
      }, 20)
      this.bindKeyHandlers(waveOne);
   }.bind(this));

   $('#next-level').click( function () {
      $('#controls').empty();
      ...more code...
   });
};

然后,你可以创建一个方法来停止这样的间隔:

Game.prototype.stop = function() {
      if (this.interval) {
          clearInterval(this.interval);
          this.interval = null;
      }
}

并且,改变你的其他方法:

Game.prototype.win = function(int) {
    this.stop();
    var content = "<p style='color:white;'>You win</p><br><button id='next-level'>Next Level</button></menu>"
    $('#controls').append(content)
};

Game.prototype.lose = function(int) {
    this.stop();
    var content = "<p style='color:white;'>You Lose</p><br><button id='next-level'>Start Over?</button></menu>"
    $('#controls').append(content)
};

对于您的事件处理问题,如果您正在销毁并重新创建按钮,那么您将丢失附加到已替换的任何DOM元素的任何事件处理程序。

如何修复它有两种选择:

  1. 创建新DOM元素后,您可以再次在新DOM元素上设置事件处理程序。
  2. 您可以使用&#34;委派事件处理&#34;。这会将事件处理程序附加到本身未替换的父DOM对象。 click事件冒泡到父级并在那里处理。孩子可以根据需要多次更换,事件处理程序仍然有效。
  3. 有关如何使用jQuery委托事件处理的信息,请参阅这些参考资料:

    Does jQuery.on() work for elements that are added after the event handler is created?

    jQuery .live() vs .on() method for adding a click event after loading dynamic html

    JQuery Event Handlers - What's the "Best" method