Javascript 处理“onkeydown”事件

Javascript 处理“onkeydown”事件,javascript,events,audio,event-handling,onkeydown,Javascript,Events,Audio,Event Handling,Onkeydown,我在文档中添加了onkeydown事件监听器,当事件触发时,我播放一个音频文件。这个音频文件是枪声。如果你轻按一次键,它会播放得很好,但如果你按住,音频会以难以置信的速度重复。我通过简单的比赛条件检查解决了这个问题,但我还有另一个问题。如果我按住,只有在第一枪之后,听起来像是枪在重复开火。例如,它就像塔塔塔 我怎样才能修理我的机枪?让它像塔塔塔一样燃烧 akinuri,这是我的第一个答案,但我删除了它我以为你想播放整个声音,所以我取消了删除它,它可以帮助你修复按键关闭的延迟错误 您应该在游戏开发

我在文档中添加了onkeydown事件监听器,当事件触发时,我播放一个音频文件。这个音频文件是枪声。如果你轻按一次键,它会播放得很好,但如果你按住,音频会以难以置信的速度重复。我通过简单的比赛条件检查解决了这个问题,但我还有另一个问题。如果我按住,只有在第一枪之后,听起来像是枪在重复开火。例如,它就像塔塔塔

我怎样才能修理我的机枪?让它像塔塔塔一样燃烧


akinuri,这是我的第一个答案,但我删除了它我以为你想播放整个声音,所以我取消了删除它,它可以帮助你修复按键关闭的延迟错误

您应该在游戏开发中使用gameLoop通用模式,并使用requestAnimationFrame。 不要直接从玩家的输入触发事件,设置将在gameLoop内处理的状态,该状态应负责更新位置、渲染

var playing = false;

var keyStatePressed = false;//set state at false at init

var weapons = {
    aug : {
        audio   : "weapons/aug-1.wav",
        icon    : "e",
        key     : "A"
    }
};

function playAudio(file) {
    if (!playing) {
        var audio = new Audio(file);
        audio.play();
        playing = true;
        setTimeout(function() {
            playing = false;
        }, 100);
    }
}

//flag at true on keydown
document.onkeydown = function(e) {
    switch(e.keyCode) {
        case 65:
            keyStatePressed = true;
            break;
    }
}

//run a game loop
function gameLoop(){
    if(keyStatePressed === true){
        playAudio(weapons.aug.audio);
        keyStatePressed = false;//reset state
    }
    //run this in 16ms (see more on game loops and requestAnimationFrame)
    requestAnimationFrame(gameLoop);
}

//launch the gameLoop
gameLoop();

也许有一种更好的方法可以使用gameLoop和更少的全局播放,但请等待音频对象的结束事件标记为playing at false,并确保在完成之前不要开始播放声音

var playing = false;//tag playing as false by default

var weapons = {
    aug : {
        audio   : "weapons/aug-1.wav",
        icon    : "e",
        key     : "A"
    }
};

function playAudio(file) {
    if (!playing) {
        audio = new Audio(file);
        playing = true;
        setTimeout(function(){
            playing = false;
        },400);
        audio.play();
    }
}

document.onkeydown = function(e) {
    switch(e.keyCode) {
        case 65:
            playAudio(weapons.aug.audio);
            break;
    }
}

嘿,让我知道它是否有效我希望它有帮助

var weapons = {
    aug : {
        audio   : "weapons/aug-1.wav",
        icon    : "e",
        key     : "A"
    }
};
function loadAudio(file) {
    var audio = new Audio(file);
    return audio;
}

function playAudio(file) {
        audio.play();
}

document.onkeydown = function(e) {
    switch(e.keyCode) {
        case 65:
            var gunsound = loadAudio(weapons.aug.audio);
            playAudio(gunsound);
            setTimeout(function() {},200);
            break;
    }
}

我在考虑之前就开始编写代码,这是我的第一个错误。我现在已经解决了这个问题。我所要做的就是简单地模仿FPS游戏的射击命令。用mousedown开始一个间隔,用mouseup清除间隔

我不得不用按键代替鼠标点击。因此,当我按下一个键并按住时,一个间隔开始并重复播放音频。当我松开钥匙时,间隔被清除,音频停止


在playAudio函数中,有一个未定义的变量audio。您添加的已结束事件侦听器。我在每次播放时都会创建音频对象,因为它需要听起来像枪声。如果我在上一个播放结束时播放该声音,听起来会不对。拍摄之间会有停顿。音频文件的长度为1秒,但实际拍摄的声音要短得多,大约为400ms。因此,我需要在上一个播放结束之前中断并再次启动。我的坏-在复制/粘贴音频成为audios[文件]后,忘记更新方法的结尾。您可以在中看到我在说什么,快照之间的暂停。我需要在每次播放时创建音频对象。更改代码以防您不想等到整个文件结束后再播放上一个版本。不起作用。将超时设置为400ms不起作用,因为音频对象仍然引用同一对象。当同一音频已经播放时,您不能再次播放该音频。在这里,粗野的演奏没有帮助。这就是为什么我每次都要重新创作。不,这个代码不能解决问题。它只是带我回到我开始的地方。在两次拍摄之间,音频播放没有任何延迟。
var weapons = {
    aug : {
        audio   : "weapons/aug-1.wav",
        icon    : "e",
        key     : "A"
    }
};
function loadAudio(file) {
    var audio = new Audio(file);
    return audio;
}

function playAudio(file) {
        audio.play();
}

document.onkeydown = function(e) {
    switch(e.keyCode) {
        case 65:
            var gunsound = loadAudio(weapons.aug.audio);
            playAudio(gunsound);
            setTimeout(function() {},200);
            break;
    }
}
var weapons = {
    aug : {
        audio       : "weapons/aug-1.wav",
        icon        : "e",
        key         : "A",
        interval    : null,
        firstShot   : false,
    }
};

function playAudio(file, weapon) {
    if (!weapon.interval) {
        if (!weapon.firstShot) {
            var audio = new Audio(file);
            audio.play();
            weapons.aug.firstShot = true;
        }
        weapon.interval = setInterval(function() {
            var audio = new Audio(file);
            audio.play();
        }, 150);
    }
}

document.onkeydown = function(e) {
    switch (e.keyCode) {
        case 65:
            playAudio(weapons.aug.audio, weapons.aug);
            break;
    }
}
document.onkeyup = function(e) {
    switch (e.keyCode) {
        case 65:
            clearInterval(weapons.aug.interval);
            weapons.aug.interval = null;
            weapons.aug.firstShot = false;
            break;
    }
}