Feat/env-manager #1

Merged
math-pixel merged 46 commits from feat/env-manager into develop 2026-05-11 15:23:32 +00:00
3 changed files with 76 additions and 0 deletions
Showing only changes of commit 7cf622d787 - Show all commits
+2
View File
@@ -3,6 +3,7 @@ import { DebugOverlayLayout } from "@/components/ui/debug/DebugOverlayLayout";
import { GameSettingsMenu } from "@/components/ui/GameSettingsMenu"; import { GameSettingsMenu } from "@/components/ui/GameSettingsMenu";
import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer"; import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer";
import { InteractPrompt } from "@/components/ui/InteractPrompt"; import { InteractPrompt } from "@/components/ui/InteractPrompt";
import { Subtitles } from "@/components/ui/Subtitles";
export function GameUI(): React.JSX.Element { export function GameUI(): React.JSX.Element {
return ( return (
@@ -11,6 +12,7 @@ export function GameUI(): React.JSX.Element {
<Crosshair /> <Crosshair />
<InteractPrompt /> <InteractPrompt />
<HandTrackingVisualizer /> <HandTrackingVisualizer />
<Subtitles />
<GameSettingsMenu /> <GameSettingsMenu />
</> </>
); );
+33
View File
@@ -0,0 +1,33 @@
import { useSettingsStore } from "@/managers/stores/useSettingsStore";
export type SubtitleSpeaker = "Narrateur" | "Fermier" | "Leonie";
interface SubtitlesProps {
speaker?: SubtitleSpeaker | null;
text?: string | null;
}
export function Subtitles({
speaker = null,
text = null,
}: SubtitlesProps): React.JSX.Element | null {
const subtitlesEnabled = useSettingsStore((state) => state.subtitlesEnabled);
const content = text?.trim();
if (!subtitlesEnabled || !content) return null;
return (
<div className="subtitles" aria-live="polite">
<p>
{speaker ? (
<span
className={`subtitles__speaker subtitles__speaker--${speaker.toLowerCase()}`}
>
{speaker}:
</span>
) : null}
{content}
</p>
</div>
);
}
+41
View File
@@ -397,6 +397,47 @@ canvas {
letter-spacing: 0.03em; letter-spacing: 0.03em;
} }
/* Subtitles */
.subtitles {
position: fixed;
left: 50%;
bottom: 7vh;
z-index: 15;
width: min(780px, calc(100vw - 32px));
transform: translateX(-50%);
pointer-events: none;
}
.subtitles p {
margin: 0;
padding: 12px 16px;
border-radius: 10px;
background: rgba(0, 0, 0, 0.82);
color: #ffffff;
font-size: clamp(1rem, 2vw, 1.25rem);
font-weight: 650;
line-height: 1.45;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}
.subtitles__speaker {
margin-right: 0.35em;
font-weight: 800;
}
.subtitles__speaker--narrateur {
color: #7dd3fc;
}
.subtitles__speaker--fermier {
color: #86efac;
}
.subtitles__speaker--leonie {
color: #f9a8d4;
}
/* In-game settings menu */ /* In-game settings menu */
.game-settings-menu { .game-settings-menu {
position: fixed; position: fixed;