Search code examples
javascripteventsaudioevent-handlingonkeydown

Handling 'onkeydown' event


I've added onkeydown event listener to document, and when the event fires, I play an audio file. This audio file is a gun sound. If you tap the key once, it plays fine, but if you press and hold, the audio repeats incredibly fast. I've solved that with a simple playing condition check, but I have another problem. If I press and hold, only after the first shot, it sounds like the gun is firing repeatedly. For example, it goes like ta-tatatatata.

How can I fix my machine gun? Make it fire like 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;
    }
}

Solution

  • I started to code this before thinking about it, and that was my first mistake. I've solved the problem now. All I had to do was simply mimic the FPS games' fire command. Start an interval with the mousedown and clear the interval with mouseup.

    Instead of using mouse click, I had to use key press. So when I press a key (and hold), an interval starts and plays the audio repeatedly. When I release the key, interval is cleared, audio stops.

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