1 changed files with 162 additions and 0 deletions
@ -0,0 +1,162 @@ |
|||||
|
import React from "react"; |
||||
|
import { Text, TouchableOpacity, View, SafeAreaView } from "react-native"; |
||||
|
import { useState, useEffect, useRef, useMemo } from "react"; |
||||
|
import { useDispatch } from "react-redux"; |
||||
|
import {generateAdditionChallenge} from '../libs/Random'; |
||||
|
import { styles } from "./styles/AppStyles"; |
||||
|
import NineKey from "../components/NineKey"; |
||||
|
import Autoscroll from "../components/Autoscroll"; |
||||
|
import Fade from "../components/Fade"; |
||||
|
import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons'; |
||||
|
import Icons from '../themes/Icons'; |
||||
|
import Colors from "../themes/Colors"; |
||||
|
import Metrics from "../themes/Metrics"; |
||||
|
|
||||
|
function AdditionGame(props){ |
||||
|
|
||||
|
const [addChallenge, setAddChallenge]= useState(() => {return generateAdditionChallenge()}); |
||||
|
const challengeState = useRef(-1); |
||||
|
const squareMemo = useMemo(renderPairs, [challengeState.current]); |
||||
|
const [timerState, setTimerState] = useState(0); |
||||
|
const localTimer = useRef(null); |
||||
|
const startTime = useRef(0); |
||||
|
const answers = useRef(0); |
||||
|
const [scrollOrigin, setScrollOrigin] = useState(0); |
||||
|
const scrollDestination = useRef(Metrics.animated.gameScrollInterval); |
||||
|
const [headerText, setHeaderText] = useState('Ready?'); |
||||
|
const [headerColor, setHeaderColor] = useState(styles.green); |
||||
|
const [headerTextColor, setHeaderTextColor] = useState(styles.darkText); |
||||
|
const dispatch = useDispatch(); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
let headerTimeout = null; |
||||
|
|
||||
|
switch(timerState){ |
||||
|
case 0: |
||||
|
headerTimeout = setTimeout(() => { |
||||
|
setHeaderColor(styles.yellow); |
||||
|
setHeaderText('Set'); |
||||
|
setTimerState(1); |
||||
|
}, 1000); |
||||
|
break; |
||||
|
case 1: |
||||
|
headerTimeout = setTimeout(() => { |
||||
|
setHeaderColor(styles.red); |
||||
|
setHeaderTextColor(styles.lightText); |
||||
|
setHeaderText('Go!'); |
||||
|
challengeState.current = 0; |
||||
|
setTimerState(2); |
||||
|
}, 1000); |
||||
|
break; |
||||
|
case 2: |
||||
|
headerTimeout = setTimeout(() => { |
||||
|
setHeaderColor(styles.dark); |
||||
|
startTime.current = (Date.now()); |
||||
|
setHeaderText(0 + ' s'); |
||||
|
setTimerState(3); |
||||
|
}, 1000); |
||||
|
break; |
||||
|
case 3: |
||||
|
headerTimeout = setInterval(() => { |
||||
|
let elapsed = Math.round((Date.now() - startTime.current) / (1000)); |
||||
|
setHeaderText(elapsed + ' s'); |
||||
|
}, 1000); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
localTimer.current = headerTimeout; |
||||
|
|
||||
|
return () => { |
||||
|
clearTimeout(localTimer.current); |
||||
|
clearInterval(localTimer.current); |
||||
|
} |
||||
|
}, [timerState]); |
||||
|
|
||||
|
|
||||
|
|
||||
|
function selectAnswer(answer){ |
||||
|
//fix
|
||||
|
if (true) { |
||||
|
answers.current = answers.current + 1; |
||||
|
} |
||||
|
|
||||
|
let newOrigin = scrollDestination.current; |
||||
|
let newDestination = scrollDestination.current - Metrics.animated.gameScrollInterval; |
||||
|
|
||||
|
scrollDestination.current = newDestination; |
||||
|
challengeState.current = challengeState.current + 1; |
||||
|
setScrollOrigin(newOrigin); |
||||
|
|
||||
|
if (challengeState.current >= 20) { |
||||
|
completeChallenge(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function completeChallenge(){ |
||||
|
let unformatted = (Date.now() - startTime.current) / (1000); |
||||
|
let finalTime = Number.parseFloat(unformatted).toFixed(3); |
||||
|
clearInterval(localTimer.current); |
||||
|
setHeaderColor(styles.darkGreen); |
||||
|
setHeaderText(finalTime + ' s'); |
||||
|
setTimerState(4); |
||||
|
// dispatch(squareFinished(answers.current, finalTime));
|
||||
|
} |
||||
|
|
||||
|
function generateLine(left, right, pairIndex) { |
||||
|
return ( |
||||
|
<Fade key={pairIndex} faded={challengeState.current !== pairIndex} duration={250}> |
||||
|
<View style={[styles.buttonMargin]}> |
||||
|
<Text style={[styles.headerTitleFont, styles.darkText, styles.centeredText]}> |
||||
|
{left + ' + ' + right + ' = '} |
||||
|
</Text> |
||||
|
</View> |
||||
|
</Fade> |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
function renderPairs(){ |
||||
|
return addChallenge.map((pair, index) => { |
||||
|
return generateLine(pair.left, pair.right, index); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<SafeAreaView style={styles.flex}> |
||||
|
<View style={[styles.timerView, headerColor, styles.centeredJustify]}> |
||||
|
<Text style={[headerTextColor, styles.headerTitleFont, styles.centeredText]}> |
||||
|
{headerText} |
||||
|
</Text> |
||||
|
</View> |
||||
|
<View style={[styles.flex, styles.flexColumn]}> |
||||
|
<Autoscroll |
||||
|
origin={scrollOrigin} |
||||
|
destination={scrollDestination.current} |
||||
|
duration={250} |
||||
|
> |
||||
|
<View style={[styles.gameView]} /> |
||||
|
{squareMemo} |
||||
|
<View style={[styles.gameView, styles.flexRow, styles.spaceEvenly, styles.centeredItems]}> |
||||
|
<MaterialIcon |
||||
|
name={Icons.squareIcons.check} |
||||
|
color={Colors.material.green800} |
||||
|
size={Metrics.icons.buttonIcon} |
||||
|
/> |
||||
|
<Text style={[styles.headerTitleFont, styles.greyText]}> |
||||
|
Finish |
||||
|
</Text> |
||||
|
</View> |
||||
|
</Autoscroll> |
||||
|
</View> |
||||
|
<View style={[styles.timerView, styles.dark, styles.centeredJustify]}> |
||||
|
<Text style={[styles.lightText, styles.headerTitleFont, styles.centeredText]}> |
||||
|
{answers.current + ' / ' + addChallenge.length} |
||||
|
</Text> |
||||
|
</View> |
||||
|
<NineKey onPress={selectAnswer}/> |
||||
|
</SafeAreaView> |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
export default AdditionGame; |
Loading…
Reference in new issue