perf: updates
This commit is contained in:
parent
5492ec32bd
commit
73b7a9e0a5
|
@ -2,6 +2,7 @@ import {useCallback, useState} from 'react';
|
|||
|
||||
import {usePacket} from '@/react/context/client.js';
|
||||
import {useEcsTick} from '@/react/context/ecs.js';
|
||||
import {RESOLUTION} from '@/util/constants.js';
|
||||
import {parseLetters} from '@/util/dialogue.js';
|
||||
|
||||
import Damages from './damages.jsx';
|
||||
|
@ -14,6 +15,10 @@ export default function Entities({
|
|||
setChatMessages,
|
||||
}) {
|
||||
const [entities, setEntities] = useState({});
|
||||
const translatedCamera = {
|
||||
x: Math.round((camera.x * scale) - RESOLUTION.x / 2),
|
||||
y: Math.round((camera.y * scale) - RESOLUTION.y / 2),
|
||||
};
|
||||
usePacket('EcsChange', async () => {
|
||||
setEntities({});
|
||||
});
|
||||
|
@ -98,7 +103,7 @@ export default function Entities({
|
|||
for (const id in entities) {
|
||||
renderables.push(
|
||||
<Entity
|
||||
camera={camera}
|
||||
camera={translatedCamera}
|
||||
entity={entities[id]}
|
||||
key={id}
|
||||
scale={scale}
|
||||
|
@ -109,8 +114,8 @@ export default function Entities({
|
|||
<div
|
||||
style={{
|
||||
translate: `
|
||||
calc(-1px * ${camera.x})
|
||||
calc(-1px * ${camera.y})
|
||||
calc(-1px * ${translatedCamera.x})
|
||||
calc(-1px * ${translatedCamera.y})
|
||||
`,
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -10,7 +10,7 @@ import TargetingGrid from './targeting-grid.jsx';
|
|||
import TileLayer from './tile-layer.jsx';
|
||||
import Water from './water.jsx';
|
||||
|
||||
export default function Ecs({camera, monopolizers, particleWorker, scale}) {
|
||||
export default function Ecs({monopolizers, particleWorker}) {
|
||||
const app = useApp();
|
||||
const mainEntityRef = useMainEntity();
|
||||
const [layers, setLayers] = useState([]);
|
||||
|
@ -120,17 +120,22 @@ export default function Ecs({camera, monopolizers, particleWorker, scale}) {
|
|||
}
|
||||
if (entity) {
|
||||
const {Direction, Position, Wielder} = entity;
|
||||
setPosition(Position.toJSON());
|
||||
setProjected(Wielder.activeItem()?.project(Position.tile, Direction.quantize(4)));
|
||||
setPosition((position) => {
|
||||
return position.x !== Position.x || position.y !== Position.y
|
||||
? Position.toJSON()
|
||||
: position;
|
||||
});
|
||||
setProjected((projected) => {
|
||||
const newProjected = Wielder.activeItem()?.project(Position.tile, Direction.quantize(4));
|
||||
return JSON.stringify(projected) !== JSON.stringify(newProjected)
|
||||
? newProjected
|
||||
: projected;
|
||||
});
|
||||
}
|
||||
}, [app.ambientLight, mainEntityRef]);
|
||||
useEcsTick(onEcsTick);
|
||||
return (
|
||||
<Container
|
||||
scale={scale}
|
||||
x={-camera.x}
|
||||
y={-camera.y}
|
||||
>
|
||||
<>
|
||||
<Container>
|
||||
{layers.map((layer, i) => (
|
||||
<TileLayer
|
||||
|
@ -162,6 +167,6 @@ export default function Ecs({camera, monopolizers, particleWorker, scale}) {
|
|||
monopolizers={monopolizers}
|
||||
particleWorker={particleWorker}
|
||||
/>
|
||||
</Container>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import {SCALE_MODES} from '@pixi/constants';
|
||||
import {BaseTexture, extensions} from '@pixi/core';
|
||||
import {Stage as PixiStage} from '@pixi/react';
|
||||
import {createElement, useContext} from 'react';
|
||||
import {Container, Stage as PixiStage} from '@pixi/react';
|
||||
import {createElement, forwardRef, memo, useContext} from 'react';
|
||||
|
||||
import AssetsContext from '@/react/context/assets.js';
|
||||
import ClientContext from '@/react/context/client.js';
|
||||
import DebugContext from '@/react/context/debug.js';
|
||||
import EcsContext from '@/react/context/ecs.js';
|
||||
import MainEntityContext from '@/react/context/main-entity.js';
|
||||
import RadiansContext from '@/react/context/radians.js';
|
||||
import {RESOLUTION} from '@/util/constants.js';
|
||||
|
||||
import Ecs from './ecs.jsx';
|
||||
|
@ -28,7 +27,6 @@ const Contexts = [
|
|||
DebugContext,
|
||||
EcsContext,
|
||||
MainEntityContext,
|
||||
RadiansContext,
|
||||
];
|
||||
|
||||
const ContextBridge = ({children, render}) => {
|
||||
|
@ -57,7 +55,7 @@ export const Stage = ({children, ...props}) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default function Pixi({camera, monopolizers, particleWorker, scale}) {
|
||||
function Pixi({monopolizers, particleWorker}, ref) {
|
||||
return (
|
||||
<Stage
|
||||
className={styles.stage}
|
||||
|
@ -67,13 +65,16 @@ export default function Pixi({camera, monopolizers, particleWorker, scale}) {
|
|||
background: 0x0,
|
||||
}}
|
||||
>
|
||||
<Ecs
|
||||
camera={camera}
|
||||
monopolizers={monopolizers}
|
||||
particleWorker={particleWorker}
|
||||
scale={scale}
|
||||
/>
|
||||
<Container
|
||||
ref={ref}
|
||||
>
|
||||
<Ecs
|
||||
monopolizers={monopolizers}
|
||||
particleWorker={particleWorker}
|
||||
/>
|
||||
</Container>
|
||||
</Stage>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(forwardRef(Pixi));
|
||||
|
|
|
@ -36,6 +36,7 @@ function Ui({disconnected}) {
|
|||
const chatInputRef = useRef();
|
||||
const latestTick = useRef();
|
||||
const gameRef = useRef();
|
||||
const pixiRef = useRef();
|
||||
const mainEntityRef = useMainEntity();
|
||||
const [, setDebug] = useDebug();
|
||||
const ecsRef = useEcs();
|
||||
|
@ -326,16 +327,15 @@ function Ui({disconnected}) {
|
|||
}
|
||||
}, []);
|
||||
useEcsTick(onEcsTickAabbs);
|
||||
const onEcsTickCamera = useCallback((payload, ecs) => {
|
||||
if (mainEntityRef.current) {
|
||||
const mainEntityEntity = ecs.get(mainEntityRef.current);
|
||||
const x = Math.round((mainEntityEntity.Camera.x * scale) - RESOLUTION.x / 2);
|
||||
const y = Math.round((mainEntityEntity.Camera.y * scale) - RESOLUTION.y / 2);
|
||||
if (x !== camera.x || y !== camera.y) {
|
||||
setCamera({x, y});
|
||||
}
|
||||
const onEcsTickCamera = useCallback((payload) => {
|
||||
if (mainEntityRef.current && payload[mainEntityRef.current]?.Camera) {
|
||||
setCamera((camera) => ({
|
||||
x: camera.x,
|
||||
y: camera.y,
|
||||
...payload[mainEntityRef.current].Camera,
|
||||
}))
|
||||
}
|
||||
}, [camera, mainEntityRef, scale]);
|
||||
}, [mainEntityRef]);
|
||||
useEcsTick(onEcsTickCamera);
|
||||
useEffect(() => {
|
||||
function onContextMenu(event) {
|
||||
|
@ -389,6 +389,14 @@ function Ui({disconnected}) {
|
|||
payload: {type: 'swapSlots', value: [0, externalInventory, i]},
|
||||
});
|
||||
}, [client, externalInventory]);
|
||||
useEffect(() => {
|
||||
if (!pixiRef.current) {
|
||||
return;
|
||||
}
|
||||
pixiRef.current.scale.set(scale);
|
||||
pixiRef.current.x = -Math.round((camera.x * scale) - RESOLUTION.x / 2);
|
||||
pixiRef.current.y = -Math.round((camera.y * scale) - RESOLUTION.y / 2);
|
||||
}, [camera, scale])
|
||||
return (
|
||||
<div
|
||||
className={styles.ui}
|
||||
|
@ -494,10 +502,9 @@ function Ui({disconnected}) {
|
|||
ref={gameRef}
|
||||
>
|
||||
<Pixi
|
||||
camera={camera}
|
||||
monopolizers={monopolizers.current}
|
||||
particleWorker={particleWorker}
|
||||
scale={scale}
|
||||
ref={pixiRef}
|
||||
/>
|
||||
<Dom>
|
||||
<HotBar
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import {createContext, useContext} from 'react';
|
||||
import {useCallback, useState} from 'react';
|
||||
|
||||
const context = createContext();
|
||||
|
||||
export default context;
|
||||
import useAnimationFrame from '@/react/hooks/use-animation-frame.js';
|
||||
import {TAU} from '@/util/math.js';
|
||||
|
||||
export function useRadians() {
|
||||
return useContext(context);
|
||||
const [radians, setRadians] = useState(0);
|
||||
useAnimationFrame(
|
||||
useCallback((elapsed) => {
|
||||
setRadians((radians) => radians + (elapsed * TAU));
|
||||
}, []),
|
||||
);
|
||||
return radians;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,6 @@ import ClientContext from '@/react/context/client.js';
|
|||
import DebugContext from '@/react/context/debug.js';
|
||||
import EcsContext from '@/react/context/ecs.js';
|
||||
import MainEntityContext from '@/react/context/main-entity.js';
|
||||
import RadiansContext from '@/react/context/radians.js';
|
||||
import useAnimationFrame from '@/react/hooks/use-animation-frame.js';
|
||||
import {TAU} from '@/util/math.js';
|
||||
|
||||
import ClientEcs from '@/react/components/client-ecs.js';
|
||||
|
||||
|
@ -25,11 +22,6 @@ export default function PlaySpecific() {
|
|||
const [disconnected, setDisconnected] = useState(false);
|
||||
const params = useParams();
|
||||
const [type, url] = params['*'].split('/');
|
||||
const [radians, setRadians] = useState(0);
|
||||
const spin = useCallback((elapsed) => {
|
||||
setRadians((radians) => radians + (elapsed * TAU));
|
||||
}, []);
|
||||
useAnimationFrame(spin);
|
||||
useEffect(() => {
|
||||
if (!Client) {
|
||||
return;
|
||||
|
@ -174,9 +166,7 @@ export default function PlaySpecific() {
|
|||
<EcsContext.Provider value={ecsRef}>
|
||||
<DebugContext.Provider value={debugTuple}>
|
||||
<AssetsContext.Provider value={assetsTuple}>
|
||||
<RadiansContext.Provider value={radians}>
|
||||
<Ui disconnected={disconnected} />
|
||||
</RadiansContext.Provider>
|
||||
<Ui disconnected={disconnected} />
|
||||
</AssetsContext.Provider>
|
||||
</DebugContext.Provider>
|
||||
</EcsContext.Provider>
|
||||
|
|
Loading…
Reference in New Issue
Block a user