From 904e7fcb1ab3df48123a42f89ba262b0a11d4388 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 26 Nov 2023 23:18:25 +0800 Subject: [PATCH] :recycle: Better cooldown system --- src/stage/index.tsx | 18 +++++++--- src/stage/objects/player.tsx | 24 +++---------- src/stage/providers/cooldown.tsx | 58 ++++++++++++++++++++++++++++++++ src/stage/ui/cooldown.tsx | 33 ++++++++++++++++++ 4 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 src/stage/providers/cooldown.tsx create mode 100644 src/stage/ui/cooldown.tsx diff --git a/src/stage/index.tsx b/src/stage/index.tsx index 333ec41..05dfdd8 100644 --- a/src/stage/index.tsx +++ b/src/stage/index.tsx @@ -3,6 +3,8 @@ import { Show, createSignal, onMount } from "solid-js"; import { vector2d } from "./vector"; import Player from "./objects/player"; +import CooldownProvider from "./providers/cooldown"; +import CooldownUI from "./ui/cooldown"; const StageContainer = styled("div")` width: 100vw; @@ -32,10 +34,16 @@ export default function Stage() { onMount(() => movePlayer(container)); return ( - - - - - + + + + {/* Objects */} + + + {/* UI Elements */} + + + + ); } diff --git a/src/stage/objects/player.tsx b/src/stage/objects/player.tsx index aa51ebe..bb4c736 100644 --- a/src/stage/objects/player.tsx +++ b/src/stage/objects/player.tsx @@ -1,6 +1,7 @@ import { styled } from "solid-styled-components"; import { createSignal, onCleanup, onMount } from "solid-js"; import { vector2d } from "../vector"; +import { useCooldown } from "../providers/cooldown"; export default function Player(props: { size?: number; @@ -63,29 +64,19 @@ export default function Player(props: { // Skills - let cooldown: { [id: string]: number } = { - dash: 0, - }; - - function reduceCooldown(amount: number = 1) { - Object.keys(cooldown).forEach((k) => { - if (cooldown[k] > 0) { - cooldown[k] -= amount; - } - }); - } + const [cooldown, { freeze }] = useCooldown(); window.addEventListener("keydown", ({ key }) => { // Dash // Fast move from one place to another place // TL;DR Speed up player movement speed in a short time if (key == " " /* Spacebar */) { - if (cooldown.dash > 0) return; + if (cooldown()["player.skills.dash"] > 0) return; - const multiplier = 2 + const multiplier = 2; velocity.x *= multiplier; velocity.y *= multiplier; - cooldown.dash = 1; + freeze("player.skills.dash", 1000); setTimeout(() => { if (velocity.x > speed) velocity.x = speed; if (velocity.x < -speed) velocity.x = -speed; @@ -95,11 +86,6 @@ export default function Player(props: { } }); - onMount(() => { - const loop = setInterval(() => reduceCooldown(0.01), 10); - onCleanup(() => clearInterval(loop)); - }); - // Renderer const PlayerRenderer = styled("div")` diff --git a/src/stage/providers/cooldown.tsx b/src/stage/providers/cooldown.tsx new file mode 100644 index 0000000..bc561db --- /dev/null +++ b/src/stage/providers/cooldown.tsx @@ -0,0 +1,58 @@ +import { + createContext, + createSignal, + onCleanup, + onMount, + useContext, +} from "solid-js"; + +const CooldownContext = createContext(); + +export default function CooldownProvider(props: any) { + const [cooldown, setCooldown] = createSignal<{ [id: string]: number }>({}); + + const store = [ + cooldown, + { + freeze(id: string, duration: number) { + setCooldown((o) => { + o[id] = duration; + return o; + }); + }, + unfreeze(id: string) { + setCooldown((o) => { + o[id] = 0; + return o; + }); + }, + }, + ]; + + function reduceCooldown(amount: number = 1000) { + setCooldown((o) => { + Object.keys(o).forEach((k) => { + if (o[k] > 0) { + o[k] -= amount; + } + }); + + return o; + }); + } + + onMount(() => { + const loop = setInterval(() => reduceCooldown(10), 10); + onCleanup(() => clearInterval(loop)); + }); + + return ( + + {props.children} + + ); +} + +export function useCooldown(): any[2] { + return useContext(CooldownContext); +} diff --git a/src/stage/ui/cooldown.tsx b/src/stage/ui/cooldown.tsx new file mode 100644 index 0000000..5756beb --- /dev/null +++ b/src/stage/ui/cooldown.tsx @@ -0,0 +1,33 @@ +import { For, createSignal } from "solid-js"; +import { styled } from "solid-styled-components"; +import { useCooldown } from "../providers/cooldown"; + +export default function CooldownUI() { + const [cooldown] = useCooldown(); + const [stack, setStack] = createSignal([]); + + const UIContainer = styled("div")` + text-align: center; + position: absolute; + + width: 100vw; + bottom: 200px; + left: 0px; + `; + + setInterval(() => { + setStack(Object.entries(cooldown()).filter((v) => (v[1] as number) > 0)); + }, 10); + + return ( + + + {(item) => ( +
+ {item[0]} {[(item[1] as number) / 1000]}s +
+ )} +
+
+ ); +}