From c83e12b6f2de41168de22ff33779be9f2e16ea74 Mon Sep 17 00:00:00 2001 From: Florrie Date: Thu, 17 Jan 2019 22:43:02 -0400 Subject: Time trial, weee --- main.js | 224 ++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 147 insertions(+), 77 deletions(-) (limited to 'main.js') diff --git a/main.js b/main.js index 97fc007..2129149 100644 --- a/main.js +++ b/main.js @@ -269,6 +269,7 @@ function waitForEvent(el, eventName) { function setupScorekeeper(numCharacters) { const container = document.getElementById('scorekeeper'); + container.innerHTML = ''; for (let i = 0; i < numCharacters; i++) { const el = document.createElement('div') el.classList.add('marker'); @@ -290,6 +291,8 @@ function markScorekeeper(cls, character) { async function mainLol() { const testChar = 'Noellef'; + // one-time initialization .............................................uuh + document.body.addEventListener('keydown', evt => { const choiceContainer = document.getElementById('choice-container'); if (!choiceContainer.classList.contains('hide')) { @@ -322,10 +325,6 @@ async function mainLol() { } }); - // pre-game ------------------------------------------------------------... - - let mode; - const modeLinks = document.querySelectorAll('#mode-picker a[data-mode]'); const modeParas = document.querySelectorAll('#mode-descriptions p[data-mode]'); @@ -344,110 +343,181 @@ async function mainLol() { el.addEventListener('click', evt => pickMode(evt.target)); } + let mode; + pickMode(modeLinks[0]); modeLinks[0].focus(); - // you can pick game options before resources are loaded await loadResources(); document.body.classList.add('resources-loaded'); - const gameEl = document.getElementById('game'); + // pre-game ------------------------------------------------------------... - const playLink = document.getElementById('play-link'); - await waitForEvent(playLink, 'click'); + while (true) { + const gameEl = document.getElementById('game'); - document.body.classList.add('game'); + const playLink = document.getElementById('play-link'); + await waitForEvent(playLink, 'click'); - const deckGames = ['deltarune']; - const hardMode = false; + document.body.classList.add('game'); + document.body.classList.add('mode-' + mode); - const characterDeck = gameData.characters.filter(chr => chr.games.some(g => deckGames.includes(g))); + const deckGames = ['deltarune']; + const hardMode = false; - // game loop -----------------------------------------------------------nym + const characterDeck = gameData.characters.filter(chr => chr.games.some(g => deckGames.includes(g))); - setupScorekeeper(characterDeck.length); + // time trial display ----------------------------------------------TT! - while (characterDeck.length) { - gameEl.classList.remove('correct'); - gameEl.classList.remove('incorrect'); + const startTime = Date.now(); + const timeTrialDuration = 30; + let timeTrialOver = false; - const correctCharacter = characterWithName(testChar) || spliceRandom(characterDeck); + let resolveTimeTrial; + const timeTrialPromise = new Promise(res => { + resolveTimeTrial = res; + }); - const numChoices = 6; - const potentialOptions = characterDeck.slice().filter(chr => chr !== correctCharacter); - const correctIndex = Math.min(Math.floor(Math.random() * numChoices), potentialOptions.length); - const allCharacters = []; - for (let i = 0; i < numChoices; i++) { - if (i === correctIndex) { - allCharacters.push(correctCharacter); - } else if (potentialOptions.length) { - let choice; - allCharacters.push(spliceRandom(potentialOptions)); - } else { - break + const updateTimeTrialDisplay = () => { + const remaining = Math.max(0, startTime + 1000 * timeTrialDuration - Date.now()); + const str = (Math.floor(remaining / 10) / 100).toString(); + const int = str.split('.')[0]; + const frac = str.split('.')[1] || ''; + document.getElementById('time-trial-time').innerHTML = `${int}.${frac.padEnd(2, '0')}s`; + + if (remaining === 0) { + resolveTimeTrial(); + timeTrialOver = true; } - } - let msg; - if (hardMode) { - msg = pickRandom(['Oh?', 'Hello!']); - } else { - msg = pickRandom(correctCharacter.messages); - } + requestAnimationFrame(updateTimeTrialDisplay); + }; if (mode === 'time-trial') { - doSpeech(correctCharacter, msg); - await delay(100); - } else { - await doSpeech(correctCharacter, msg); - await delay(500); + updateTimeTrialDisplay(); } - const choice = await displayChoices(allCharacters, mode === 'time-trial'); + // game loop -----------------------------------------------------------nym + + let numCorrect = 0; + let numIncorrect = 0; + + setupScorekeeper(characterDeck.length); + + while (characterDeck.length) { + gameEl.classList.remove('correct'); + gameEl.classList.remove('incorrect'); + + // heck sorry I don't know how to code I know this is bad + const status = await Promise.race([timeTrialPromise, (async () => { + const correctCharacter = characterWithName(testChar) || spliceRandom(characterDeck); + + const numChoices = 6; + const potentialOptions = characterDeck.slice().filter(chr => chr !== correctCharacter); + const correctIndex = Math.min(Math.floor(Math.random() * numChoices), potentialOptions.length); + const allCharacters = []; + for (let i = 0; i < numChoices; i++) { + if (i === correctIndex) { + allCharacters.push(correctCharacter); + } else if (potentialOptions.length) { + let choice; + allCharacters.push(spliceRandom(potentialOptions)); + } else { + break + } + } - const container = document.getElementById('choice-container'); - for (let i = 0; i < allCharacters.length; i++) { - const el = container.children[i]; - if (i === correctIndex) { - el.classList.add('correct'); - } else { - el.classList.add('incorrect'); - } - if (i === allCharacters.indexOf(choice)) { - el.classList.add('chosen'); - } else { - el.classList.add('not-chosen'); - } - } + let msg; + if (hardMode) { + msg = pickRandom(['Oh?', 'Hello!']); + } else { + msg = pickRandom(correctCharacter.messages); + } - if (choice === correctCharacter) { - markScorekeeper('correct', correctCharacter); - } else { - markScorekeeper('incorrect', correctCharacter); - } + if (mode === 'time-trial') { + doSpeech(correctCharacter, msg.slice(0, 10)); + await delay(100); + } else { + await doSpeech(correctCharacter, msg); + await delay(500); + } - await delay(200); + const choice = await displayChoices(allCharacters, mode === 'time-trial'); + + if (timeTrialOver) return; + + const container = document.getElementById('choice-container'); + for (let i = 0; i < allCharacters.length; i++) { + const el = container.children[i]; + if (i === correctIndex) { + el.classList.add('correct'); + } else { + el.classList.add('incorrect'); + } + if (i === allCharacters.indexOf(choice)) { + el.classList.add('chosen'); + } else { + el.classList.add('not-chosen'); + } + } - if (choice === correctCharacter) { - gameEl.classList.add('correct'); - } else { - gameEl.classList.add('incorrect'); - const el = document.getElementById('correct-character'); - el.innerHTML = ''; - el.appendChild(document.createTextNode(correctCharacter.name)); + if (choice === correctCharacter) { + markScorekeeper('correct', correctCharacter); + numCorrect++; + } else { + markScorekeeper('incorrect', correctCharacter); + numIncorrect++; + } + + await delay(200); + + if (choice === correctCharacter) { + gameEl.classList.add('correct'); + } else { + gameEl.classList.add('incorrect'); + const el = document.getElementById('correct-character'); + el.innerHTML = ''; + el.appendChild(document.createTextNode(correctCharacter.name)); + } + + if (timeTrialOver) return; + + document.getElementById('results').classList.remove('hide'); + + const nextLink = document.getElementById('next-link'); + nextLink.focus(); + await waitForEvent(nextLink, 'click'); + })()]); + + document.getElementById('choice-container').classList.add('hide'); + document.getElementById('results').classList.add('hide'); + + await delay(400); + + if (timeTrialOver) { + break; + } } - document.getElementById('results').classList.remove('hide'); + // results screen ------------------------------------------------------gg- - const nextLink = document.getElementById('next-link'); - nextLink.focus(); - await waitForEvent(nextLink, 'click'); + document.body.classList.add('game-over'); + document.getElementById('final-correct').innerHTML = numCorrect; + document.getElementById('final-incorrect').innerHTML = numIncorrect; - document.getElementById('choice-container').classList.add('hide'); - document.getElementById('results').classList.add('hide'); + const playAgain = document.getElementById('play-again-link'); + playAgain.focus(); + await waitForEvent(playAgain, 'click'); - await delay(400); + document.getElementById('choice-container').innerHTML = ''; + document.getElementById('scorekeeper').innerHTML = ''; + document.body.classList.remove('game-over'); + await delay(1000); + document.body.classList.remove('game'); + for (const el of modeLinks) { + document.body.classList.remove('mode-' + el.dataset.mode); + } } } -- cgit 1.3.0-6-gf8a5