处理'onkeydown'事件

时间:2015-01-01 23:33:21

标签: javascript events audio event-handling onkeydown

我已将onkeydown事件监听器添加到document,当事件触发时,我播放音频文件。这个音频文件是枪声。如果您点击一次键,它会正常播放,但如果您按住,音频会以极快的速度重复播放。我通过简单的playing条件检查解决了这个问题,但我还有另外一个问题。如果我按下并按住,只有在第一次拍摄之后,听起来就像枪在反复射击。例如,它就像 ta-tatatatata

如何修理机枪?像 tatatata 一样点火。

Demo


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);
    }
}

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

4 个答案:

答案 0 :(得分:0)

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

您应该使用requestAnimationFrame使用gameLoop(游戏开发中的常见模式)。 不要直接从玩家的输入触发事件,设置将在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();

答案 1 :(得分:0)

对于gameLoop和更少的全局变量,应该有更好的方法,但等待音频对象的ended事件在playing标记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;
    }
}

答案 2 :(得分:0)

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

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;
    }
}

答案 3 :(得分:0)

在考虑之前我开始编码,这是我的第一个错误。我现在已经解决了这个问题。我所要做的只是模仿FPS游戏的火力指挥。使用mousedown开始一个时间间隔,并使用mouseup清除时间间隔。

我不得不使用鼠标点击,而是使用按键。因此,当我按下一个键(并保持)时,一个间隔开始并重复播放音频。当我释放键时,间隔被清除,音频停止。

Demo

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;
    }
}