diff --git a/src/stage/objects/crystal.css b/src/stage/objects/crystal.css index 64f0a1a..67f9b58 100644 --- a/src/stage/objects/crystal.css +++ b/src/stage/objects/crystal.css @@ -6,3 +6,11 @@ transform: rotate(calc(90deg + 360deg * var(--rotation-factor))); } } + +.crystal--energy-indicator { + stroke-opacity: 1; +} + +.crystal--powerless .crystal--energy-indicator { + stroke-opacity: 0; +} \ No newline at end of file diff --git a/src/stage/objects/crystal.tsx b/src/stage/objects/crystal.tsx index 3379d99..3810ff0 100644 --- a/src/stage/objects/crystal.tsx +++ b/src/stage/objects/crystal.tsx @@ -1,6 +1,8 @@ import { styled } from "solid-styled-components"; import { vector2d } from "../vector"; -import { createMemo, createSignal, onCleanup, onMount } from "solid-js"; +import { createMemo, createSignal } from "solid-js"; +import { useTimer } from "../providers/timer"; +import { checkElementOverlap } from "./collision"; import "./crystal.css"; @@ -23,14 +25,35 @@ export default function Crystal(props: { size?: number; position?: vector2d }) { const rechargeProgress = createMemo(() => (energy() / maxEnergy()) * 100); - function updateEnergy() { - setEnergy(energy() - 1); + const isAlive = createMemo(() => energy() > 0); + + function checkAnyPlayerUnderCrystal() { + const players = document.querySelectorAll(".player"); + const crystal = document.querySelector(".crystal"); + + for (const player of players) { + if (crystal && checkElementOverlap(crystal, player)) { + return true; + } + } + return false; } - onMount(() => { - const loop = setInterval(() => updateEnergy(), 100); - onCleanup(() => clearInterval(loop)); - }); + function updateEnergy() { + const doRecharge = checkAnyPlayerUnderCrystal(); + if (doRecharge) { + if (energy() < maxEnergy()) { + setEnergy(energy() + 1); + } + } else { + if (energy() > 0) { + setEnergy(energy() - 1); + } + } + } + + const [{ subscribe }] = useTimer(); + subscribe(() => updateEnergy()); // Renderer @@ -61,9 +84,10 @@ export default function Crystal(props: { size?: number; position?: vector2d }) { stroke-linecap: round; animation: alternate 10s crystal--fill-wabble infinite ease-in-out; + transform-origin: var(--half-size) var(--half-size); stroke-dasharray: var(--dash) calc(var(--circumference) - var(--dash)); - transition: stroke-dasharray 0.3s linear 0s; + transition: all 0.3s linear 0s; stroke: var(--color-primary); `; @@ -80,7 +104,7 @@ export default function Crystal(props: { size?: number; position?: vector2d }) { return ( - + ); }