From 1e982b08f0d21a335434fc685c9aec5ea4c2242f Mon Sep 17 00:00:00 2001 From: Michael Tintiuc Date: Tue, 11 Oct 2022 03:07:01 +0300 Subject: [PATCH] Refactor 3 --- src/components/CellarDoor/index.tsx | 41 ++++++------------- src/components/Coin/index.tsx | 61 +++++++---------------------- src/components/Fire/index.tsx | 61 +++++++---------------------- src/components/Heart/index.tsx | 60 +++++++--------------------- src/components/House/index.tsx | 45 ++++++--------------- src/components/Lever/index.tsx | 49 +++++++---------------- src/hooks/index.ts | 2 + src/hooks/useAnimatedSprite.ts | 50 +++++++++++++++++++++++ src/hooks/useSprite.ts | 44 +++++++++++++++++++++ 9 files changed, 176 insertions(+), 237 deletions(-) create mode 100644 src/hooks/index.ts create mode 100644 src/hooks/useAnimatedSprite.ts create mode 100644 src/hooks/useSprite.ts diff --git a/src/components/CellarDoor/index.tsx b/src/components/CellarDoor/index.tsx index 77b3161..081a415 100644 --- a/src/components/CellarDoor/index.tsx +++ b/src/components/CellarDoor/index.tsx @@ -1,11 +1,11 @@ -import { useEffect, useRef, FC } from "react"; +import { useRef, FC } from "react"; import { TILE_SETS } from "../../constants"; +import { useSprite } from "../../hooks"; import "./style.css"; const WIDTH = 64; const HEIGHT = 64; const TILE_X = 992; -const TILE_Y = 160; type CellarDoorProps = { top: number; left: number; isOpen?: boolean }; @@ -16,34 +16,17 @@ type CellarDoorProps = { top: number; left: number; isOpen?: boolean }; */ const CellarDoor: FC = ({ isOpen = false, top, left }) => { const canvasRef = useRef(null); - useEffect(() => { - const ctx = canvasRef.current?.getContext("2d"); - if (!canvasRef.current || !ctx) { - return; - } - - canvasRef.current.style.left = `${left}px`; - canvasRef.current.style.top = `${top}px`; - - const tileSet = new Image(); - tileSet.src = TILE_SETS.World; - tileSet.onload = () => { - ctx.clearRect(0, 0, WIDTH, HEIGHT); - - ctx.drawImage( - tileSet, - isOpen ? TILE_X + WIDTH : TILE_X, - TILE_Y, - WIDTH, - HEIGHT, - 0, - 0, - WIDTH, - HEIGHT - ); - }; - }, [isOpen, left, top]); + useSprite({ + canvasRef, + left, + top, + tileSet: TILE_SETS.World, + width: WIDTH, + height: HEIGHT, + tileX: isOpen ? TILE_X + WIDTH : TILE_X, + tileY: 160, + }); return ( = ({ left, top }) => { const canvasRef = useRef(null); - useEffect(() => { - const ctx = canvasRef.current?.getContext("2d"); - let intervalId: number; - - if (!canvasRef.current || !ctx) { - return; - } - - canvasRef.current.style.left = `${left}px`; - canvasRef.current.style.top = `${top}px`; - - const tileSet = new Image(); - tileSet.src = TILE_SETS.Objects; - tileSet.onload = () => { - let currentFrame = 0; - - intervalId = window.setInterval(() => { - ctx.clearRect(0, 0, WIDTH, HEIGHT); - - ctx.drawImage( - tileSet, - TILE_X + WIDTH * currentFrame, - TILE_Y, - WIDTH, - HEIGHT, - 0, - 0, - WIDTH, - HEIGHT - ); - - currentFrame = currentFrame === ANIMATION_LENGTH ? 0 : currentFrame + 1; - }, 100); - }; - - return () => { - clearInterval(intervalId); - }; - }, [left, top]); + useAnimatedSprite({ + canvasRef, + left, + top, + tileSet: TILE_SETS.Objects, + width: WIDTH, + height: HEIGHT, + tileX: 0, + tileY: 128, + animationLength: 3, + animationSpeed: 100, + }); return ( = ({ left, top }) => { const canvasRef = useRef(null); - useEffect(() => { - const ctx = canvasRef.current?.getContext("2d"); - let intervalId: number; - - if (!canvasRef.current || !ctx) { - return; - } - - canvasRef.current.style.left = `${left}px`; - canvasRef.current.style.top = `${top}px`; - - const tileSet = new Image(); - tileSet.src = TILE_SETS.Objects; - tileSet.onload = () => { - let currentFrame = 0; - - intervalId = window.setInterval(() => { - ctx.clearRect(0, 0, WIDTH, HEIGHT); - - ctx.drawImage( - tileSet, - TILE_X + WIDTH * currentFrame, - TILE_Y, - WIDTH, - HEIGHT, - 0, - 0, - WIDTH, - HEIGHT - ); - - currentFrame = currentFrame === ANIMATION_LENGTH ? 0 : currentFrame + 1; - }, 125); - }; - - return () => { - clearInterval(intervalId); - }; - }, [left, top]); + useAnimatedSprite({ + canvasRef, + left, + top, + tileSet: TILE_SETS.Objects, + width: WIDTH, + height: HEIGHT, + tileX: 130, + tileY: 98, + animationLength: 6, + animationSpeed: 125, + }); return ( = ({ left, top }) => { const canvasRef = useRef(null); - useEffect(() => { - const ctx = canvasRef.current?.getContext("2d"); - let intervalId: number; - - if (!canvasRef.current || !ctx) { - return; - } - canvasRef.current.style.left = `${left}px`; - canvasRef.current.style.top = `${top}px`; - - const tileSet = new Image(); - tileSet.src = TILE_SETS.Objects; - tileSet.onload = () => { - let currentFrame = 0; - - intervalId = window.setInterval(() => { - ctx.clearRect(0, 0, WIDTH, HEIGHT); - - ctx.drawImage( - tileSet, - TILE_X + WIDTH * currentFrame, - TILE_Y, - WIDTH, - HEIGHT, - 0, - 0, - WIDTH, - HEIGHT - ); - - currentFrame = currentFrame === ANIMATION_LENGTH ? 0 : currentFrame + 1; - }, 75); - }; - - return () => { - clearInterval(intervalId); - }; - }, [left, top]); + useAnimatedSprite({ + canvasRef, + left, + top, + tileSet: TILE_SETS.Objects, + width: WIDTH, + height: HEIGHT, + tileX: 0, + tileY: 96, + animationLength: 3, + animationSpeed: 75, + }); return ( = ({ left, top }) => { const canvasRef = useRef(null); - useEffect(() => { - const ctx = canvasRef.current?.getContext("2d"); - - if (!canvasRef.current || !ctx) { - return; - } - - canvasRef.current.style.left = `${left}px`; - canvasRef.current.style.top = `${top}px`; - - const tileSet = new Image(); - tileSet.src = TILE_SETS.World; - tileSet.onload = () => { - ctx.drawImage( - tileSet, - TILE_X, - TILE_Y, - WIDTH, - HEIGHT, - 0, - 0, - WIDTH, - HEIGHT - ); - }; - }, [left, top]); + useSprite({ + canvasRef, + left, + top, + tileSet: TILE_SETS.World, + width: WIDTH, + height: HEIGHT, + tileX: 198, + tileY: 0, + }); return ( boolean)) => void; }; -/* - * TODO: - * - util function for tile set, tiles and animation - */ const Lever: FC = ({ left, top, used, onInteract }) => { const canvasRef = useRef(null); - useEffect(() => { - const ctx = canvasRef.current?.getContext("2d"); - - if (!canvasRef.current || !ctx) { - return; - } - - canvasRef.current.style.left = `${left}px`; - canvasRef.current.style.top = `${top}px`; - - const tileSet = new Image(); - tileSet.src = TILE_SETS.Objects; - tileSet.onload = () => { - ctx.clearRect(0, 0, WIDTH, HEIGHT); - onInteract(used); - - ctx.drawImage( - tileSet, - used ? TILE_X + WIDTH : TILE_X, - TILE_Y, - WIDTH, - HEIGHT, - 0, - 0, - WIDTH, - HEIGHT - ); - }; - }, [left, top, used, onInteract]); + useSprite({ + canvasRef, + left, + top, + tileSet: TILE_SETS.Objects, + width: WIDTH, + height: HEIGHT, + tileX: used ? TILE_X + WIDTH : TILE_X, + tileY: 288, + }); + + onInteract(used); return ( { + useEffect(() => { + const ctx = props.canvasRef.current?.getContext("2d"); + let intervalId: number; + + if (!props.canvasRef.current || !ctx) { + return; + } + + props.canvasRef.current.style.left = `${props.left}px`; + props.canvasRef.current.style.top = `${props.top}px`; + + const sprite = new Image(); + sprite.src = props.tileSet; + sprite.onload = () => { + let currentFrame = 0; + + intervalId = window.setInterval(() => { + ctx.clearRect(0, 0, props.width, props.height); + + ctx.drawImage( + sprite, + props.tileX + props.width * currentFrame, + props.tileY, + props.width, + props.height, + 0, + 0, + props.width, + props.height + ); + + currentFrame = + currentFrame === props.animationLength ? 0 : currentFrame + 1; + }, props.animationSpeed); + }; + + return () => { + clearInterval(intervalId); + }; + }, [props]); +}; diff --git a/src/hooks/useSprite.ts b/src/hooks/useSprite.ts new file mode 100644 index 0000000..d1a6397 --- /dev/null +++ b/src/hooks/useSprite.ts @@ -0,0 +1,44 @@ +import { useEffect, RefObject } from "react"; +import { TILE_SETS } from "../constants"; + +export type SpriteProps = { + canvasRef: RefObject; + tileSet: TILE_SETS; + width: number; + height: number; + tileX: number; + tileY: number; + left: number; + top: number; +}; + +export const useSprite = (props: SpriteProps) => { + useEffect(() => { + const ctx = props.canvasRef.current?.getContext("2d"); + + if (!props.canvasRef.current || !ctx) { + return; + } + + props.canvasRef.current.style.left = `${props.left}px`; + props.canvasRef.current.style.top = `${props.top}px`; + + const sprite = new Image(); + sprite.src = props.tileSet; + sprite.onload = () => { + ctx.clearRect(0, 0, props.width, props.height); + + ctx.drawImage( + sprite, + props.tileX, + props.tileY, + props.width, + props.height, + 0, + 0, + props.width, + props.height + ); + }; + }, [props]); +};