mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: start on visualizer
This commit is contained in:
1 parent
cda83639b2
commit
00e89cff55
2 files changed
+97
No files matched your search
+95
@@ -0,0 +1,95 @@
|
|||||||
|
import { Button, Card, Code, Flex, Switch, Text } from '@radix-ui/themes';
|
||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
import type { TankCharacteristics } from '../../../../../../core/blitzkit/tankCharacteristics';
|
||||||
|
|
||||||
|
interface DispersionVisualizerProps {
|
||||||
|
stats: TankCharacteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshRate = 1000 / 60; // ms
|
||||||
|
|
||||||
|
export function DispersionVisualizer({ stats }: DispersionVisualizerProps) {
|
||||||
|
const aInfinity = stats.dispersion;
|
||||||
|
const tau = stats.aimTime;
|
||||||
|
const timeText = useRef<HTMLElement>(null);
|
||||||
|
const aText = useRef<HTMLElement>(null);
|
||||||
|
const [a0, setA0] = useState(stats.dispersionMoving);
|
||||||
|
const [stateDiscriminator, setStateDiscriminator] = useState(0);
|
||||||
|
const [gunBroken, setGunBroken] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let t = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (!timeText.current || !aText.current) return;
|
||||||
|
|
||||||
|
t += refreshRate / 1000; // ms -> s
|
||||||
|
const a = aInfinity + a0 * Math.exp(-t / tau);
|
||||||
|
|
||||||
|
timeText.current.innerText = `t = ${t.toFixed(1)}s`;
|
||||||
|
aText.current.innerText = `a = ${a.toFixed(3)}m`;
|
||||||
|
}, refreshRate);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
|
}, [aInfinity, tau, a0]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Flex direction="column" gap="4">
|
||||||
|
<Flex gap="2" wrap="wrap">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
setA0(stats.dispersionMoving);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Move
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
setA0(stats.dispersionHullTraversing);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Hull traverse
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
setA0(stats.dispersionTurretTraversing);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Turret traverse
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
setA0(stats.dispersion + stats.dispersionShooting);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Shoot
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex align="center" gap="2">
|
||||||
|
<Switch
|
||||||
|
checked={gunBroken}
|
||||||
|
onCheckedChange={(checked) => setGunBroken(checked as boolean)}
|
||||||
|
/>
|
||||||
|
<Text>Gun broken</Text>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex justify="between">
|
||||||
|
<Code color="gray" ref={timeText}>
|
||||||
|
t = 0s
|
||||||
|
</Code>
|
||||||
|
|
||||||
|
<Code color="gray" ref={aText}>
|
||||||
|
a = {(aInfinity + a0).toFixed(3)}m
|
||||||
|
</Code>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
+2
@@ -30,6 +30,7 @@ import { useEquipment } from '../../../../../hooks/useEquipment';
|
|||||||
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
|
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
|
||||||
import { Duel } from '../../../../../stores/duel';
|
import { Duel } from '../../../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
||||||
|
import { DispersionVisualizer } from './components/DispersionVisualizer';
|
||||||
import { Info } from './components/Info';
|
import { Info } from './components/Info';
|
||||||
import { InfoWithDelta } from './components/InfoWithDelta';
|
import { InfoWithDelta } from './components/InfoWithDelta';
|
||||||
|
|
||||||
@@ -397,6 +398,7 @@ export function Characteristics() {
|
|||||||
value="aimTime"
|
value="aimTime"
|
||||||
/>
|
/>
|
||||||
<Info name="Dispersion at 100m" />
|
<Info name="Dispersion at 100m" />
|
||||||
|
<DispersionVisualizer stats={stats} />
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
stats={stats}
|
stats={stats}
|
||||||
decimals={3}
|
decimals={3}
|
||||||
|
|||||||
Reference in new issue
Block a user