✨ Overlap detection
This commit is contained in:
parent
b42def99a0
commit
046f33b68e
@ -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;
|
||||
}
|
@ -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<HTMLElement>(".player");
|
||||
const crystal = document.querySelector<HTMLElement>(".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 (
|
||||
<CrystalElement
|
||||
class="crystal"
|
||||
class={`crystal ${isAlive() ? `crystal--powerful` : `crystal--powerless`}`}
|
||||
style={{
|
||||
left: `${x()}px`,
|
||||
top: `${y()}px`,
|
||||
@ -91,7 +115,7 @@ export default function Crystal(props: { size?: number; position?: vector2d }) {
|
||||
}}
|
||||
>
|
||||
<CrystalCircleInactive />
|
||||
<CrystalCircleActive />
|
||||
<CrystalCircleActive class="crystal--energy-indicator" />
|
||||
</CrystalElement>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user