Integrated Home comp with the game comp

This commit is contained in:
2024-02-13 09:41:01 +01:00
parent 232aae14a8
commit 79962f45dc
7 changed files with 170 additions and 86 deletions
+11 -6
View File
@@ -7,7 +7,8 @@ import { useState } from 'react';
// --------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- Context ------------------------------------------------------- // ----------------------------------------------------- Context -------------------------------------------------------
import { RecoilRoot } from 'recoil'; import { useRecoilState } from 'recoil';
import { gameStateAtom } from './contexts/gameState';
// --------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------- Components ------------------------------------------------------ // --------------------------------------------------- Components ------------------------------------------------------
@@ -28,9 +29,13 @@ import LeaderBoard from './components/Leaderboard/leaderboard';
const App = () => { const App = () => {
const [helpDisplayed, displayHelp] = useState(false); const [helpDisplayed, displayHelp] = useState(false);
const [gameState] = useRecoilState(gameStateAtom);
return ( return (
<div className='App'> <div className='App'>
{/* <RecoilRoot> {gameState.status === 'settings' && <Home />}
{(gameState.status === 'idle' || gameState.status === 'playing') && (
<>
<div className='stats'> <div className='stats'>
<Timer /> <Timer />
<Logo className={'logo'} /> <Logo className={'logo'} />
@@ -44,16 +49,16 @@ const App = () => {
<Question /> <Question />
<span>Comment jouer</span> <span>Comment jouer</span>
</button> </button>
</RecoilRoot>
{helpDisplayed && ( {helpDisplayed && (
<Help <Help
onClose={() => { onClose={() => {
displayHelp(false); displayHelp(false);
}} }}
/> />
)} */} )}
<Home /> </>
{/* <LeaderBoard /> */} )}
{gameState.status === 'board' && <LeaderBoard />}
</div> </div>
); );
}; };
+6 -6
View File
@@ -22,10 +22,10 @@ import Flag from '../../assets/flag.png';
import './styles.scss'; import './styles.scss';
// --------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------------
const Grid = ({ size = 12, difficulty = 'beginner' }) => { const Grid = () => {
const [gameState, setGameState] = useRecoilState(gameStateAtom); const [gameState, setGameState] = useRecoilState(gameStateAtom);
const [grid, setGrid] = useState(genGrid(size)); const [grid, setGrid] = useState(genGrid(gameState.gridSize));
const [, updateGrid] = useState({}); const [, updateGrid] = useState({});
const forceUpdate = useCallback(() => updateGrid({}), []); const forceUpdate = useCallback(() => updateGrid({}), []);
@@ -37,7 +37,7 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
if (grid[rowIndex][colIndex].hidden && !grid[rowIndex][colIndex].flag) { if (grid[rowIndex][colIndex].hidden && !grid[rowIndex][colIndex].flag) {
setGrid((prev) => { setGrid((prev) => {
if (gameState.status === 'idle') { if (gameState.status === 'idle') {
const { grid: newGrid, bombsCount } = startGame(prev, difficulty as Difficulty, true, rowIndex, colIndex); const { grid: newGrid, bombsCount } = startGame(prev, gameState.difficulty as Difficulty, true, rowIndex, colIndex);
prev = newGrid; prev = newGrid;
setGameState((prevGameState) => ({ setGameState((prevGameState) => ({
@@ -59,7 +59,7 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
if (grid[rowIndex][colIndex].hidden) { if (grid[rowIndex][colIndex].hidden) {
setGrid((prev) => { setGrid((prev) => {
if (gameState.status === 'idle') { if (gameState.status === 'idle') {
const { grid: newGrid, bombsCount } = startGame(prev, difficulty as Difficulty, false); const { grid: newGrid, bombsCount } = startGame(prev, gameState.difficulty as Difficulty, false);
prev = newGrid; prev = newGrid;
setGameState((prevGameState) => ({ setGameState((prevGameState) => ({
@@ -97,7 +97,7 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
<div <div
className='grid' className='grid'
style={{ style={{
gridTemplateRows: `repeat(${size}, var(--size))`, gridTemplateRows: `repeat(${gameState.gridSize}, var(--size))`,
}} }}
> >
{grid.map((row, rowIndex) => ( {grid.map((row, rowIndex) => (
@@ -105,7 +105,7 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
key={`row${rowIndex}`} key={`row${rowIndex}`}
className='row' className='row'
style={{ style={{
gridTemplateColumns: `repeat(${size}, var(--size))`, gridTemplateColumns: `repeat(${gameState.gridSize}, var(--size))`,
}} }}
> >
{row.map((cell, cellIndex) => { {row.map((cell, cellIndex) => {
+64 -12
View File
@@ -1,27 +1,79 @@
// ---------------------------------------------------------------------------------------------------------------------
//! Imports
// ---------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- Styles --------------------------------------------------------
import { useRef } from 'react';
import './styles.scss'; import './styles.scss';
import { useRecoilState } from 'recoil';
import { gameStateAtom } from '../../contexts/gameState';
// ---------------------------------------------------------------------------------------------------------------------
const Home = () => { const Home = () => {
const difficultyRef = useRef<HTMLSelectElement>(null);
const sizeRef = useRef<HTMLSelectElement>(null);
const [, setGameState] = useRecoilState(gameStateAtom);
const onClick = () => {
if (difficultyRef.current !== null && sizeRef.current !== null) {
const difficulty = difficultyRef.current.value;
const size = sizeRef.current.value;
setGameState((prev) => ({
...prev,
difficulty: difficulty,
gridSize: parseInt(size),
status: 'idle',
}));
}
};
return ( return (
<div className='gameContainer'> <div className='gameContainer'>
<h1 className='gameTitle'>Démineur</h1> <h1 className='title'>Démineur</h1>
<div className='settingsContainer'> <div className='settingsContainer'>
<div className='selectorBox'> <div className='selectorBox'>
<p className='chooseTitle'>Choisissez la taille de la grille</p> <p className='settingLabel'>Taille de la grille</p>
<select className='parameterBox'> <select
<option value='little'>Petit</option> ref={sizeRef}
<option value='medium'>Moyen</option> className='select'
<option value='big'>Grand</option> >
<option
value='12'
selected
>
Petit
</option>
<option value='16'>Moyen</option>
<option value='20'>Grand</option>
</select> </select>
</div> </div>
<div className='selectorBox'> <div className='selectorBox'>
<p className='chooseTitle'>Choisissez votre niveau</p> <p className='settingLabel'>Difficulté</p>
<select className='parameterBox'> <select
<option value='easy'>Facile</option> ref={difficultyRef}
<option value='medium'>Moyen</option> className='select'
<option value='hard'>Difficile</option> >
<option
value='beginner'
selected
>
Facile
</option>
<option value='intermediate'>Moyen</option>
<option value='expert'>Difficile</option>
</select> </select>
</div> </div>
<button className='startGameBtn'>Commencer</button>
<button
className='startButton'
onClick={onClick}
>
Commencer
</button>
</div> </div>
</div> </div>
); );
+47 -30
View File
@@ -1,47 +1,64 @@
.gameContainer { .gameContainer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center;
justify-content: center; justify-content: center;
height: 100vh; align-items: stretch;
gap: 30px;
width: 95svw;
max-width: 500px;
& > .title {
font-size: 2em;
font-weight: 600;
text-align: center;
color: #ffffff;
} }
.gameTitle { & > .settingsContainer {
font-size: 2rem; display: flex;
font-weight: bold; flex-direction: column;
} gap: 20px;
padding: 20px;
border: 2px solid #f39440;
border-radius: 5px;
background-color: #ffdccb;
.settingsContainer { & > .selectorBox {
display: grid;
grid-template-rows: repeat(2, 1fr);
margin: 1rem 0 1rem 0;
gap: 10px;
}
.selectorBox {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 20px; gap: 20px;
}
.chooseTitle{ & > .settingLabel {
font-size: 1.2rem; font-size: 1.2rem;
color: #f39440;
} }
.parameterBox { & > .select {
font-size: 1rem;
border-radius: 5px;
padding: 2.5px 5px; padding: 2.5px 5px;
} border: 1px solid #f39440;
border-radius: 5px;
.startGameBtn { background-color: #ffdccb;
margin: 1rem 0 1rem 0; font-size: 1rem;
padding: 0.7rem 1rem; color: #f39440;
border-radius: 10px; outline: none;
font-size: 1.2rem;
font-weight: bold;
background-color: #333;
color: #FFF;
border: #FFF 0.5px solid;
cursor: pointer; cursor: pointer;
} }
}
& > .startButton {
padding: 10px;
border: 2px solid #f39440;
border-radius: 5px;
background-color: #ffdccb;
font-size: 1.2em;
color: #f39440;
cursor: pointer;
transition: background-color 0.3s ease, color 0.3s ease;
&:hover {
background-color: #f39440;
color: #ffdccb;
}
}
}
}
+3 -1
View File
@@ -3,8 +3,10 @@ import { atom } from 'recoil';
export const gameStateAtom = atom({ export const gameStateAtom = atom({
key: 'gameState', key: 'gameState',
default: { default: {
status: 'settings',
difficulty: 'begginer',
gridSize: 20,
bombs: 0, bombs: 0,
placedFlags: 0, placedFlags: 0,
status: 'idle',
}, },
}); });
+6 -1
View File
@@ -5,12 +5,17 @@
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
user-select: none;
} }
#root { #root {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 20px;
width: 100svw; width: 100svw;
height: 100svh; height: 100svh;
background: #598b8e; background: #598b8e;
overflow: hidden; overflow: hidden;
color: #fff;
} }
+3
View File
@@ -2,11 +2,14 @@ import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import './index.scss'; import './index.scss';
import App from './App'; import App from './App';
import { RecoilRoot } from 'recoil';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<RecoilRoot>
<App /> <App />
</RecoilRoot>
</React.StrictMode>, </React.StrictMode>,
); );