silphius/app/react-components/targeting-ghost.jsx

65 lines
2.0 KiB
React
Raw Normal View History

2024-06-18 04:36:44 -05:00
import {Container} from '@pixi/display';
import {Graphics} from '@pixi/graphics';
2024-06-25 01:46:07 -05:00
import {PixiComponent} from '@pixi/react';
2024-06-18 04:36:44 -05:00
import {useEffect, useState} from 'react';
const tileSize = {x: 16, y: 16};
const TargetingGhostInternal = PixiComponent('TargetingGhost', {
2024-06-25 01:46:07 -05:00
create: () => {
// Solid target square.
2024-06-24 10:53:01 -05:00
const target = new Graphics();
2024-06-25 01:46:07 -05:00
target.lineStyle(1, 0xffffff);
target.drawRect(0.5, 0.5, tileSize.x, tileSize.y);
target.pivot = {x: tileSize.x / 2, y: tileSize.y / 2};
// Inner spinny part.
2024-06-24 10:53:01 -05:00
const targetInner = new Graphics();
targetInner.alpha = 0.6;
2024-06-25 01:46:07 -05:00
targetInner.lineStyle(3, 0x333333);
targetInner.beginFill(0xdddddd);
targetInner.pivot = {x: tileSize.x / 2, y: tileSize.y / 2};
targetInner.drawRect(0, 0, tileSize.x, tileSize.y);
targetInner.position.x = 0.5;
targetInner.position.y = 0.5;
// ...
2024-06-18 04:36:44 -05:00
const container = new Container();
2024-06-25 01:46:07 -05:00
container.addChild(target, targetInner);
2024-06-18 04:36:44 -05:00
return container;
},
2024-06-25 01:46:07 -05:00
applyProps: (container, oldProps, {x, y, radians}) => {
container.position.set(x, y);
container.children[1].rotation = radians / 4;
container.children[1].scale.set(0.3 + 0.2 * (Math.cos(radians) + 1));
2024-06-18 04:36:44 -05:00
},
})
2024-06-25 06:20:45 -05:00
export default function TargetingGhost({ecs, entity, projection}) {
2024-06-18 04:36:44 -05:00
const [radians, setRadians] = useState(0);
useEffect(() => {
const handle = setInterval(() => {
setRadians((radians) => (radians + 0.2) % (Math.PI * 2))
}, 50);
return () => {
clearInterval(handle);
};
}, []);
2024-06-25 06:20:45 -05:00
const {TileLayers: {layers: [layer]}} = ecs.get(1);
const {Position, Wielder} = entity;
const projected = Wielder.project(Position.tile, projection)
2024-06-25 01:46:07 -05:00
const ghosts = [];
2024-06-25 06:20:45 -05:00
for (const {x, y} of projected) {
if (x < 0 || y < 0 || x >= layer.area.x || y >= layer.area.y) {
continue;
2024-06-25 01:46:07 -05:00
}
2024-06-25 06:20:45 -05:00
ghosts.push(
<TargetingGhostInternal
key={JSON.stringify({x, y})}
x={x * tileSize.x + tileSize.x * 0.5}
y={y * tileSize.y + tileSize.y * 0.5}
radians={radians}
/>
);
2024-06-25 01:46:07 -05:00
}
return <>{ghosts}</>;
2024-06-18 04:36:44 -05:00
}