From 73f825da72c565e311313e6dc69aeaf97855e5f6 Mon Sep 17 00:00:00 2001 From: Mak Date: Fri, 24 Apr 2026 22:11:32 +0900 Subject: [PATCH] added hammer, prop targets falling and attentive meter, and references to sources used in readme --- README.md | 46 +------ Simple computer.glb | Bin 0 -> 70236 bytes monitor.glb | Bin 0 -> 76732 bytes package-lock.json | 179 +++++++++++++++++++++++++- package.json | 1 + src/App.svelte | 302 ++++++++++++++++++++++++++++++-------------- 6 files changed, 391 insertions(+), 137 deletions(-) create mode 100644 Simple computer.glb create mode 100644 monitor.glb diff --git a/README.md b/README.md index 54a2631..32fd708 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,3 @@ -# Svelte + Vite - -This template should help get you started developing with Svelte in Vite. - -## Recommended IDE Setup - -[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). - -## Need an official Svelte framework? - -Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. - -## Technical considerations - -**Why use this over SvelteKit?** - -- It brings its own routing solution which might not be preferable for some users. -- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. - -This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. - -Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. - -**Why include `.vscode/extensions.json`?** - -Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. - -**Why enable `checkJs` in the JS template?** - -It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration. - -**Why is HMR not preserving my local component state?** - -HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/sveltejs/svelte-hmr/tree/master/packages/svelte-hmr#preservation-of-local-state). - -If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. - -```js -// store.js -// An extremely simple external store -import { writable } from 'svelte/store' -export default writable(0) -``` +Commodore 64 by Jason Toff [CC-BY] via Poly Pizza +https://freefrontend.com/code/procedural-3d-endless-runner-game-2026-02-24/?utm_source=chatgpt.com +using perplexity, gemini, google ai studio diff --git a/Simple computer.glb b/Simple computer.glb new file mode 100644 index 0000000000000000000000000000000000000000..5b3441a6c06dbfa9745fd08180707cf34fb9b25b GIT binary patch literal 70236 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 Czw0>w literal 0 HcmV?d00001 diff --git a/monitor.glb b/monitor.glb new file mode 100644 index 0000000000000000000000000000000000000000..86119acd6278b9493dc79549d93339fc12825cad GIT binary patch literal 76732 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 3b8e45c..2e8b384 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "neurorunner", "version": "0.0.0", "dependencies": { + "p5": "^2.2.3", "three": "^0.184.0" }, "devDependencies": { @@ -16,6 +17,21 @@ "vite": "^8.0.9" } }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@davepagurek/bezier-path": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@davepagurek/bezier-path/-/bezier-path-0.0.7.tgz", + "integrity": "sha512-CVlnCOrV1iy4Z12T756i9l4G6kF7r8uhlnb+xqDemAMmWQB+8Q0b+8VEqIiUfywgZDSiDr18Rm7pZlnA69rE8Q==", + "license": "MIT" + }, "node_modules/@emnapi/core": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", @@ -50,6 +66,12 @@ "tslib": "^2.4.0" } }, + "node_modules/@japont/unicode-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@japont/unicode-range/-/unicode-range-1.0.0.tgz", + "integrity": "sha512-BckHvA2XdjRBVAWe2uceNuRf78lBeI28kyWEbfr/Q2pE17POkwuZ6WWY/UMv8FL9iBxhW4xfDoNLM9UVZaTeUQ==", + "license": "MIT" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -452,7 +474,6 @@ "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -461,6 +482,18 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/aria-query": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", @@ -491,6 +524,16 @@ "node": ">=6" } }, + "node_modules/colorjs.io": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.1.tgz", + "integrity": "sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/color" + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -518,6 +561,27 @@ "dev": true, "license": "MIT" }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/esm-env": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", @@ -525,6 +589,19 @@ "dev": true, "license": "MIT" }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esrap": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.5.tgz", @@ -543,6 +620,24 @@ } } }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -576,6 +671,30 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/gifenc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gifenc/-/gifenc-1.0.3.tgz", + "integrity": "sha512-xdr6AdrfGBcfzncONUOlXMBuc5wJDtOueE3c5rdG0oNgtINLD+f2iFZltrBRZYzACRbKr+mSVU/x98zv2u3jmw==", + "license": "MIT" + }, + "node_modules/i18next": { + "version": "19.9.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-19.9.2.tgz", + "integrity": "sha512-0i6cuo6ER6usEOtKajUUDj92zlG+KArFia0857xxiEHAQcUwh/RtOQocui1LPJwunSYT574Pk64aNva1kwtxZg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.0" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-4.3.1.tgz", + "integrity": "sha512-KIToAzf8zwWvacgnRwJp63ase26o24AuNUlfNVJ5YZAFmdGhsJpmFClxXPuk9rv1FMI4lnc8zLSqgZPEZMrW4g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5" + } + }, "node_modules/is-reference": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", @@ -586,6 +705,12 @@ "@types/estree": "^1.0.6" } }, + "node_modules/libtess": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/libtess/-/libtess-1.2.2.tgz", + "integrity": "sha512-Nps8HPeVVcsmJxUvFLKVJcCgcz+1ajPTXDVAVPs6+giOQP4AHV31uZFFkh+CKow/bkB7GbZWKmwmit7myaqDSw==", + "license": "SGI-B-2.0" + }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", @@ -894,6 +1019,39 @@ ], "license": "MIT" }, + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "license": "MIT" + }, + "node_modules/p5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/p5/-/p5-2.2.3.tgz", + "integrity": "sha512-jz9uy0k3Fcj9vKSOafQlIrpaPZZjO4rAEBZF6dGkbokisshP0M3aFm4qtLHYCoEW1XJSkFaVaOMILCQAQxUHHA==", + "license": "LGPL-2.1", + "dependencies": { + "@davepagurek/bezier-path": "^0.0.7", + "@japont/unicode-range": "^1.0.0", + "acorn": "^8.15.0", + "acorn-walk": "^8.3.4", + "colorjs.io": "^0.6.0", + "escodegen": "^2.1.0", + "gifenc": "^1.0.3", + "i18next": "^19.0.2", + "i18next-browser-languagedetector": "^4.0.1", + "libtess": "^1.2.2", + "omggif": "^1.0.10", + "pako": "^2.1.0", + "zod": "^4.2.1" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -977,6 +1135,16 @@ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1150,6 +1318,15 @@ "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", "dev": true, "license": "MIT" + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 36287b0..bd3dc13 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "vite": "^8.0.9" }, "dependencies": { + "p5": "^2.2.3", "three": "^0.184.0" } } diff --git a/src/App.svelte b/src/App.svelte index 347839e..8fb3293 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -2,27 +2,27 @@ // @ts-nocheck import { onMount } from "svelte"; import * as THREE from "three"; +import p5 from "p5"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import { clone as cloneSkeleton } from "three/examples/jsm/utils/SkeletonUtils.js"; -const CONFIG = { - lane: 2.5, - jump: 0.35, - grav: 0.015, - speed: 55, // Keeping your faster speed - playerScale: 1.7 // Increased size significantly -}; +const CONFIG = { lane: 2.5, jump: 0.35, grav: 0.015, speed: 55, playerScale: 1.7 }; let score = 0, isPlaying = false, gameOver = false, startScreen = true; +let attentiveness = 100; let lane = 0, currX = 0, isJumping = false, jumpV = 0, playerY = 0; -let container, canvas, scene, camera, renderer; -let worldObjects = [], animationFrame; +let container, canvas, scene, camera, renderer, p5Container; +let worldObjects = [], animationFrame, p5Instance; let isDying = false, hitFlash = false; -let playerAnchor, currentModel = null, currentMixer = null, swapToken = 0; +// 2D Game Logic +let gamePhase = "START"; +let instructionTimer = 3; +let targetType = "NEURON"; +let targets = []; -// Treadmill System -const CHUNKS = []; +let playerAnchor, currentModel = null, currentMixer = null, swapToken = 0; +let CHUNKS = []; const CHUNK_COUNT = 3; const CHUNK_SIZE = 140; @@ -31,6 +31,108 @@ const loader = new GLTFLoader(); const clock = new THREE.Clock(); const glbCache = new Map(); +// --- P5 SKETCH (HUD, 2D Hammer & Rare Targets) --- +const sketch = (p) => { + p.setup = () => { + p.createCanvas(p.windowWidth, p.windowHeight); + }; + + p.draw = () => { + p.clear(); + if (!isPlaying) return; + + if (gamePhase === "INSTRUCTIONS") { + p.fill(0, 180); + p.rect(0, 0, p.width, p.height); + p.fill(255); + p.textAlign(p.CENTER); + p.textSize(24); + p.text(`NEURO-MISSION: CLICK THE ${targetType}`, p.width/2, p.height/2 - 20); + p.textSize(60); + p.text(Math.ceil(instructionTimer), p.width/2, p.height/2 + 60); + return; + } + + // Attentiveness Meter + p.noFill(); + p.stroke(255, 100); + p.strokeWeight(2); + p.rect(20, 20, 200, 20, 10); + let color = p.lerpColor(p.color(255, 50, 50), p.color(50, 255, 150), attentiveness / 100); + p.fill(color); + p.noStroke(); + let w = (attentiveness / 100) * 200; + if (attentiveness < 30) w += p.sin(p.frameCount * 0.2) * 5; + p.rect(20, 20, Math.max(0, w), 20, 10); + + // Spawning Rare 2D Targets (0.4% chance) + if (p.random(1) < 0.004) { + const types = ["NEURON", "SUGAR", "GLITCH"]; + targets.push({ + x: p.random(p.width * 0.2, p.width * 0.8), + y: -50, + type: types[p.floor(p.random(types.length))], + speed: p.random(1.5, 3), + rot: 0 + }); + } + + // Process 2D Targets + for (let i = targets.length - 1; i >= 0; i--) { + let t = targets[i]; + t.y += t.speed; + t.rot += 0.02; + + p.push(); + p.translate(t.x, t.y); + p.rotate(t.rot); + p.strokeWeight(2); + if (t.type === "NEURON") { + p.stroke(0, 255, 200); p.noFill(); + for(let j=0; j<8; j++) p.line(0,0, p.cos(j)*20, p.sin(j)*20); + p.ellipse(0, 0, 12); + } else if (t.type === "SUGAR") { + p.fill(255, 105, 180); p.noStroke(); + p.ellipse(0, 0, 25, 25); p.fill(255); p.ellipse(0, 0, 8); + } else { + p.fill(255, 50, 0); p.noStroke(); + p.rect(-12, -12, 24, 24); + } + p.pop(); + + if (t.y > p.height + 50) targets.splice(i, 1); + } + + // 2D Hammer + p.push(); + p.translate(p.mouseX, p.mouseY); + p.rotate(-0.4); + p.fill(120, 80, 50); p.noStroke(); + p.rect(-5, 0, 10, 40, 2); + p.fill(100); + p.rect(-20, -10, 40, 20, 4); + p.pop(); + }; + + p.mousePressed = () => { + if (gamePhase !== "PLAYING") return; + for (let i = targets.length - 1; i >= 0; i--) { + let t = targets[i]; + if (p.dist(p.mouseX, p.mouseY, t.x, t.y) < 40) { + if (t.type === targetType) { + score += 100; + attentiveness = Math.min(100, attentiveness + 15); + } else { + attentiveness -= 20; + } + targets.splice(i, 1); + break; + } + } + }; +}; + +// --- SHADERS --- const grassVertex = ` varying vec2 vUv; uniform float uTime; @@ -50,35 +152,40 @@ const grassFragment = ` } `; -function createWorldChunk(zOffset) { +// --- WORLD GENERATION --- +const createClouds = (group) => { + const cloudMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, transparent: true, opacity: 0.8 }); + const thickness = 2; + const cloudMeshes = Array.from({ length: 20 }).map(() => { + const w = 10 + Math.random() * 20; + const d = 10 + Math.random() * 20; + const cloud = new THREE.Mesh(new THREE.BoxGeometry(w, thickness, d), cloudMaterial); + cloud.position.set((Math.random() - 0.5) * 280, 35, (Math.random() - 0.5) * 300); + return cloud; + }); + group.add(...cloudMeshes); +}; + +const createWorldChunk = (zOffset) => { const group = new THREE.Group(); group.position.z = zOffset; - - const floor = new THREE.Mesh( - new THREE.PlaneGeometry(160, CHUNK_SIZE + 0.1), - new THREE.MeshStandardMaterial({ color: 0x1e2b21 }) - ); + const floor = new THREE.Mesh(new THREE.PlaneGeometry(160, CHUNK_SIZE + 0.1), new THREE.MeshStandardMaterial({ color: 0x1e2b21 })); floor.rotation.x = -Math.PI / 2; group.add(floor); - const count = 7000; // Adjusted for slightly larger floor + const count = 7000; const geo = new THREE.PlaneGeometry(0.4, 0.9, 1, 2); geo.translate(0, 0.45, 0); const mat = new THREE.ShaderMaterial({ - uniforms: { uTime }, - vertexShader: grassVertex, - fragmentShader: grassFragment, - side: THREE.DoubleSide, - alphaToCoverage: true + uniforms: { uTime }, vertexShader: grassVertex, fragmentShader: grassFragment, + side: THREE.DoubleSide, alphaToCoverage: true }); - const mesh = new THREE.InstancedMesh(geo, mat, count); const dummy = new THREE.Object3D(); - for (let i = 0; i < count; i++) { + for(let i=0; i -10 && x < 10) x += (x > 0) ? 10 : -10; - let z = (Math.random() - 0.5) * CHUNK_SIZE; - dummy.position.set(x, 0, z); + dummy.position.set(x, 0, (Math.random() - 0.5) * CHUNK_SIZE); dummy.rotation.y = Math.random() * Math.PI; dummy.scale.setScalar(0.7 + Math.random() * 1.6); dummy.updateMatrix(); @@ -86,13 +193,11 @@ function createWorldChunk(zOffset) { } group.add(mesh); return group; -} +}; +// --- CORE LOGIC --- async function getCachedGLTF(file) { - if (!glbCache.has(file)) { - const gltf = await loader.loadAsync(file); - glbCache.set(file, gltf); - } + if (!glbCache.has(file)) glbCache.set(file, await loader.loadAsync(file)); return glbCache.get(file); } @@ -100,24 +205,15 @@ async function swapCharacter(file, isDeathAnimation = false) { const myToken = ++swapToken; const source = await getCachedGLTF(file); if (myToken !== swapToken) return; - const model = cloneSkeleton(source.scene); model.scale.setScalar(CONFIG.playerScale); model.rotation.y = Math.PI; - const mixer = new THREE.AnimationMixer(model); if (source.animations?.length) { const action = mixer.clipAction(source.animations[0]); - - if (isDeathAnimation) { - action.setLoop(THREE.LoopOnce, 1); - action.clampWhenFinished = true; // STOPS AT THE LAST FRAME - action.play(); - } else { - action.play(); - } + if (isDeathAnimation) { action.setLoop(THREE.LoopOnce, 1); action.clampWhenFinished = true; } + action.play(); } - if (currentModel) playerAnchor.remove(currentModel); currentModel = model; currentMixer = mixer; playerAnchor.add(currentModel); @@ -125,24 +221,32 @@ async function swapCharacter(file, isDeathAnimation = false) { function init() { scene = new THREE.Scene(); - const skyColor = 0xa4c3b2; + const skyColor = 0x87CEFA; scene.background = new THREE.Color(skyColor); - scene.fog = new THREE.Fog(skyColor, 35, 150); - + scene.fog = new THREE.Fog(skyColor, 150, 350); camera = new THREE.PerspectiveCamera(60, 1, 0.1, 1000); - camera.position.set(0, 4.5, 13); // Lowered slightly to match bigger player + camera.position.set(0, 4.5, 13); camera.lookAt(0, 1, -5); - renderer = new THREE.WebGLRenderer({ canvas, antialias: true }); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5)); - scene.add(new THREE.AmbientLight(0xffffff, 1.2)); + const lights = [ + new THREE.AmbientLight(0xffffff, 1.8), + new THREE.DirectionalLight(0xffffff, 1.2) + ]; + lights[1].position.set(0, 50, 0); + scene.add(...lights); - for (let i = 0; i < CHUNK_COUNT; i++) { + // Re-added Clouds + const cloudGroup = new THREE.Group(); + createClouds(cloudGroup); + scene.add(cloudGroup); + + CHUNKS = Array.from({ length: CHUNK_COUNT }).map((_, i) => { const chunk = createWorldChunk(-i * CHUNK_SIZE); - CHUNKS.push(chunk); scene.add(chunk); - } + return chunk; + }); playerAnchor = new THREE.Group(); scene.add(playerAnchor); @@ -155,32 +259,40 @@ function init() { }).observe(container); } -function spawn() { +async function spawn() { const l = Math.floor(Math.random() * 5) - 2; - const mesh = new THREE.Mesh( - new THREE.BoxGeometry(1.8, 1.8, 1.8), - new THREE.MeshStandardMaterial({ color: 0xffffff, transparent: true, opacity: 0.9 }) - ); - mesh.position.set(l * CONFIG.lane, 0.9, -130); - scene.add(mesh); - worldObjects.push({ mesh, lane: l }); + const source = await getCachedGLTF("Simple computer.glb"); + const model = cloneSkeleton(source.scene); + const pivot = new THREE.Group(); + pivot.position.set(l * CONFIG.lane, 0, -130); + model.position.set(0, 0.6, 0); + model.rotation.y = Math.PI; + model.scale.setScalar(5.5); + pivot.add(model); + scene.add(pivot); + worldObjects = [...worldObjects, { mesh: pivot, lane: l }]; } function update() { const delta = clock.getDelta(); uTime.value = clock.getElapsedTime(); - if (currentMixer) currentMixer.update(delta); if (!isPlaying) return; + if (gamePhase === "INSTRUCTIONS") { + instructionTimer -= delta; + if (instructionTimer <= 0) gamePhase = "PLAYING"; + return; + } + const moveStep = CONFIG.speed * delta; score++; + attentiveness -= 0.05; + if (attentiveness <= 0) triggerGameOver(); CHUNKS.forEach(chunk => { chunk.position.z += moveStep; - if (chunk.position.z > CHUNK_SIZE) { - chunk.position.z -= CHUNK_SIZE * CHUNK_COUNT; - } + if (chunk.position.z > CHUNK_SIZE) chunk.position.z -= CHUNK_SIZE * CHUNK_COUNT; }); currX += (lane * CONFIG.lane - currX) * 0.18; @@ -189,23 +301,18 @@ function update() { if (isJumping) { jumpV -= CONFIG.grav; playerY += jumpV; - if (playerY <= 0) { - playerY = 0; - isJumping = false; - if (!isDying) swapCharacter("Running.glb"); - } + if (playerY <= 0) { playerY = 0; isJumping = false; if (!isDying) swapCharacter("Running.glb"); } } playerAnchor.position.y = playerY; worldObjects = worldObjects.map(obj => { obj.mesh.position.z += moveStep; - // Collision box adjusted for larger character - if (Math.abs(obj.mesh.position.z) < 1.3 && obj.lane === lane && playerY < 1.5) triggerGameOver(); + if (Math.abs(obj.mesh.position.z) < 1.5 && obj.lane === lane && playerY < 1.5) triggerGameOver(); return obj; }).filter(obj => { - const keep = obj.mesh.position.z < 25; - if (!keep) scene.remove(obj.mesh); - return keep; + const active = obj.mesh.position.z < 25; + if (!active) { scene.remove(obj.mesh); attentiveness = Math.min(100, attentiveness + 2); } + return active; }); if (score % 30 === 0) spawn(); @@ -213,55 +320,64 @@ function update() { function triggerGameOver() { isPlaying = false; gameOver = true; isDying = true; hitFlash = true; - swapCharacter("Falling Back Death.glb", true); // Pass 'true' for death logic + swapCharacter("Falling Back Death.glb", true); setTimeout(() => hitFlash = false, 150); } async function startGame() { worldObjects.forEach(obj => scene.remove(obj.mesh)); worldObjects = []; - score = 0; isPlaying = true; gameOver = false; startScreen = false; + targets = []; + score = 0; attentiveness = 100; isPlaying = true; gameOver = false; startScreen = false; + gamePhase = "INSTRUCTIONS"; instructionTimer = 3; lane = 0; currX = 0; isJumping = false; jumpV = 0; playerY = 0; isDying = false; - - CHUNKS.forEach((chunk, i) => { - chunk.position.z = -i * CHUNK_SIZE; - }); - + CHUNKS.forEach((chunk, i) => { chunk.position.z = -i * CHUNK_SIZE; }); await swapCharacter("Running.glb"); } -function handleKeyDown(e) { +const handleKeyDown = (e) => { if (!isPlaying || isDying) return; - if (e.key === "ArrowLeft" && lane > -2) lane--; - if (e.key === "ArrowRight" && lane < 2) lane++; - if ((e.key === " " || e.key === "ArrowUp") && !isJumping) { - isJumping = true; jumpV = CONFIG.jump; swapCharacter("Jumping.glb"); - } -} + const actions = { + ArrowLeft: () => lane > -2 && lane--, a: () => lane > -2 && lane--, A: () => lane > -2 && lane--, + ArrowRight: () => lane < 2 && lane++, d: () => lane < 2 && lane++, D: () => lane < 2 && lane++, + " ": () => !isJumping && (isJumping = true, jumpV = CONFIG.jump, swapCharacter("Jumping.glb")), + ArrowUp: () => !isJumping && (isJumping = true, jumpV = CONFIG.jump, swapCharacter("Jumping.glb")), + w: () => !isJumping && (isJumping = true, jumpV = CONFIG.jump, swapCharacter("Jumping.glb")), + W: () => !isJumping && (isJumping = true, jumpV = CONFIG.jump, swapCharacter("Jumping.glb")) + }; + actions[e.key]?.(); +}; onMount(() => { init(); + p5Instance = new p5(sketch, p5Container); const loop = () => { animationFrame = requestAnimationFrame(loop); update(); renderer.render(scene, camera); }; loop(); window.addEventListener("keydown", handleKeyDown); - return () => { cancelAnimationFrame(animationFrame); window.removeEventListener("keydown", handleKeyDown); }; + return () => { + cancelAnimationFrame(animationFrame); + window.removeEventListener("keydown", handleKeyDown); + if (p5Instance) p5Instance.remove(); + }; });
+
{#if hitFlash}
{/if}
{score}