"use client"; import { useMemo, useEffect, Suspense, useState } from "react"; import { Canvas } from "@react-three/fiber"; import { Physics } from "@react-three/rapier"; import { ThreeRenderer } from "@json-render/react-three-fiber"; import { Braces, SlidersHorizontal, X } from "lucide-react"; import { useEditorStore } from "@/lib/store"; import { useIsMobile } from "@/lib/use-mobile"; import { registry } from "@/lib/registry"; import { sceneToSpec } from "@/lib/scene-to-spec"; import { Toolbar } from "@/components/editor/toolbar"; import { SceneInspector } from "@/components/editor/scene-inspector"; import { AddObjectButton } from "@/components/editor/add-object-button"; import { EditorControls } from "@/components/editor/transform-controls"; import { JsonPane } from "@/components/editor/json-pane"; import { AIPrompt } from "@/components/editor/ai-prompt"; import { HealthBar } from "@/components/hud/health-bar"; import { DamageEffect } from "@/components/hud/damage-effect"; import { GameOverScreen } from "@/components/hud/game-over"; import { CharacterDialog } from "@/components/hud/character-dialog"; import { InteractionPrompt } from "@/components/hud/interaction-prompt"; import { InGamePrompt } from "@/components/hud/in-game-prompt"; import { DamageSound } from "@/components/hud/damage-sound"; import { DeathSound } from "@/components/hud/death-sound"; import { LoadingSpinner } from "@/components/hud/loading-spinner"; import { TouchControls } from "@/components/hud/touch-controls"; import { CharacterInteraction } from "@/components/game/character-interaction"; import { DropZone } from "@/components/editor/drop-zone"; export function GameEngine() { const scenes = useEditorStore((s) => s.scenes); const activeSceneId = useEditorStore((s) => s.activeSceneId); const isPlaying = useEditorStore((s) => s.isPlaying); const setIsPlaying = useEditorStore((s) => s.setIsPlaying); const selectedObjectId = useEditorStore((s) => s.selectedObjectId); const health = useEditorStore((s) => s.health); const lastDamageTime = useEditorStore((s) => s.lastDamageTime); const undo = useEditorStore((s) => s.undo); const redo = useEditorStore((s) => s.redo); const removeObject = useEditorStore((s) => s.removeObject); const isMobile = useIsMobile(); const [leftDrawer, setLeftDrawer] = useState(false); const [rightDrawer, setRightDrawer] = useState(false); const activeScene = useMemo( () => scenes.find((s) => s.id === activeSceneId) || scenes[0], [scenes, activeSceneId], ); const spec = useMemo(() => { if (!activeScene) return null; return sceneToSpec(activeScene); }, [activeScene]); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { const isMod = e.metaKey || e.ctrlKey; if (isMod && e.key === "Enter") { e.preventDefault(); setIsPlaying(!isPlaying); return; } if (isMod && (e.key === "Backspace" || e.key === "Delete")) { e.preventDefault(); if (selectedObjectId && !isPlaying) { removeObject(selectedObjectId); } return; } if (isMod && e.key === "z" && !e.shiftKey) { e.preventDefault(); undo(); return; } if (isMod && (e.key === "y" || (e.key === "z" && e.shiftKey))) { e.preventDefault(); redo(); return; } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [isPlaying, setIsPlaying, selectedObjectId, removeObject, undo, redo]); useEffect(() => { if (isPlaying) { setLeftDrawer(false); setRightDrawer(false); } }, [isPlaying]); const showSidebars = !isPlaying; return (
{/* Left sidebar - JSON Pane (desktop only) */} {showSidebars && (
)} {/* Mobile left drawer */} {showSidebars && ( <>
setLeftDrawer(false)} />
JSON Spec
)} {/* Canvas area */}
{isPlaying ? ( ) : ( <> )} {/* Mobile drawer toggle buttons */} {showSidebars && ( <> )} {!isPlaying && } {!isPlaying && } {isPlaying && } {isPlaying && } {isPlaying && health <= 0 && } {isPlaying && } {isPlaying && } {isPlaying && } {isPlaying && isMobile && }
{/* Right sidebar - Inspector (desktop only) */} {showSidebars && (
)} {/* Mobile right drawer */} {showSidebars && ( <>
setRightDrawer(false)} />
Inspector
)}
); }