♻️ Better cooldown system

This commit is contained in:
LittleSheep 2023-11-26 23:18:25 +08:00
parent 62ae1730fd
commit 904e7fcb1a
4 changed files with 109 additions and 24 deletions

View File

@ -3,6 +3,8 @@ import { Show, createSignal, onMount } from "solid-js";
import { vector2d } from "./vector"; import { vector2d } from "./vector";
import Player from "./objects/player"; import Player from "./objects/player";
import CooldownProvider from "./providers/cooldown";
import CooldownUI from "./ui/cooldown";
const StageContainer = styled("div")` const StageContainer = styled("div")`
width: 100vw; width: 100vw;
@ -32,10 +34,16 @@ export default function Stage() {
onMount(() => movePlayer(container)); onMount(() => movePlayer(container));
return ( return (
<CooldownProvider>
<StageContainer ref={container}> <StageContainer ref={container}>
<Show when={ready()}> <Show when={ready()}>
{/* Objects */}
<Player size={64} position={playerPosition} /> <Player size={64} position={playerPosition} />
{/* UI Elements */}
<CooldownUI />
</Show> </Show>
</StageContainer> </StageContainer>
</CooldownProvider>
); );
} }

View File

@ -1,6 +1,7 @@
import { styled } from "solid-styled-components"; import { styled } from "solid-styled-components";
import { createSignal, onCleanup, onMount } from "solid-js"; import { createSignal, onCleanup, onMount } from "solid-js";
import { vector2d } from "../vector"; import { vector2d } from "../vector";
import { useCooldown } from "../providers/cooldown";
export default function Player(props: { export default function Player(props: {
size?: number; size?: number;
@ -63,29 +64,19 @@ export default function Player(props: {
// Skills // Skills
let cooldown: { [id: string]: number } = { const [cooldown, { freeze }] = useCooldown();
dash: 0,
};
function reduceCooldown(amount: number = 1) {
Object.keys(cooldown).forEach((k) => {
if (cooldown[k] > 0) {
cooldown[k] -= amount;
}
});
}
window.addEventListener("keydown", ({ key }) => { window.addEventListener("keydown", ({ key }) => {
// Dash // Dash
// Fast move from one place to another place // Fast move from one place to another place
// TL;DR Speed up player movement speed in a short time // TL;DR Speed up player movement speed in a short time
if (key == " " /* Spacebar */) { 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.x *= multiplier;
velocity.y *= multiplier; velocity.y *= multiplier;
cooldown.dash = 1; freeze("player.skills.dash", 1000);
setTimeout(() => { setTimeout(() => {
if (velocity.x > speed) velocity.x = speed; if (velocity.x > speed) velocity.x = speed;
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 // Renderer
const PlayerRenderer = styled("div")` const PlayerRenderer = styled("div")`

View File

@ -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 (
<CooldownContext.Provider value={store}>
{props.children}
</CooldownContext.Provider>
);
}
export function useCooldown(): any[2] {
return useContext(CooldownContext);
}

33
src/stage/ui/cooldown.tsx Normal file
View File

@ -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<any[]>([]);
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 (
<UIContainer>
<For each={stack()}>
{(item) => (
<div>
{item[0]} {[(item[1] as number) / 1000]}s
</div>
)}
</For>
</UIContainer>
);
}