在JS中减慢.push()间隔

时间:2012-09-16 09:27:08

标签: javascript arrays instance

player.fire是一个布尔值,如果空格键位于keydown,则会变为 true 。一切都按预期工作。

我遇到的问题是控制数组asteroids.firing.push间隔。现在,它添加了少数实例,即使我在空格键上轻触 也是如此。我正在使用requestAnimationFrame

如何控制push间隔?

    if(player.fire){
        var angle = thisShip.rot, 
        hyp = 10; //speed

        var vX = Math.cos(angle) * hyp, 
        vY = Math.sin(angle) * hyp;

        asteroids.firing.push(new asteroids.model.fire(thisShip.x, thisShip.y, vX, vY));
    }

我尝试过类似的东西,但它不会减慢push间隔,而只会产生脉冲效果,一次又一次地重新生成点火序列。

    ...
    if(player.fire){
            fireInterval(thisShip);
    }

    function fireInterval(thisShip){
        var angle = thisShip.rot, 
            hyp = 10; //speed

        var vX = Math.cos(angle) * hyp, 
        vY = Math.sin(angle) * hyp;

        asteroids.firing.push(new asteroids.model.fire(thisShip.x, thisShip.y, vX, vY));

        setTimeout(function(){
            fireInterval(thisShip);
        }, 500);
    } 

3 个答案:

答案 0 :(得分:5)

发生的事情是你每次更新都会调用此函数。 我不知道您的引擎是什么样的,但是如果您使用requestAnimationFrame则可能高达60fps,如果您只是尽快循环,则可能更高,并且更新与绘图无关

你需要做的是在船上放置某种状态。 它是什么并不重要......

thisShip.cooldownTime = 250; //ms
thisShip.lastFired =    oldTimestamp;

if (currentTime - thisShip.lastFired >= thisShip.cooldownTime) {
    thisShip.fire(); // push the model, set lastFired to current time, etc...
}

另外,就其他人的建议而言:

我不确定你是如何实现听键盘事件的... ... 但是在JS中处理键时,我最倾向于做的是让键盘触发尽可能多的keydownkeyup事件。 不使用缓冲,而是使用 事件,键事件函数会告诉Keyboard对象一个键是否关闭,或者它是否已关闭。

在更新期间轮询Keyboard个对象。

document.addEventListener("keydown", function (e) {
    var key = e.keyCode;
    if (!!Keyboard[key]) { return; } 
    Keyboard[key] = e.timeStamp;
});


document.addEventListener("keyup", function (e) {
    var key = e.keyCode;
    delete Keyboard[key];
});

轮询以查看密钥是否已关闭。 通过将键的值设置为e.timeStamp,您现在可以知道它们何时开始按住它,这样您就可以控制船只发射的频率。

更好的是,您可以设置一些抽象系统,例如:

var Keymap = { SPACE : 32, A : 65, ... };
Player1.controls = { FIRE : "SPACE" };

var code = Keymap[Player1.controls.FIRE],
    pressedSince = Keyboard[code]; // timestamp || undefined

现在你有一些东西可以与你的冷却时间和大门进行比较。 它们点击的速度无关紧要,或者如果键盘默认通过涡轮增压工作,你应该拥有防止涡轮火力所需的所有数据点,允许按住自动点火(门控250毫秒,如果你发现钥匙一直被敲击,你可以选择只有3个子弹在屏幕上,或其他任何东西上,然后选通一个较小的值,让按钮瞄准器略微超过按钮架。

答案 1 :(得分:1)

我假设你的游戏循环中有if(player.fire){...}部分代码?如果是这样,那么它经常被触发的原因。对此最常见的解决方案是在一次火灾事件发生后,在用户再次开火之前进行“冷静”期。 e.g:

if ( player.fireWait > 0 ) {
  player.fireWait--;
}

if( player.fire && (player.fireWait == 0) ){
  player.fireWait = 20;
  fire( thisShip );
}

上述问题之一是,如果用户反复点击开火按钮,则无法再次开火(直到.fireWait计数器再次击中0)。这就是为什么你的onkeydown是你需要这样做的原因:

player.fireWait = 0;

然而,另一张海报已正确声明您需要使用键盘缓冲区,以便您的消防机制能够像大多数游戏一样工作。如果没有缓冲区,如果用户按下空间,你将得到一个单一的镜头......然后经过一段时间你会突然得到快速射击。这是因为keydown与正常的键盘输入相关联,如果您按住某个键,您将看到发生了什么事情。

答案 2 :(得分:0)

您需要使用某种键盘缓冲区 我建议看this blog post 评论也非常有用,您可以从中找到:this site

你现在正在做的就是将火力行动延迟半秒,但所有被抓住的“keydown”仍然被发送。
我也会考虑使用“keyup”,可能会更好。