I have created a flip tile memory game. A sequence of tiles will flip over displaying a colour. The user must remember the sequence and repeat it. When the user selects correctly a correct Mp 3 is played. On the Iphone if the tiles are selected quickly the audio isn't being played for each touch, its as though the audio is being skipped for some. link
const elements = {
gameContainer: $('#game-container'),
gameMenu: $('#game-menu'),
audioPlayer: document.querySelector('#player'),
audioPlayer2: document.querySelector('#player2'),
audioPlayer3: document.querySelector('#player3'),
tiles: $('.tile'),
correctAlert: $('#correct-alert'),
wrongAlert: $('#wrong-alert'),
failAlert: $('#fail-alert'),
alertModal: $('#alert-modal'),
stageNumber: $('.stage-number'),
maxStageNumber: $('.max-stage-number'),
gamemodeCheckbox: $('#gamemode-checkbox'),
stageProgress: $('#stage-progress'),
waitText: $('#wait-text'),
wonAlert: $('#won'),
goText: $('#go-text')
};
function tileClicked(tile) {
console.dir(tile)
// only allow clicking on tiles when game is started and game is not showing pattern
if (!game.showing && game.started && !tile.classList.contains('flip-card-onclick')) {
flipTile(tile);
// check if game reached maximum number of stages i.e. game has been won
if (game.playerMove <= game.maxStageNumber) {
// check if current move (tile clicked) matches the tile in the generated pattern
if (parseInt(tile.id) == game.currentGame[game.playerMove]) {
// increase the pattern pointer
game.playerMove++;
// play sound when correct tile has been clicked
elements.audioPlayer.pause();
elements.audioPlayer.currentTime = 0;
elements.audioPlayer.play();
// check if we reached the end of the current pattern
if (game.playerMove == game.currentGame.length) {
// update the progress bar
elements.stageProgress.css('width', `${(game.currentGame.length / game.maxStageNumber) * 100}%`);
// show alert prompting user to go to the next stage
elements.correctAlert.modal('show');
}
// current move did not match current pattern, wrong move
} else {
if (game.strictGamemode) {
elements.audioPlayer2.play();
// show fail alert and prompt to restart or exit game if strict mode has been selected
elements.failAlert.modal('show');
} else {
// show wrong move alert and prompt to show pattern again
elements.audioPlayer2.play();
elements.wrongAlert.modal('show');
}
}
}
}
}
<!--Audio Player-->
<audio controls id="player" class="d-none">
<source id="player-src" src="assets/audio/correct.mp3">
</audio>
<audio controls id="player2" class="d-none">
<source id="player-src-2" src="assets/audio/incorrect.mp3">
</audio>
<audio controls id="player3" class="d-none">
<source id ="player-src-3" src="assets/audio/won.mp3">
</audio>
It is very hard to tell where your bug comes from, so your solution may not be so easy to find. Some research might tell you some things but otherwise there is an alternative you could try.
The Web Audio API is an interface where you can get more control over the audio you play. So in your case instead of manipulating the
<audio>element, use the Web Audio API to play your audio files.Down here I've created a snippet which utilizes this API. It currently selects all of your
<audio>elements and extracts the sound into a node which then can use to play the sound. This gives you control over how the sound plays.So here it creates an object, which is stored in the
soundsconstant, that holds all the names as keys and the players as values. Something like this:Each of those
MediaElementAudioSourceNodeare the sounds which can be played. Later in the script there is aplaySoundfunction, which plays one of the sounds found in yoursoundsobject.So all of this could be added above your original script so that the sound files are loaded and ready for use. And then use the
playSound()function anywhere in your script whenever you want to play anyone of the sounds. Example below:Also, add a
data-nameattribute to each<audio>element so that JavaScript knows how to call each player and it's accompanying sound.All my code above is untested and might throw an error, or worse, makes no difference at all. But hey, at least it's worth a shot.