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 {count} antimatters.
-
You have {firstDimCount} First Dimension x2.0
- +
+

+ 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%.`}

+
+ + +
+
+ + + {`First Dimension Cost: ${firstDimPrice}`} + + + + {`Second Dimension Cost: ${secondDimPrice}`} + + {/* the 3. dimension must be unlocked */} + {resetGameCounter > 2 && ( + + {`Third Dimension Cost: ${thirdDimPrice}`} + + + /* Here have to come all the other dims */ + )} +
+
+
+

{`Dimension Shift (${resetGameCounter}) `}

+

{`requires 20 ${resetGameCounter}. Dimension `}

+ +
+
+

{`Antimatter Galaxies (${galaxyCounter})`}

+

{`requires 80 8. Dimension `}

+ +
); } diff --git a/src/App2.tsx b/src/App2.tsx deleted file mode 100644 index b6775b2..0000000 --- a/src/App2.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { useState, useEffect } from 'react'; -import './App.css'; - -function App() { - const [count, setCount] = useState(0); - const [firstDimCount, setFirstDimCount] = useState(0); - const [timer, setTime] = useState(0); - const [running, setRunning] = useState(false) - - useEffect(() => { - if (running) { - const myTimer = setInterval(() => { - console.log(count, firstDimCount); - setCount(count => count + firstDimCount); - }, 500); - - return () => clearInterval(myTimer); - } - - },[running]); - - return ( -
-
You have {count} antimatters.
-
You have {firstDimCount} First Dimension x2.0
- -

- -
- ); -} - -export default App; diff --git a/src/App3.tsx b/src/App3.tsx deleted file mode 100644 index 179e2ef..0000000 --- a/src/App3.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { useState, useEffect, useRef } from 'react'; -import './App.css'; -import Dimension from './Dimension'; - -function App() { - const timerExpiredCallback = useRef(() => {}); - const [balance, setBalance] = useState(100); - const [firstDimCount, setFirstDimCount] = useState(0); - const [secondDimCount, setSecondDimCount] = useState(0); - // if the component updates, replace the timeout callback with one that references the new - // values of `count` and `firstDimCount` - - timerExpiredCallback.current = () => { - setBalance(balance + firstDimCount + 10*secondDimCount); - }; - - useEffect(() => { - let timeID = -1; - const startTimer = () => { - timeID = setTimeout(() => { - timerExpiredCallback.current(); - startTimer(); - }, 1000); - }; - startTimer(); - - // if we ever unmount / destroy this component instance, clear the timeout - return () => clearTimeout(timeID); - }, []); - - return ( -
-
You have {balance} antimatters.
- - First Dim: 10 - - Second Dim: 100 -
- ); -} - -export default App; diff --git a/src/Dimension.tsx b/src/Dimension.tsx index 69e8f26..647b638 100644 --- a/src/Dimension.tsx +++ b/src/Dimension.tsx @@ -1,31 +1,61 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, Children } from 'react'; +import './Dimentions.css'; type DimProps = { - balance: number; + antimatter: number; + setAntimatter: (fn: ((antimatter: number) => void) | number) => void; dimCount: number; setDimCount: (fn: (dim: number) => void) => void; - setBalance: (fn: ((balance: number) => void) | number) => void; + price: number; + setPrice: (fn: (dim: number) => void) => void; factor: number; + setFactor: (fn: (dim: number) => void) => void; + dimFactorCount: number; + setDimFactorCount: (fn: ((antimatter: number) => void) | number) => void; children: string; }; export default function Dimension(props: DimProps) { - const { balance, dimCount, setDimCount, setBalance, factor } = props; - const handleFirstDimBuy = () => { - if (balance >= factor) { - setDimCount(dimCount => dimCount + 1); - setBalance(balance => balance - factor); + const { antimatter, dimCount, setDimCount, setAntimatter, price, setPrice, factor, setFactor, dimFactorCount, setDimFactorCount } = props; + + const handleDimBuy = (quantity: number) => { + if (antimatter >= price) { + setDimCount(dimCount => dimCount + quantity); + setAntimatter(prevValue => prevValue - price * quantity); + setDimFactorCount(prevCount => prevCount +1) + } + if ((dimCount + 1) % 10 === 0 && dimCount > 1 || quantity===10) { + setPrice(prevPrice => prevPrice * 10); + setFactor(prevFactor => prevFactor * 2) + setDimFactorCount(0) } }; + + return ( <>
-
- You have {dimCount} {props.children.split(" ")[0]} {factor / 10}x +
+

+ {`${ props.children.split(" ").slice(0,2).join(" ")} x${factor}`} +

+

+ {` ${dimCount % 1 === 0 ? dimCount.toFixed(0) : dimCount.toFixed(1)} + (${dimFactorCount}) + + `} +

+ +
- +
); diff --git a/src/Dimentions.css b/src/Dimentions.css new file mode 100644 index 0000000..e69de29 diff --git a/src/backup.ts b/src/backup.ts new file mode 100644 index 0000000..7d26cd3 --- /dev/null +++ b/src/backup.ts @@ -0,0 +1,23 @@ +const data = { + timerId, + toSaveId, + clockSpeedRef, + tickspeedPrice, + antimatter, + firstDimCount, + firstDimFactor, + firstDimPrice, + firstDimFactorCount, + secondDimCount, + secondDimFactor, + secondDimPrice, + secondDimFactorCount, + thirdDimCount, + thirdDimFactor, + thirdDimPrice, + thirdDimFactorCount, +}; +const canIstillBuy = () => { + if (canIstillBuyRef.current > 0) true + else false +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 9a9546e..4a1b150 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,6 +1,6 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import App from './App3' +import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render(