diff --git a/index.html b/index.html
index cdce99d..86c4c08 100644
--- a/index.html
+++ b/index.html
@@ -2,7 +2,7 @@
- Babylon.js Project
+ Truligon - Anomaly + Card System
-
-
-
-
-
+
\ No newline at end of file
diff --git a/package.json b/package.json
index a1925c2..aed46b1 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,22 @@
{
- "name": "babylonjs-project",
+ "name": "truligon",
"version": "1.0.0",
- "description": "A Babylon.js 3D project",
- "main": "app.js",
+ "description": "Truligon Game - Anomaly + Card System",
+ "type": "module",
"scripts": {
- "start": "http-server -c-1 -p 5687"
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview"
},
"dependencies": {
- "http-server": "^14.1.1"
+ "@babylonjs/core": "^6.47.0",
+ "@babylonjs/gui": "^6.47.0",
+ "@babylonjs/loaders": "^6.47.0",
+ "@babylonjs/materials": "^6.47.0"
+ },
+ "devDependencies": {
+ "typescript": "^5.3.3",
+ "vite": "^5.0.12",
+ "@types/node": "^20.11.0"
}
}
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..96c0fda
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,95 @@
+import { Engine, Scene, Vector3, MeshBuilder, Color4, FreeCamera, HemisphericLight, ActionManager, ExecuteCodeAction } from "@babylonjs/core";
+import "@babylonjs/loaders";
+import { AdvancedDynamicTexture, Button, Control } from "@babylonjs/gui";
+
+// 1) Boilerplate
+const canvas = document.getElementById("renderCanvas") as HTMLCanvasElement;
+const engine = new Engine(canvas, true);
+const scene = new Scene(engine);
+
+// 2) Camera & Light
+const camera = new FreeCamera("cam", new Vector3(0, 5, -10), scene);
+camera.setTarget(Vector3.Zero());
+camera.attachControl(canvas, true);
+new HemisphericLight("light", new Vector3(0, 1, 0), scene);
+
+// 3) Ground & Zone
+MeshBuilder.CreateGround("ground", { width: 20, height: 20 }, scene);
+const zone = MeshBuilder.CreateBox("zone", { size: 4 }, scene);
+zone.position = new Vector3(0, 1, 0);
+zone.isVisible = false;
+
+// 4) Anomaly state
+let inAnomaly = false;
+const ANOMALY_DUR = 5000; // 5 s
+const normalSpeed = 1;
+let currentSpeed = normalSpeed;
+
+// 5) GUI – single "Freeze Time" card
+const guiTex = AdvancedDynamicTexture.CreateFullscreenUI("UI");
+const btn = Button.CreateSimpleButton("card", "❄️ Freeze Time");
+btn.width = "150px";
+btn.height = "40px";
+btn.color = "white";
+btn.background = "#444";
+btn.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
+btn.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
+btn.top = "-20px";
+btn.left = "-20px";
+guiTex.addControl(btn);
+
+// 6) Card effect: pause physics 3 s
+btn.onPointerUpObservable.add(() => {
+ if (!inAnomaly) return;
+ scene.getPhysicsEngine()?.setTimeStep(0); // pause
+ setTimeout(() => {
+ scene.getPhysicsEngine()?.setTimeStep(1/60); // resume
+ }, 3000);
+});
+
+// 7) Enter/Exit Anomaly
+zone.actionManager = new ActionManager(scene);
+zone.actionManager.registerAction(
+ new ExecuteCodeAction(
+ { trigger: ActionManager.OnIntersectionEnterTrigger, parameter: zone },
+ () => startAnomaly()
+ )
+);
+
+// 8) Anomaly logic
+function startAnomaly() {
+ if (inAnomaly) return;
+ inAnomaly = true;
+ // fog
+ scene.fogMode = Scene.FOGMODE_EXP;
+ scene.fogColor = new Color4(0.05, 0.05, 0.1, 1);
+ scene.fogDensity = 0.1;
+ // slow-mo
+ currentSpeed = normalSpeed * 0.5;
+
+ // automatically end
+ setTimeout(endAnomaly, ANOMALY_DUR);
+}
+
+function endAnomaly() {
+ inAnomaly = false;
+ scene.fogDensity = 0;
+ currentSpeed = normalSpeed;
+}
+
+// 9) Simple "movement" demo (WASD)
+scene.onBeforeRenderObservable.add(() => {
+ const dt = engine.getDeltaTime() / 1000;
+ const dir = new Vector3(
+ (camera._keys.shift().includes(68) ? 1 : camera._keys.shift().includes(65) ? -1 : 0),
+ 0,
+ (camera._keys.shift().includes(83) ? 1 : camera._keys.shift().includes(87) ? -1 : 0)
+ );
+ camera.position.addInPlace(dir.normalize().scale(currentSpeed * dt * 5));
+});
+
+// 10) Render loop
+engine.runRenderLoop(() => scene.render());
+
+// 11) Resize handler
+window.addEventListener("resize", () => engine.resize());
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a00bb2c
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "include": ["src"]
+}
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..8a885da
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from 'vite';
+import { resolve } from 'path';
+
+export default defineConfig({
+ server: {
+ port: 5687
+ },
+ resolve: {
+ alias: {
+ '@': resolve(__dirname, './src')
+ }
+ }
+});
\ No newline at end of file