If you use setTimeout or setInterval and want the ability to cancel them, you need to save the returnvalue of this function in a variable. The return-value is a handler, that can be used in clearTimeout or clearInterval.
In this scenario setInterval would be easier if the moveMonster function has a smaller time consumption than this.speed.
this.startMove = function() {
this.startMove.intervalHandler = setInterval(function handler() {
self.moveMonster(moveMonsterCallback);
}, this.speed);
};
this.stopMove = function() { clearInterval(this.startMove.intervalHandler); }
I prefer using the function scope to save such things like Handler. If you don't like it use the parent scope or the context
If it's important to use setTimeout instead of setInterval you have solution in other answers. It's simply the same: Save the returnvalue of setTimeout und use it later with clearTimeout.
If moveMonsterCallback should be called if the animation is over, take a look at promises instead of callbacks. With callbacks you're getting fast in a position, it's hard to track the callings.
A word on animations: They're tricky! Don't use setTimeout. Better call requestAnimationFrame on the window object.
function step(timestamp) {
if (!step.startTime) step.startTime = timestamp;
var delta = step.getDelta(timestamp);
// do the calculations of how far you have to move the monster in this time range
// move the monster...
...
// animation is stopped? If not: We want to animate another timeframe
if (!step.stopped) {
window.requestAnimationFrame(step);
}
}
step.startTime = null;
step.stopped = false;
step.getDelta = (timestamp)=>timestamp-step.startTime;
function stopMove() {
step.stopped = true;
}
window.requestAnimationFrame(step);
This solution provides a better result, because it's independent of the precision of setTimeout. It works with time differences