72 lines
3.0 KiB
TypeScript
72 lines
3.0 KiB
TypeScript
import { Canvas, useFrame, useThree } from '@react-three/fiber';
|
|
import { KeyboardControls, Stats } from '@react-three/drei';
|
|
import { action } from 'mobx';
|
|
import { chartRef } from './chartRef';
|
|
|
|
function RenderInfoUpdater() {
|
|
const { gl } = useThree();
|
|
useFrame(action(() => {
|
|
const { calls, triangles } = gl.info.render;
|
|
const shaders = gl.info.programs?.length ?? 0;
|
|
const { geometries, textures } = gl.info.memory;
|
|
state.setRenderInfo({
|
|
calls,
|
|
triangles,
|
|
shaders,
|
|
geometries,
|
|
textures,
|
|
});
|
|
}));
|
|
return null;
|
|
}
|
|
|
|
import { observer } from 'mobx-react-lite';
|
|
import { state } from '../state';
|
|
import { GameView } from './GameView';
|
|
import { SceneEditorView } from './SceneEditorView';
|
|
import { JoystickView } from './JoystickView';
|
|
import type { RefObject } from 'react';
|
|
|
|
const IconStop = () => <svg viewBox="0 0 14 14"><rect x="2" y="2" width="10" height="10" fill="currentColor" /></svg>;
|
|
const IconPause = () => <svg viewBox="0 0 14 14"><rect x="2" y="2" width="4" height="10" fill="currentColor" /><rect x="8" y="2" width="4" height="10" fill="currentColor" /></svg >;
|
|
const IconPlay = () => <svg viewBox="0 0 14 14"><polygon points="3,1 13,7 3,13" fill="currentColor" /></svg>;
|
|
|
|
export const ThreeView = observer(function () {
|
|
const isGame = state.isGamePlaying;
|
|
return (
|
|
<KeyboardControls map={[
|
|
{ name: 'forward', keys: ['ArrowUp', 'w', 'W'] },
|
|
{ name: 'backward', keys: ['ArrowDown', 's', 'S'] },
|
|
{ name: 'left', keys: ['ArrowLeft', 'a', 'A'] },
|
|
{ name: 'right', keys: ['ArrowRight', 'd', 'D'] },
|
|
{ name: 'jump', keys: ['Space'] },
|
|
]}>
|
|
<div style={{ position: 'fixed', inset: 0, overflow: 'hidden' }}>
|
|
<Canvas
|
|
// camera={state.world.character.camera}
|
|
onPointerMissed={() => state.worldEditor.resetSelection()}
|
|
>
|
|
<Stats parent={chartRef as RefObject<HTMLElement>} />
|
|
<RenderInfoUpdater />
|
|
{isGame ? <GameView /> : <SceneEditorView />}
|
|
</Canvas>
|
|
{isGame && <JoystickView />}
|
|
<div style={{ position: 'absolute', top: 8, right: 8, display: 'flex', gap: 4 }}>
|
|
{
|
|
state.game
|
|
? <>
|
|
<button onClick={() => state.stopGame()}><IconStop /></button>
|
|
{
|
|
state.game!.isPaused
|
|
? <button onClick={() => state.game!.resume()}><IconPlay /></button>
|
|
: <button onClick={() => state.game!.pause()}><IconPause /></button>
|
|
}
|
|
</>
|
|
: <button onClick={() => state.startGame()}><IconPlay /></button>
|
|
}
|
|
</div>
|
|
</div>
|
|
</KeyboardControls>
|
|
)
|
|
});
|