perf: entity rendering
This commit is contained in:
parent
354b013e70
commit
a208863823
|
@ -2,7 +2,6 @@ import {Container} from '@pixi/react';
|
|||
import {useEffect, useState} from 'react';
|
||||
|
||||
import {RESOLUTION} from '@/constants.js';
|
||||
import {usePacket} from '@/context/client.js';
|
||||
import {useEcs, useEcsTick} from '@/context/ecs.js';
|
||||
import {useMainEntity} from '@/context/main-entity.js';
|
||||
|
||||
|
@ -30,11 +29,15 @@ function calculateDarkness(hour) {
|
|||
|
||||
export default function Ecs({applyFilters, scale}) {
|
||||
const [ecs] = useEcs();
|
||||
const [entities, setEntities] = useState({});
|
||||
const [filters, setFilters] = useState([]);
|
||||
const [mainEntity] = useMainEntity();
|
||||
const [camera, setCamera] = useState({x: 0, y: 0});
|
||||
const [layers, setLayers] = useState([]);
|
||||
const [hour, setHour] = useState(10);
|
||||
const [night, setNight] = useState();
|
||||
const [projected, setProjected] = useState([]);
|
||||
const [position, setPosition] = useState({x: 0, y: 0});
|
||||
const [water, setWater] = useState();
|
||||
useEffect(() => {
|
||||
async function buildNightFilter() {
|
||||
const {ColorMatrixFilter} = await import('@pixi/filter-color-matrix');
|
||||
|
@ -62,101 +65,89 @@ export default function Ecs({applyFilters, scale}) {
|
|||
night.setIntensity(calculateDarkness(hour));
|
||||
}
|
||||
}, [hour, night]);
|
||||
usePacket('EcsChange', async () => {
|
||||
setEntities({});
|
||||
}, [setEntities]);
|
||||
useEcsTick((payload) => {
|
||||
if (!ecs) {
|
||||
return;
|
||||
}
|
||||
const updatedEntities = {...entities};
|
||||
const entity = ecs.get(mainEntity);
|
||||
for (const id in payload) {
|
||||
const update = payload[id];
|
||||
if (false === update) {
|
||||
delete updatedEntities[id];
|
||||
}
|
||||
else {
|
||||
if ('1' === id) {
|
||||
switch (id) {
|
||||
case '1': {
|
||||
const master = ecs.get(1);
|
||||
if (update.TileLayers) {
|
||||
setLayers(Object.values(master.TileLayers.$$layersProxies));
|
||||
}
|
||||
if (update.Time) {
|
||||
setHour(Math.round(ecs.get(1).Time.hour * 60) / 60);
|
||||
}
|
||||
if (update.Water) {
|
||||
setWater(master.Water.water);
|
||||
}
|
||||
break;
|
||||
}
|
||||
updatedEntities[id] = ecs.get(id);
|
||||
if (update.Emitter?.emit) {
|
||||
updatedEntities[id].Emitter.emitting = {
|
||||
...updatedEntities[id].Emitter.emitting,
|
||||
...update.Emitter.emit,
|
||||
};
|
||||
case mainEntity: {
|
||||
const {Camera} = entity;
|
||||
setCamera({
|
||||
x: Math.round((Camera.x * scale) - RESOLUTION.x / 2),
|
||||
y: Math.round((Camera.y * scale) - RESOLUTION.y / 2),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setEntities(updatedEntities);
|
||||
}, [ecs, entities, mainEntity]);
|
||||
if (entity) {
|
||||
const {Direction, Position, Wielder} = entity;
|
||||
setPosition(Position.toJSON());
|
||||
setProjected(Wielder.activeItem()?.project(Position.tile, Direction.direction));
|
||||
}
|
||||
}, [ecs, mainEntity, scale]);
|
||||
useEffect(() => {
|
||||
setFilters(
|
||||
applyFilters
|
||||
? [night]
|
||||
? [
|
||||
...(night ? [night] : [])
|
||||
]
|
||||
: [],
|
||||
);
|
||||
}, [applyFilters, night])
|
||||
if (!ecs || !mainEntity) {
|
||||
return false;
|
||||
}
|
||||
const entity = ecs.get(mainEntity);
|
||||
if (!entity) {
|
||||
return false;
|
||||
}
|
||||
const {Direction, Position, Wielder} = entity;
|
||||
const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction)
|
||||
const {Camera} = entity;
|
||||
const {TileLayers, Water: WaterEcs} = ecs.get(1);
|
||||
const layer0 = TileLayers.layer(0);
|
||||
const layer1 = TileLayers.layer(1);
|
||||
const [cx, cy] = [
|
||||
Math.round((Camera.x * scale) - RESOLUTION.x / 2),
|
||||
Math.round((Camera.y * scale) - RESOLUTION.y / 2),
|
||||
];
|
||||
return (
|
||||
<Container
|
||||
scale={scale}
|
||||
x={-cx}
|
||||
y={-cy}
|
||||
x={-camera.x}
|
||||
y={-camera.y}
|
||||
>
|
||||
<Container
|
||||
filters={filters}
|
||||
>
|
||||
<TileLayer
|
||||
filters={filters}
|
||||
tileLayer={layer0}
|
||||
/>
|
||||
{layer1 && (
|
||||
{layers.map((layer, i) => (
|
||||
<TileLayer
|
||||
filters={filters}
|
||||
tileLayer={layer1}
|
||||
key={i}
|
||||
tileLayer={layer}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
</Container>
|
||||
{WaterEcs && (
|
||||
{water && layers[0] && (
|
||||
<Water
|
||||
tileLayer={layer0}
|
||||
water={WaterEcs.water}
|
||||
tileLayer={layers[0]}
|
||||
water={water}
|
||||
/>
|
||||
)}
|
||||
{projected && (
|
||||
{projected && layers[0] && (
|
||||
<TargetingGrid
|
||||
tileLayer={layer0}
|
||||
x={Position.x}
|
||||
y={Position.y}
|
||||
tileLayer={layers[0]}
|
||||
x={position.x}
|
||||
y={position.y}
|
||||
/>
|
||||
)}
|
||||
<Entities
|
||||
entities={entities}
|
||||
filters={filters}
|
||||
/>
|
||||
{projected?.length > 0 && (
|
||||
{projected?.length > 0 && layers[0] && (
|
||||
<TargetingGhost
|
||||
projected={projected}
|
||||
tileLayer={layer0}
|
||||
tileLayer={layers[0]}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
|
|
|
@ -3,13 +3,15 @@ import {GlowFilter} from '@pixi/filter-glow';
|
|||
import {Container} from '@pixi/react';
|
||||
import {useEffect, useState} from 'react';
|
||||
|
||||
import {useEcs} from '@/context/ecs.js';
|
||||
import {usePacket} from '@/context/client.js';
|
||||
import {useEcs, useEcsTick} from '@/context/ecs.js';
|
||||
import {useMainEntity} from '@/context/main-entity.js';
|
||||
|
||||
import Entity from './entity.jsx';
|
||||
|
||||
export default function Entities({entities, filters}) {
|
||||
export default function Entities({filters}) {
|
||||
const [ecs] = useEcs();
|
||||
const [entities, setEntities] = useState({});
|
||||
const [mainEntity] = useMainEntity();
|
||||
const [radians, setRadians] = useState(0);
|
||||
const [willInteractWith, setWillInteractWith] = useState(0);
|
||||
|
@ -17,6 +19,37 @@ export default function Entities({entities, filters}) {
|
|||
const pulse = (Math.cos(radians) + 1) * 0.5;
|
||||
interactionFilters[0].brightness = (pulse * 0.75) + 1;
|
||||
interactionFilters[1].outerStrength = pulse * 0.5;
|
||||
usePacket('EcsChange', async () => {
|
||||
setEntities({});
|
||||
}, [setEntities]);
|
||||
useEcsTick((payload) => {
|
||||
if (!ecs) {
|
||||
return;
|
||||
}
|
||||
const updatedEntities = {...entities};
|
||||
for (const id in payload) {
|
||||
const update = payload[id];
|
||||
if (false === update) {
|
||||
delete updatedEntities[id];
|
||||
}
|
||||
else {
|
||||
if ('1' !== id) {
|
||||
updatedEntities[id] = ecs.get(id);
|
||||
if (update.Emitter?.emit) {
|
||||
updatedEntities[id].Emitter.emitting = {
|
||||
...updatedEntities[id].Emitter.emitting,
|
||||
...update.Emitter.emit,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setEntities(updatedEntities);
|
||||
const main = ecs.get(mainEntity);
|
||||
if (main) {
|
||||
setWillInteractWith(main.Interacts.willInteractWith);
|
||||
}
|
||||
}, [ecs, entities, mainEntity]);
|
||||
useEffect(() => {
|
||||
setRadians(0);
|
||||
const handle = setInterval(() => {
|
||||
|
@ -26,17 +59,8 @@ export default function Entities({entities, filters}) {
|
|||
clearInterval(handle);
|
||||
};
|
||||
}, [willInteractWith]);
|
||||
useEffect(() => {
|
||||
if (!mainEntity) {
|
||||
return;
|
||||
}
|
||||
setWillInteractWith(ecs.get(mainEntity).Interacts.willInteractWith);
|
||||
}, [entities, ecs, mainEntity]);
|
||||
const renderables = [];
|
||||
for (const id in entities) {
|
||||
if ('1' === id) {
|
||||
continue;
|
||||
}
|
||||
const isHighlightedInteraction = id == willInteractWith;
|
||||
renderables.push(
|
||||
<Entity
|
||||
|
|
Loading…
Reference in New Issue
Block a user