在游戏关卡结束时退出 setInterval
escape from setInterval at end of game level
我正在使用 HTML5 canvas 和 Javascript 编写游戏。我正在使用 setInterval 来设置游戏动画并定期检查事件。我已经为游戏编写了多个级别,但是当给定级别结束以开始下一个级别时,我似乎无法逃避 setInterval 。代码准确地检测到一个级别何时获胜或失败,并成功清除间隔并呈现按钮,但按钮没有触发。
添加按钮是我的最新想法。我还尝试使用 jQuery 删除 canvas 并插入一个新的。我也试过在 canvas 上使用 clearRect,但它也没有触发。
鉴于我无法 return 来自 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...
});
};
要停止 setInterval()
,您必须将对 setInterval()
的原始调用的返回值存储在某个持久位置,然后对该值调用 clearInterval()
。
因为您在 var int
中使用 var
声明了间隔,所以它仅适用于该方法,在代码的其他任何地方都不可用。
在您的代码中有多种方法可以做到这一点。我可能会建议将其存储为这样的实例变量:
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 元素的任何事件处理程序。
您有两种修复方式可供选择:
- 创建新的 DOM 元素后,您可以再次在新的 DOM 元素上设置事件处理程序。
- 您可以使用 "delegated event handling"。这会将事件处理程序附加到本身未被替换的父 DOM 对象。单击事件冒泡到父级并在那里处理。可以根据需要多次替换子项,事件处理程序仍然有效。
请参阅这些参考资料,了解如何通过 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
我正在使用 HTML5 canvas 和 Javascript 编写游戏。我正在使用 setInterval 来设置游戏动画并定期检查事件。我已经为游戏编写了多个级别,但是当给定级别结束以开始下一个级别时,我似乎无法逃避 setInterval 。代码准确地检测到一个级别何时获胜或失败,并成功清除间隔并呈现按钮,但按钮没有触发。
添加按钮是我的最新想法。我还尝试使用 jQuery 删除 canvas 并插入一个新的。我也试过在 canvas 上使用 clearRect,但它也没有触发。
鉴于我无法 return 来自 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...
});
};
要停止 setInterval()
,您必须将对 setInterval()
的原始调用的返回值存储在某个持久位置,然后对该值调用 clearInterval()
。
因为您在 var int
中使用 var
声明了间隔,所以它仅适用于该方法,在代码的其他任何地方都不可用。
在您的代码中有多种方法可以做到这一点。我可能会建议将其存储为这样的实例变量:
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 元素的任何事件处理程序。
您有两种修复方式可供选择:
- 创建新的 DOM 元素后,您可以再次在新的 DOM 元素上设置事件处理程序。
- 您可以使用 "delegated event handling"。这会将事件处理程序附加到本身未被替换的父 DOM 对象。单击事件冒泡到父级并在那里处理。可以根据需要多次替换子项,事件处理程序仍然有效。
请参阅这些参考资料,了解如何通过 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