diff --git a/src/App.css b/src/App.css index 8da3fde..43d9fa5 100644 --- a/src/App.css +++ b/src/App.css @@ -1,42 +1,73 @@ +* { + /* border: 1px solid black; */ +} + .App { - text-align: center; + margin: 1rem; +} +.heading { + display: flex; + padding: 2rem; + margin: auto; + width: 100%; +} + +.highlight { + padding: 0.5rem 2rem; + font-size: 1.3rem; + border: 1px black solid; + background-color: beige; } -.App-logo { - height: 40vmin; - pointer-events: none; +.gridContainer4Cols { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 10px; + grid-auto-rows: minmax(40px, auto); } -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } +.gridContainer3Rows { + display: grid; + grid-template-rows: repeat(3, 1fr); + gap: 4px; + grid-auto-rows: minmax(40px, auto); } -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; +.centered { + display: flex; + justify-content: center; + margin: auto; + align-items: center; + text-align: center; } -.App-link { - color: #61dafb; +.cols-2{ + grid-template-columns: repeat(3, 1fr); + margin: auto 5rem; } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +.btn { + font-size: calc(10px + 1vmin); + padding: 0.2em 1em 0.2em 1em; + margin: 0 0.5rem; + border: 1px black solid; + border-radius: 6px; + background-color: rgb(240, 238, 238); +} +.btn:hover { + background-image: linear-gradient(to right, #29323c, #485563, #2b5876, #4e4376); + box-shadow: 0 4px 15px 0 rgba(45, 54, 65, 0.75); +} +.btn:disabled{ + background: initial; + box-shadow: initial; +} +.sm{ + font-size: calc(10px + 0.5vmin); } -button { - font-size: calc(10px + 2vmin); +.btn:disabled{ + background-color: rgb(255, 254, 254); + border: 1px rgb(240, 238, 238) solid; + color: rgb(180, 177, 177); } diff --git a/src/App.tsx b/src/App.tsx index fcabae8..1a6f099 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,29 +1,288 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import './App.css'; +import Dimension from './Dimension'; + +type DimProps = { + antimatter: number; + dimCount: number; + setDimCount: (fn: (dim: number) => void) => void; + setAntimatter: (fn: ((antimatter: number) => void) | number) => void; + price: number; +}; function App() { - const [count, setCount] = useState(0); + // tried to load the object data with the first opening of the page and then assign it to all the state but this was not sucessful. Loading ervery prop this way is very slow. CUrrently I do not know how to get the load data + + // the 2. thing I did not know how to do was the Buy max button. A while loop crashed the browser :( UPDATE: now it works with a recursion. are there better ways + const dataRef = useRef(() => JSON.parse(localStorage.getItem('data')) ?? {}); + const canIstillBuyRef = useRef(0); + const timerExpiredCallback = useRef(() => {}); + const clockSpeedRef = useRef(2000); + const timerIdRef = useRef(-1); + const idRef = useRef(-1); + const timeIdRef = useRef(-1); + + // const dataRef = useRef({}); + const [tickspeedPrice, setTickspeedPrice] = useState(10); + const [antimatter, setAntimatter] = useState(1000); + const [resetGameCounter, setResetGameCounter] = useState(2); + const [galaxyCounter, setGalaxyCounter] = useState(0); + const [highesDim, setHighesDim] = useState(0); + + const [firstDimFactor, setFirstDimFactor] = useState(1.1); const [firstDimCount, setFirstDimCount] = useState(0); - const [timer, setTime] = useState(0); + const [firstDimPrice, setFirstDimPrice] = useState(10); + const [firstDimFactorCount, setFirstDimFactorCount] = useState(0); + + const [secondDimFactor, setSecondDimFactor] = useState(1.1); + const [secondDimCount, setSecondDimCount] = useState(0); + const [secondDimPrice, setSecondDimPrice] = useState(100); + const [secondDimFactorCount, setSecondDimFactorCount] = useState(0); + + const [thirdDimFactor, setThirdDimFactor] = useState(1.1); + const [thirdDimCount, setThirdDimCount] = useState(0); + const [thirdDimPrice, setThirdDimPrice] = useState(1000); + const [thirdDimFactorCount, setThirdDimFactorCount] = useState(0); + // if the component updates, replace the timeout callback with one that references the new + // values of `count` and `firstDimCount` + + timerExpiredCallback.current = () => { + setAntimatter(prevAntimatter => prevAntimatter + firstDimCount * firstDimFactor); + setFirstDimCount(prevFirstDim => prevFirstDim + (secondDimCount / 10) * secondDimFactor); + setSecondDimCount(prevSecondDim => prevSecondDim + (thirdDimCount / 100) * thirdDimFactor); + }; useEffect(() => { const startTimer = () => { - const myTimer = setTimeout(() => { - console.log(count, firstDimCount); - setCount(count => count + firstDimCount); + timerIdRef.current = setTimeout(() => { + timerExpiredCallback.current(); startTimer(); - }, 1000); + }, clockSpeedRef.current); }; - - startTimer(); - return () => {}; + startTimer(); + + // if we ever unmount / destroy this component instance, clear the timeout + return () => clearTimeout(timerIdRef.current); }, []); + //------------------------------------------- + // FROM HERE + + const handleTickBtnClick = () => { + clockSpeedRef.current = clockSpeedRef.current * (1 - 0.11); + setAntimatter(prevPrice => prevPrice - tickspeedPrice); + setTickspeedPrice(prevPrice => prevPrice * 10); + }; + + useEffect(() => { + canIstillBuyRef.current = antimatter - tickspeedPrice; + }, [tickspeedPrice]); + + /* ref is needed to get the current state */ + const canIstillBuy = () => { + if (canIstillBuyRef.current > 0) return true; + else return false; + }; + + /* It works but I do not know if there are better ways */ + const handleBuyMaxClick = () => { + const repeatMax = () => { + timeIdRef.current = setTimeout(() => { + if (canIstillBuy()) { + console.log(canIstillBuy(), canIstillBuyRef.current, tickspeedPrice); + handleTickBtnClick(); + repeatMax(); + } + }, 20); + + return () => clearTimeout(timeIdRef.current); + }; + repeatMax(); + }; + + // creates constantly an uptodate object which is then saved later + useEffect(() => { + dataRef.current = { + // ...dataRef.current, + antimatter, + tickspeedPrice, + firstDimCount, + firstDimFactor, + firstDimPrice, + firstDimFactorCount, + secondDimCount, + secondDimFactor, + secondDimPrice, + secondDimFactorCount, + thirdDimCount, + thirdDimFactor, + thirdDimPrice, + thirdDimFactorCount, + resetGameCounter, + highesDim, + timerIdRef, + idRef, + clockSpeedRef, + }; + //console.log('dataRef object update cycle: ', dataRef.current ?? ''); + }); + + // saves the created object every minuit to localStorage + useEffect(() => { + const startSave = () => { + timerIdRef.current = setTimeout(() => { + //localStorage.removeItem('dataRef'); + localStorage.setItem('data', JSON.stringify(dataRef.current)); + console.log('data save cycle: ', dataRef.current); + startSave(); + }, 60000); + }; + startSave(); + + // if we ever unmount / destroy this component instance, clear the timeout + return () => clearTimeout(timerIdRef.current); + }, []); + + // this prints the saved object from local storage. It is just for dev. No final purpose + useEffect(() => { + const printStorage = () => { + idRef.current = setTimeout(() => { + let savedDataRef = JSON.parse(localStorage.getItem('data') ?? ''); + console.log('dataRef from storage', savedDataRef); + printStorage(); + }, 60000); + }; + printStorage(); + + return () => clearTimeout(idRef.current); + }, []); + + /* resets the game to unlock new dimension */ + const handleResetGameClick = () => { + clockSpeedRef.current = 2000; + timerIdRef.current = -1; + idRef.current = -1; + + setTickspeedPrice(10); + setAntimatter(1000); + + setFirstDimFactor(1.1); + setFirstDimCount(0); + setFirstDimPrice(10); + setFirstDimFactorCount(0); + + setSecondDimFactor(1.1); + setSecondDimCount(0); + setSecondDimPrice(100); + setSecondDimFactorCount(0); + + setThirdDimFactor(1.1); + setThirdDimCount(0); + setThirdDimPrice(1000); + setThirdDimFactorCount(0); + + // increase ResetCounter by one + setResetGameCounter(prev => prev + 1); + }; + /* saves the current DimCount of the highes Dim */ + useEffect(() => { + /* higher dims have to be added when created */ + if (thirdDimCount !== 0) setHighesDim(thirdDimCount); + else setHighesDim(secondDimCount); + }, [secondDimCount, thirdDimCount]); + + //--------------------------------------------------- + return (
+ You have {antimatter % 1 === 0 ? antimatter.toFixed(0) : antimatter.toFixed(1)}{' '} + antimatters. +
+{`The current clockspeed is ${clockSpeedRef.current.toFixed( + 0 + )} ms. Reduce the tickspeed by 11%.`}
+{`Dimension Shift (${resetGameCounter}) `}
+{`requires 20 ${resetGameCounter}. Dimension `}
+ +{`Antimatter Galaxies (${galaxyCounter})`}
+{`requires 80 8. Dimension `}
+ ++ {`${ props.children.split(" ").slice(0,2).join(" ")} x${factor}`} +
++ {` ${dimCount % 1 === 0 ? dimCount.toFixed(0) : dimCount.toFixed(1)} + (${dimFactorCount}) + + `} +
+ +