Challenge mode functionality complete; layout updates

This commit is contained in:
Gene Mecija 2020-02-10 17:51:09 -08:00
parent dd077e6d12
commit 113e4a2348
20 changed files with 1100 additions and 272 deletions

View file

@ -1,22 +1,42 @@
import React, {useState, useContext} from "react"
import { GameClockContext } from "./gameClockContext"
import { WordFeederContext } from "./wordFeederContext"
// import { KeyTypeContext } from "./keyTypeContext"
import { KeyTypeContext } from "./keyTypeContext";
import { MorseBufferContext } from "./morseBufferContext";
import morseCode from '../data/morse-reverse.json'
const ChallengeContext = React.createContext()
function ChallengeContextProvider(props) {
console.log('ChallengeContextProvider');
const [challengeState, setChallengeState] = useState('ready')
const {startGameClock, stopGameClock, setGameClockTime, intervals} = useContext(GameClockContext)
const {resetFeeder} = useContext(WordFeederContext)
const {word, getNextWord} = useContext(WordFeederContext)
const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext)
let morseArray = morseCharBuffer.split('_').filter(l => l !== '')
let challengeWordClass = ''
let correctCharIndexes = [] // Indexes of correct letters in Challenge Word
let incorrectMorseIndexes = [] // Indexes of incorrect morse characters in morse character buffer
let offset = 0
let challengeLetters
function startChallenge() {
setGameClockTime(0)
console.log('STARTCHALLENGE');
let countdown
let count = 3
// Challenge countdown setup
document.getElementById('challengeReady').classList.add('starting')
document.getElementById('challengeReady').innerHTML = `<span id="message">Challenge starting in</span><span id="count">${count}</span>`
// Start Challenge countdown
countdown = setInterval(() => {
count--
if (count === 0) {
@ -25,7 +45,7 @@ function ChallengeContextProvider(props) {
clearInterval(countdown)
setTimeout(() => {
document.getElementById('challenge-overlay').classList.add('hide')
startGameClock()
// Start Challenge
setChallengeState('started')
}, 900);
}
@ -34,31 +54,92 @@ function ChallengeContextProvider(props) {
}
function completeChallenge() {
stopGameClock()
setChallengeState('completed')
for (let i = 0; i < intervals.length; i++) {
clearInterval(intervals[i]);
if (challengeState !== 'completed') {
setChallengeState('completed')
resetFeeder()
showOverlay()
}
resetFeeder()
const challengeOverlay = document.getElementById('challenge-overlay')
challengeOverlay.classList.remove('fade')
challengeOverlay.classList.remove('hide')
}
function cancelChallenge() {
stopGameClock()
for (let i = 0; i < intervals.length; i++) {
clearInterval(intervals[i]);
if (challengeState !== 'cancelled') {
setChallengeState('cancelled')
resetFeeder()
showOverlay()
}
setChallengeState('ready')
resetFeeder()
setGameClockTime(0)
}
function showOverlay() {
const challengeOverlay = document.getElementById('challenge-overlay')
challengeOverlay.classList.remove('fade')
challengeOverlay.classList.remove('hide')
}
// If no more words in wordlist, feeder returns first word in an array
if (typeof word === 'object') {
completeChallenge()
challengeLetters = word[0].split('')
}
else {
challengeLetters = word.split('')
}
// Iterate through the morse character buffer and compare with each letter of challenge word
morseArray.forEach((item, index) => {
if (morseCharBuffer.slice(-1) === '_') { // If end of morse character
let morseLetter = morseCode[morseArray[index]] || '[?]'
let challengeLetter = challengeLetters[index-offset].toLowerCase()
if (morseLetter === challengeLetter) {
correctCharIndexes.push(index-offset)
console.log('morseCharBuffer', morseCharBuffer);
document.getElementById('challengeWord').childNodes[index-offset].classList.add('correct')
// incorrectCharIndex = null
}
else {
// incorrectCharIndex = index-offset
incorrectMorseIndexes.push(index)
if (incorrectMorseIndexes.length > 0) {
setMorseCharBuffer(prev => {
let newState = prev.split('_').filter(l => l !== '')
newState.splice(incorrectMorseIndexes[0], 1)
newState = newState.join('_') + '_'
return newState
})
incorrectMorseIndexes.splice(1,incorrectMorseIndexes.length)
}
offset = incorrectMorseIndexes.length
}
}
})
// Next word once all correct
if (correctCharIndexes.length === challengeLetters.length) {
challengeWordClass = 'correct'
setTimeout(() => {
setMorseCharBuffer('')
morseArray = []
incorrectMorseIndexes = []
offset = 0
if (document.getElementById('challengeWord') !== null) {
document.getElementById('challengeWord').childNodes.forEach(node => {
node.classList = "cLetter"
})
}
}, 800)
setTimeout(() => {
if (correctCharIndexes.length > 0) {
correctCharIndexes = []
getNextWord()
}
}, 1000)
}
return (
<ChallengeContext.Provider value={{
@ -66,7 +147,10 @@ function ChallengeContextProvider(props) {
setChallengeState: setChallengeState,
startChallenge: startChallenge,
completeChallenge: completeChallenge,
cancelChallenge: cancelChallenge
cancelChallenge: cancelChallenge,
challengeWordClass: challengeWordClass,
morseArray: morseArray,
incorrectMorseIndexes: incorrectMorseIndexes
}}>
{props.children}
</ChallengeContext.Provider>

View file

@ -1,19 +1,20 @@
import React, {useState} from "react"
import React, {useState, useContext, useEffect} from "react"
import { ChallengeContext } from "./challengeContext"
// import { KeyTypeContext } from "./keyTypeContext"
const GameClockContext = React.createContext()
function GameClockContextProvider(props) {
const [gameClockTime, setGameClockTime] = useState(0)
const [clockIsRunning, setClockIsRunning] = useState(false)
// const [gameClockTimer, setGameClockTimer] = useState(0)
// let intervals = []
const [intervals, setIntervals] = useState([])
const {challengeState, setChallengeState} = useContext(ChallengeContext)
function startGameClock() {
console.log('before clock');
if (!clockIsRunning) {
console.log('after clock');
setClockIsRunning(true)
setIntervals(prev => [...prev, (setInterval(() => {
if (document.getElementById('gameClock') === null) {
@ -40,6 +41,27 @@ function GameClockContextProvider(props) {
clearInterval(intervals[i]);
}
}
useEffect(() => {
switch (challengeState) {
case 'ready':
setGameClockTime(0)
cleanup()
break
case 'started':
startGameClock()
break
case 'completed':
stopGameClock()
break
case 'cancelled':
stopGameClock()
setChallengeState('ready')
break
default:
return
}
}, [challengeState])
return (

View file

@ -3,6 +3,7 @@ import React, {useState} from "react"
const KeyTypeContext = React.createContext()
function KeyTypeContextProvider(props) {
console.log('KeyTypeContextProvider');
const [keyType, setKeyType] = useState('straight')

View file

@ -3,6 +3,7 @@ import { WordListPickerContext } from "./wordListPickerContext"
const WordFeederContext = React.createContext()
function WordFeederContextProvider(props) {
// let wordList = ['hi', 'morse', 'code', 'hello', 'gene']
const {wordList, wordListShuffled} = useContext(WordListPickerContext)