Skip to content

Commit

Permalink
add nicer score indicators and instructions page
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-james-watson committed Oct 29, 2021
1 parent a2cb811 commit 94e8ade
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 41 deletions.
22 changes: 17 additions & 5 deletions components/board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import Hearts from "./hearts";
import GameOver from "./game-over";

interface Props {
highscore: number;
resetGame: () => void;
state: GameState;
setState: (state: GameState) => void;
updateHighscore: (score: number) => void;
}

export default function Board(props: Props) {
const { resetGame, state, setState } = props;
const { highscore, resetGame, state, setState, updateHighscore } = props;

const [isDragging, setIsDragging] = React.useState(false);

Expand Down Expand Up @@ -57,7 +59,6 @@ export default function Board(props: Props) {
played: { correct },
});

console.log({ added1: { ...state.next } });
setState({
...state,
deck: newDeck,
Expand All @@ -81,7 +82,6 @@ export default function Board(props: Props) {
const newPlayed = [...state.played];
const [item] = newPlayed.splice(source.index, 1);
newPlayed.splice(destination.index, 0, item);
console.log({ added2: item });

setState({
...state,
Expand Down Expand Up @@ -110,6 +110,12 @@ export default function Board(props: Props) {
return state.played.filter((item) => item.played.correct).length - 1;
}, [state.played]);

React.useLayoutEffect(() => {
if (score > highscore) {
updateHighscore(score);
}
}, [score, highscore, updateHighscore]);

return (
<DragDropContext
onDragEnd={onDragEnd}
Expand All @@ -120,9 +126,15 @@ export default function Board(props: Props) {
<div className={styles.top}>
<Hearts lives={state.lives} />
{state.lives > 0 ? (
<NextItemList next={state.next} />
<>
<NextItemList next={state.next} />
</>
) : (
<GameOver resetGame={resetGame} score={score} />
<GameOver
highscore={highscore}
resetGame={resetGame}
score={score}
/>
)}
</div>
<div id="bottom" className={styles.bottom}>
Expand Down
26 changes: 12 additions & 14 deletions components/game-over.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,16 @@ import React from "react";
import { animated, useSpring } from "react-spring";
import styles from "../styles/game-over.module.scss";
import Button from "./button";
import Score from "./score";

interface Props {
highscore: number;
resetGame: () => void;
score: number;
}

export default function GameOver(props: Props) {
const { resetGame, score } = props;

const highscore = Number(localStorage.getItem("highscore") ?? "0");

React.useLayoutEffect(() => {
if (score > highscore) {
localStorage.setItem("highscore", String(score));
}
}, [score, highscore]);
const { highscore, resetGame, score } = props;

const animProps = useSpring({
opacity: 1,
Expand All @@ -27,11 +21,15 @@ export default function GameOver(props: Props) {

return (
<animated.div style={animProps} className={styles.gameOver}>
<span className={styles.score}>Score: {score}</span>
{highscore !== 0 && (
<span className={styles.highscore}>High Score: {highscore}</span>
)}
<Button onClick={resetGame} text="Play again" />
<div className={styles.scoresWrapper}>
<div className={styles.score}>
<Score score={score} title="Streak" />
</div>
<div className={styles.score}>
<Score score={highscore} title="Best streak" />
</div>
</div>
<Button onClick={resetGame} text="Play again!" />
</animated.div>
);
}
35 changes: 28 additions & 7 deletions components/game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { Item } from "../types/item";
import createState from "../lib/create-state";
import Board from "./board";
import Loading from "./loading";
import Instructions from "./instructions";

export default function Game() {
const [state, setState] = useState<GameState | null>(null);
const [loaded, setLoaded] = useState(false);
const [started, setStarted] = useState(false);
const [items, setItems] = useState<Item[] | null>(null);

React.useEffect(() => {
Expand Down Expand Up @@ -43,13 +45,32 @@ export default function Game() {
})();
}, [items]);

const [highscore, setHighscore] = React.useState<number>(
Number(localStorage.getItem("highscore") ?? "0")
);

const updateHighscore = React.useCallback((score: number) => {
localStorage.setItem("highscore", String(score));
setHighscore(score);
}, []);

if (!loaded || state === null) {
return <Loading />;
}

if (!started) {
return (
<Instructions highscore={highscore} start={() => setStarted(true)} />
);
}

return (
<>
{loaded && state !== null ? (
<Board state={state} setState={setState} resetGame={resetGame} />
) : (
<Loading />
)}
</>
<Board
highscore={highscore}
state={state}
setState={setState}
resetGame={resetGame}
updateHighscore={updateHighscore}
/>
);
}
25 changes: 25 additions & 0 deletions components/instructions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import styles from "../styles/instructions.module.scss";
import Button from "./button";
import Score from "./score";

interface Props {
highscore: number;
start: () => void;
}

export default function Instructions(props: Props) {
const { highscore, start } = props;

return (
<div className={styles.instructions}>
<div className={styles.wrapper}>
<h2>Place the cards on the timeline in the correct order.</h2>
<div className={styles.highscoreWrapper}>
<Score score={highscore} title="Best streak" />
</div>
<Button onClick={start} text="Start game!" />
</div>
</div>
);
}
28 changes: 28 additions & 0 deletions components/score.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import styles from "../styles/score.module.scss";

interface Props {
score: number;
title: string;
}

export default function Score(props: Props) {
const { score, title } = props;

let backgroundColor = "#ffffff";

if (score >= 20) {
backgroundColor = "#FFC940";
} else if (score >= 10) {
backgroundColor = "#A7B6C2";
} else if (score >= 1) {
backgroundColor = "#C99765";
}

return (
<div className={styles.score} style={{ backgroundColor }}>
<div className={styles.title}>{title}</div>
<div className={styles.value}>{score}</div>
</div>
);
}
5 changes: 2 additions & 3 deletions styles/button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
border: none;
background: $primary;
color: $text-light;
padding: 10px;
border-radius: 20px;
padding: 10px 24px;
border-radius: $button-border-radius;
cursor: pointer;
text-transform: uppercase;
font-weight: 700;
font-style: italic;
padding: 10px 24px;

&:hover {
filter: brightness(1.3);
Expand Down
23 changes: 11 additions & 12 deletions styles/game-over.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 20px;
margin-top: 60px;

.score,
.highscore {
color: $text-light;
font-size: 28px;
}
.scoresWrapper {
margin: 40px 0;
display: flex;
justify-content: space-evenly;

.score {
margin-top: 20px;
}
.score {
display: inline-block;

.highscore {
margin-top: 10px;
margin-bottom: 40px;
&:last-child {
margin-left: 20px;
}
}
}
}
24 changes: 24 additions & 0 deletions styles/instructions.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@import "./variables.scss";

.instructions {
display: flex;
height: calc(100% - 100px);
flex-direction: column;
align-items: center;
justify-content: center;

.wrapper {
padding: 0 20px;
text-align: center;

h2 {
color: $text-light;
font-style: italic;
text-transform: uppercase;
}

.highscoreWrapper {
margin: 40px 0;
}
}
}
22 changes: 22 additions & 0 deletions styles/score.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@import "./variables.scss";

.score {
display: inline-block;
transform: skewX(-12deg);
border-radius: $box-border-radius;
padding: 10px 24px;
text-align: left;
width: 140px;

.title {
font-weight: 700;
text-transform: uppercase;
margin-bottom: 5px;
white-space: nowrap;
}

.value {
font-weight: 700;
font-size: 24px;
}
}
1 change: 1 addition & 0 deletions styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ $incorrect: #990000;
$correct: #339966;
$primary: #006699;
$box-border-radius: 8px;
$button-border-radius: 20px;

0 comments on commit 94e8ade

Please sign in to comment.