Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor 4 #22

Open
wants to merge 1 commit into
base: refactor-3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/components/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useState } from "react";
import { GlobalContext } from "../../contexts";
import World from "../World";
import Player from "../Player";
import PlayerHealth from "../PlayerHealth";
import Npc from "../Npc";
import Heart from "../Heart";
import Coin from "../Coin";
Expand All @@ -10,7 +11,7 @@ import Lever from "../Lever";
import House from "../House";
import Fire from "../Fire";
import GameOver from "../GameOver";
import { GAME_STATES } from "../../constants";
import { GAME_STATES, MAX_HEALTH } from "../../constants";
import "./style.css";

/*
Expand All @@ -22,17 +23,19 @@ export default function App() {
const [gameState, setGameState] = useState<GAME_STATES>(GAME_STATES.Game);
const [isCellarDoorOpen, setIsCellarDoorOpen] = useState(false);
const [isLeverUsed, setIsLeverUsed] = useState(false);
const [playerHealth, setPlayerHealth] = useState(4);
const [playerHealth, setPlayerHealth] = useState(MAX_HEALTH);

return (
<div className="App">
<GlobalContext.Provider value={{ gameState: gameState, setGameState }}>
<GlobalContext.Provider
value={{ gameState: gameState, setGameState, playerHealth }}
>
{gameState === GAME_STATES.GameOver && <GameOver />}
<World />
<PlayerHealth />
<Player
top={328}
left={420}
health={playerHealth}
onInteract={setIsLeverUsed}
onCollision={setPlayerHealth}
/>
Expand Down
47 changes: 7 additions & 40 deletions src/components/Player/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const ANIMATION_LENGTH = 3;
type PlayerProps = {
top: number;
left: number;
health: number;
onInteract: (isOpen: boolean | ((wasOpen: boolean) => boolean)) => void;
onCollision: (health: number | ((prev: number) => number)) => void;
};
Expand All @@ -27,52 +26,21 @@ type PlayerProps = {
* - create util function for collisions
*/
let invulnerable = false;
const Player: FC<PlayerProps> = ({
health,
onInteract,
onCollision,
top,
left,
}) => {
const Player: FC<PlayerProps> = ({ onInteract, onCollision, top, left }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const { setGameState } = useContext(GlobalContext);
const { setGameState, playerHealth } = useContext(GlobalContext);

useEffect(() => {
const fireCanvas = document.getElementById(
"fire-canvas"
) as HTMLCanvasElement | null;
const healthCanvas = document.getElementById(
"health-canvas"
) as HTMLCanvasElement | null;
const heartCanvas = document.getElementById(
"heart-canvas"
) as HTMLCanvasElement | null;
const coinCanvas = document.getElementById(
"coin-canvas"
) as HTMLCanvasElement | null;

if (healthCanvas) {
const ctx = healthCanvas.getContext("2d");
if (ctx) {
const tileSet = new Image();
tileSet.src = TILE_SETS.Objects;
tileSet.onload = () => {
ctx.clearRect(0, 0, 30, 26);
if (health === 4) {
ctx.drawImage(tileSet, 128, 4, 30, 26, 0, 0, 30, 26);
} else if (health === 3) {
ctx.drawImage(tileSet, 160, 4, 30, 26, 0, 0, 30, 26);
} else if (health === 2) {
ctx.drawImage(tileSet, 192, 4, 30, 26, 0, 0, 30, 26);
} else if (health === 1) {
ctx.drawImage(tileSet, 224, 4, 30, 26, 0, 0, 30, 26);
} else if (health === 0) {
ctx.drawImage(tileSet, 256, 4, 30, 26, 0, 0, 30, 26);
}
};
}
}

if (!canvasRef.current) {
return;
}
Expand Down Expand Up @@ -164,8 +132,8 @@ const Player: FC<PlayerProps> = ({
return;
}

if (health > 0) {
if (health < 4) {
if (playerHealth > 0) {
if (playerHealth < 4) {
if (
heartCanvas &&
parseInt(canvasRef.current.style.left || "0") + 6 <=
Expand All @@ -177,7 +145,7 @@ const Player: FC<PlayerProps> = ({
parseInt(canvasRef.current.style.top || "0") + 36 >=
parseInt(heartCanvas.style.top || "0") + 16
) {
onCollision((health) => Math.min(4, health + 1));
onCollision((playerHealth) => Math.min(4, playerHealth + 1));
heartCanvas.remove();
}
}
Expand Down Expand Up @@ -254,7 +222,7 @@ const Player: FC<PlayerProps> = ({
)}px`;
}

onCollision((health) => Math.max(0, health - 1));
onCollision((playerHealth) => Math.max(0, playerHealth - 1));
invulnerable = true;
canvasRef.current.style.filter = "brightness(6)";

Expand Down Expand Up @@ -347,7 +315,7 @@ const Player: FC<PlayerProps> = ({
}
};
};
}, [onInteract, onCollision, health, setGameState, top, left]);
}, [onInteract, onCollision, playerHealth, setGameState, top, left]);

return (
<>
Expand All @@ -357,7 +325,6 @@ const Player: FC<PlayerProps> = ({
width={WIDTH}
height={HEIGHT}
></canvas>
<canvas id="health-canvas" width="30" height="26"></canvas>
</>
);
};
Expand Down
6 changes: 0 additions & 6 deletions src/components/Player/style.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
#player-canvas {
z-index: 99;
}

#health-canvas {
z-index: 99;
top: calc((1536px - 100vh) / 2 + 8px);
left: calc((2048px - 100vw) / 2 + 8px);
}
34 changes: 34 additions & 0 deletions src/components/PlayerHealth/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useRef, useContext, FC } from "react";
import { TILE_SIZE, TILE_SETS, MAX_HEALTH } from "../../constants";
import { GlobalContext } from "../../contexts";
import { useSprite } from "../../hooks";
import "./style.css";

const WIDTH = TILE_SIZE;
const HEIGHT = TILE_SIZE;
const TILE_X = 128;

const PlayerHealth: FC = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const { playerHealth } = useContext(GlobalContext);

useSprite({
canvasRef,
tileSet: TILE_SETS.Objects,
width: WIDTH,
height: HEIGHT,
tileX: TILE_X + WIDTH * (MAX_HEALTH - playerHealth),
tileY: 0,
});

return (
<canvas
ref={canvasRef}
id="health-canvas"
width={WIDTH}
height={HEIGHT}
></canvas>
);
};

export default PlayerHealth;
5 changes: 5 additions & 0 deletions src/components/PlayerHealth/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#health-canvas {
z-index: 99;
top: calc((1536px - 100vh) / 2 + 32px);
left: calc((2048px - 100vw) / 2 + 8px);
}
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ export enum TILE_SETS {
export const TILE_SIZE = 32;
export const WORLD_WIDTH = 2048;
export const WORLD_HEIGHT = 1536;

export const MAX_HEALTH = 4;
export const MIN_HEALTH = 0;
4 changes: 3 additions & 1 deletion src/contexts/global.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { createContext } from "react";
import { GAME_STATES } from "../constants";
import { GAME_STATES, MAX_HEALTH } from "../constants";

export type GlobalContextType = {
readonly gameState: GAME_STATES;
setGameState(newState: GAME_STATES): void;
playerHealth: number;
};

export const GlobalContext = createContext<GlobalContextType>({
gameState: GAME_STATES.Game,
setGameState: () => {},
playerHealth: MAX_HEALTH,
});
4 changes: 2 additions & 2 deletions src/hooks/useAnimatedSprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const useAnimatedSprite = (props: AnimatedSpriteProps) => {
return;
}

props.canvasRef.current.style.left = `${props.left}px`;
props.canvasRef.current.style.top = `${props.top}px`;
props.left && (props.canvasRef.current.style.left = `${props.left}px`);
props.top && (props.canvasRef.current.style.top = `${props.top}px`);

const sprite = new Image();
sprite.src = props.tileSet;
Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useSprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export type SpriteProps = {
height: number;
tileX: number;
tileY: number;
left: number;
top: number;
left?: number;
top?: number;
};

export const useSprite = (props: SpriteProps) => {
Expand All @@ -20,8 +20,8 @@ export const useSprite = (props: SpriteProps) => {
return;
}

props.canvasRef.current.style.left = `${props.left}px`;
props.canvasRef.current.style.top = `${props.top}px`;
props.left && (props.canvasRef.current.style.left = `${props.left}px`);
props.top && (props.canvasRef.current.style.top = `${props.top}px`);

const sprite = new Image();
sprite.src = props.tileSet;
Expand Down