【问题标题】:How to change the speed of setInterval in real time如何实时改变setInterval的速度
【发布时间】:2015-02-02 22:21:25
【问题描述】:

我想知道如何实时改变 setInterval 的速度例如:

if (score < 10)
    repeater = setInterval(function() {
        spawnEnemy();
    }, 1000);
if (score => 10)
    repeater = setInterval(function() {
        spawnEnemy();
    }, 500);

我知道这种方法行不通,但是有没有其他方法可以实现?

【问题讨论】:

  • clearInterval 并重新设置。
  • “其他方式”是什么意思?应该有什么区别?除了这个问题:不,如果不使用 JavaScript 的标准区间功能创建新区间,则绝对没有办法改变现有区间的速度。

标签: javascript


【解决方案1】:

您可以使用游戏循环并跟踪敌人类中的生成状态:

// press f12 so see console
function Enemy() {
    this.spawned = false;
    this.spawnOn = 20;

    this.tick = function () {
        this.spawnOn = this.spawnOn - 1;
        if (this.spawnOn == 0) {
            this.spawned = true;
        }
    }

    this.goBackToYourCage = function () {
        this.spawnOn = Math.floor(Math.random() * 50) + 1;
        this.spawned = false;
    }
}

var enemy = new Enemy();

window.setInterval(function () {

    enemy.tick();
    if (enemy.spawned) {
        console.log('spawned');
        enemy.goBackToYourCage();
        console.log('Next spawin in :' + enemy.spawnOn);
    }
}, 100);

http://jsfiddle.net/martijn/qxt2fe8y/2/

【讨论】:

  • 这是我最喜欢的一个!无需更改实际滴答速度,因此它将游戏计时器与敌人的行为分开。 OOP 就是 OP :)
【解决方案2】:

jsFiddle Demo

一旦运行,就无法更改间隔速度本身。唯一的方法是为速度设置一个变量,然后清除间隔并以新速度开始一个新的间隔。

var speed = 500;
var changeSpeed = speed;
repeater = setInterval(repeaterFn, speed);
function repeaterFn(){
    spawnEnemy();
    if( changeSpeed != speed ){
     clearInterval(repeater);
     speed = changeSpeed;
     repeater = setInterval(repeaterFn, speed);
    }
}
function changeRepeater(){
 changeSpeed = 700;
}

【讨论】:

  • 这看起来是个不错的建议,比我的要好。但我会创建一个函数,它重新创建间隔而不是设置变量..也许。
  • @Matmarbon - 必须在此处使用变量或标志或选择的机制来指示间隔需要更改,但在当前间隔结束时。否则间隔会短路,看起来不连贯。
  • 好点。除了您可以... 理论上 ...在每次调用repeaterFn时记录当前时间((new Date()).getTime()),然后...哇直到最后都不会这么想。它要么会造成巨大的混乱,要么会成为数英里的源代码。算了吧。
【解决方案3】:

另一种方法是只使用 setTimeout 而不是 setInterval。每次都进行检查,这样您就可以将速度逻辑保存在单独的函数中。

var game_over = false;
var score = 0;
function getSpeedFromScore(score)
{
    if (score > 20) {
        game_over = true;
    }

    if (score < 10) {
        return 1000;
    } else {
        return 500;
    }
}

function spawnEnemyThenWait() {
    if (!game_over) {
        spawnEnemy();

        var speed = getSpeedFromScore(score);
        setTimeout(spawnEnemyThenWait, speed);
    }
}

JS 小提琴http://jsfiddle.net/bq926xz6/

【讨论】:

  • 一个不错的实现!谢谢。
【解决方案4】:

你可以使用clearInterval:

if (score < 10) {
  clearInterval(repeater);
  repeater = setInterval(spawnEnemy, 1000);
}
if (score => 10) {
  clearInterval(repeater);
  repeater = setInterval(spawnEnemy, 500);
}

但这取决于上下文。如果这个 sn-p 执行得比它必须更频繁,你将需要某种机制来防止它一直重置你的时间间隔。

但是(正如我在对问题的评论中所写)无法使用 clearInterval更改 间隔本身。至少在没有用上面所示的新间隔替换它的情况下是这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    相关资源
    最近更新 更多