在JS中减慢.push()间隔

1 javascript arrays instance

player.fire是一个布尔值,如果空格键在,则返回true.一切都按预期工作. keydown

我遇到的问题是控制阵列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));
    }
Run Code Online (Sandbox Code Playgroud)

我尝试过类似的东西,但它不会减慢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);
    } 
Run Code Online (Sandbox Code Playgroud)

Nor*_*ard 5

发生的事情是你每次更新都会调用此函数.我不知道你的引擎是什么样的,但是如果你正在使用它可能高达60fps requestAnimationFrame,或者如果你只是尽可能快地循环,那么更新,并且更新不依赖于绘图.

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

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

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

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

我不确定你是如何实现对键盘事件的监听......
但是在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];
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

var code = Keymap[Player1.controls.FIRE],
    pressedSince = Keyboard[code]; // timestamp || undefined
Run Code Online (Sandbox Code Playgroud)

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