Ability to loose game

This commit is contained in:
2024-02-18 09:50:33 +01:00
parent e21910547a
commit 8219634b9c
8 changed files with 113 additions and 28 deletions
+20
View File
@@ -0,0 +1,20 @@
const Podium = (props: any) => {
return (
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 512 512'
{...props}
>
<path
d='M32 160v296a8 8 0 008 8h136V160a16 16 0 00-16-16H48a16 16 0 00-16 16zM320 48H192a16 16 0 00-16 16v400h160V64a16 16 0 00-16-16zM464 208H352a16 16 0 00-16 16v240h136a8 8 0 008-8V224a16 16 0 00-16-16z'
fill='none'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='32'
/>
</svg>
);
};
export default Podium;
+29 -1
View File
@@ -13,13 +13,14 @@ import { gameStateAtom } from '../../contexts/gameState';
// ------------------------------------------------------ Utils --------------------------------------------------------
import { Difficulty } from '../../types/game';
import { discoverAroundCell, genGrid, startGame } from '../../utils/game';
import { discoverAroundCell, genGrid, revealAllGrid, startGame } from '../../utils/game';
// ---------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- Assets --------------------------------------------------------
import Bomb from '../../assets/bomb.png';
import Flag from '../../assets/flag.png';
import './styles.scss';
import Podium from '../../assets/podium';
// ---------------------------------------------------------------------------------------------------------------------
const Grid = () => {
@@ -47,6 +48,14 @@ const Grid = () => {
}));
}
if (prev[rowIndex][colIndex].value === 'bomb') {
setGameState((prev) => ({
...prev,
endType: 'loose',
}));
return revealAllGrid(grid, true);
}
return discoverAroundCell(prev, rowIndex, colIndex);
});
forceUpdate();
@@ -138,6 +147,25 @@ const Grid = () => {
})}
</div>
))}
{gameState.endType !== '' && (
<div
className='overlay'
style={
{
'--overlayColor': gameState.endType === 'win' ? '#5f8e59' : '#ca5940',
} as React.CSSProperties
}
>
<p className='overlayTitle'>{gameState.endType === 'win' ? 'Gagné !' : 'Perdu !'}</p>
<button
className='overlayButton'
onClick={() => setGameState((prev) => ({ ...prev, status: 'board' }))}
>
<Podium />
Leaderboard
</button>
</div>
)}
</div>
);
};
+36
View File
@@ -1,5 +1,6 @@
.grid {
--size: 30px;
position: relative;
display: grid;
gap: 2px;
padding: 2px;
@@ -73,4 +74,39 @@
}
}
}
& > .overlay {
z-index: 1;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 30px;
width: 100%;
height: 100%;
background-color: rgba($color: #000000, $alpha: 0.3);
backdrop-filter: blur(1px);
& > .overlayTitle {
font-size: 2.5em;
color: var(--overlayColor);
}
& > .overlayButton {
display: grid;
grid-template-columns: 1.1em auto;
place-items: center;
gap: 10px;
padding: 10px 25px;
border: none;
border-radius: 5px;
background-color: var(--overlayColor);
font-size: 1em;
color: #ffff;
cursor: pointer;
}
}
}
+4 -12
View File
@@ -39,13 +39,9 @@ const Home = () => {
<select
ref={sizeRef}
className='select'
defaultValue={'12'}
>
<option
value='12'
selected
>
Petit
</option>
<option value='12'>Petit</option>
<option value='16'>Moyen</option>
<option value='20'>Grand</option>
</select>
@@ -56,13 +52,9 @@ const Home = () => {
<select
ref={difficultyRef}
className='select'
defaultValue={'beginner'}
>
<option
value='beginner'
selected
>
Facile
</option>
<option value='beginner'>Facile</option>
<option value='intermediate'>Moyen</option>
<option value='expert'>Difficile</option>
</select>
+2 -2
View File
@@ -47,7 +47,7 @@ const LeaderBoard = () => {
if (data.length === 0) {
getData();
}
}, []);
}, [data.length]);
return (
<>
@@ -93,7 +93,7 @@ const LeaderBoard = () => {
<button
className='controlButton replay'
onClick={() => setGameState((prev) => ({ ...prev, status: 'idle', endType: '', placedFlags: 0, bombs: 0, gameTime: 0 }))}
onClick={() => setGameState((prev) => ({ ...prev, status: 'idle', endType: '', placedFlags: 0, bombs: 0, gameTime: '' }))}
>
<Replay />
Rejouer
+21 -9
View File
@@ -14,23 +14,25 @@ import { gameStateAtom } from '../../../contexts/gameState';
// ---------------------------------------------------------------------------------------------------------------------
const Timer = () => {
const [{ status }] = useRecoilState(gameStateAtom);
const [gameState, setGameState] = useRecoilState(gameStateAtom);
const [intervalId, setIntervalId] = useState<NodeJS.Timeout | null>(null);
const [startedTime, setStartedTime] = useState<number | null>(null);
const [displayedTime, setDisplayedTime] = useState<string>('00:00');
useEffect(() => {
if (status === 'playing') {
setStartedTime(Date.now());
} else if (status === 'win' || status === 'loose') {
if (gameState.status === 'win' || gameState.status === 'loose') {
setStartedTime(null);
}
}, [status]);
}, [gameState.status]);
useEffect(() => {
if (startedTime) {
if (!startedTime && gameState.endType === '' && gameState.status === 'playing') {
const now = Date.now();
setStartedTime(now);
const interval = setInterval(() => {
const elapsedTime = (Date.now() - startedTime) / 1000;
const elapsedTime = (Date.now() - now) / 1000;
const seconds = Math.floor(elapsedTime % 60);
const strSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
@@ -41,9 +43,19 @@ const Timer = () => {
setDisplayedTime(`${strMinute}:${strSeconds}`);
}, 500);
return () => clearInterval(interval);
setIntervalId(interval);
}
}, [startedTime]);
}, [startedTime, gameState.endType, gameState.status]);
useEffect(() => {
if (intervalId && gameState.endType !== '') {
setGameState((prev) => ({
...prev,
gameTime: displayedTime,
}));
clearInterval(intervalId);
}
}, [intervalId, gameState.endType, setGameState, displayedTime]);
return (
<div className='statContainer'>
+1 -1
View File
@@ -19,7 +19,7 @@ export const gameStateAtom = atom({
gridSize: 12,
bombs: 0,
placedFlags: 0,
gameTime: 0,
gameTime: '',
endType: '',
},
});
-3
View File
@@ -31,9 +31,6 @@ export const genBombs = (grid: GridType, difficulty: Difficulty) => {
bombs = surface * 0.15;
}
console.log(difficulty);
// console.log(surface, surface * 0.05, bombs);
bombs = Math.floor(bombs);
for (let i = 1; i <= bombs; i++) {
let needRegenerate = false;