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 01:46:07 -05:00
|
|
|
export default function TargetingGhost({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 01:46:07 -05:00
|
|
|
const {Direction: {direction}, Position: {x, y}} = entity;
|
|
|
|
const tileX = x - (x % tileSize.x);
|
|
|
|
const tileY = y - (y % tileSize.y);
|
|
|
|
let startX = tileX + (tileSize.x / 2);
|
|
|
|
let startY = tileY + (tileSize.y / 2);
|
|
|
|
switch (direction) {
|
|
|
|
case 0:
|
|
|
|
startX += projection.distance[1] * tileSize.x;
|
|
|
|
startY -= projection.distance[0] * tileSize.y;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
startX += projection.distance[0] * tileSize.x;
|
|
|
|
startY += projection.distance[1] * tileSize.y;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
startX -= projection.distance[1] * tileSize.x;
|
|
|
|
startY += projection.distance[0] * tileSize.y;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
startX -= projection.distance[0] * tileSize.x;
|
|
|
|
startY -= projection.distance[1] * tileSize.y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
const ghosts = [];
|
|
|
|
for (const row in projection.grid) {
|
|
|
|
const columns = projection.grid[row];
|
|
|
|
for (const column in columns) {
|
|
|
|
const targeted = projection.grid[row][column];
|
|
|
|
if (targeted) {
|
|
|
|
let axe;
|
|
|
|
switch (direction) {
|
|
|
|
case 0:
|
|
|
|
axe = [column, row];
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
axe = [-row, column];
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
axe = [-column, -row];
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
axe = [row, -column];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ghosts.push(
|
|
|
|
<TargetingGhostInternal
|
|
|
|
key={JSON.stringify({column, row})}
|
|
|
|
x={startX + (tileSize.x * parseInt(axe[0]))}
|
|
|
|
y={startY + (tileSize.y * parseInt(axe[1]))}
|
|
|
|
radians={radians}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return <>{ghosts}</>;
|
2024-06-18 04:36:44 -05:00
|
|
|
}
|