Overlap detection

This commit is contained in:
LittleSheep 2024-02-15 23:08:48 +08:00
parent b42def99a0
commit 046f33b68e
2 changed files with 42 additions and 10 deletions

View File

@ -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;
}

View File

@ -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>
);
}