♻️ Better cooldown system
This commit is contained in:
		| @@ -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 ( | ||||
|     <CooldownProvider> | ||||
|       <StageContainer ref={container}> | ||||
|         <Show when={ready()}> | ||||
|           {/* Objects */} | ||||
|           <Player size={64} position={playerPosition} /> | ||||
|  | ||||
|           {/* UI Elements */} | ||||
|           <CooldownUI /> | ||||
|         </Show> | ||||
|       </StageContainer> | ||||
|     </CooldownProvider> | ||||
|   ); | ||||
| } | ||||
|   | ||||
| @@ -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")` | ||||
|   | ||||
							
								
								
									
										58
									
								
								src/stage/providers/cooldown.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/stage/providers/cooldown.tsx
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										33
									
								
								src/stage/ui/cooldown.tsx
									
									
									
									
									
										Normal 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> | ||||
|   ); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user