From 6d54f4b15acda8a12c57f847a388c0768720ec07 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Sun, 16 Nov 2025 14:07:06 +0100 Subject: [PATCH] Feature: door randomly opens and closes --- tv-player/src/core/animate.js | 6 ++-- tv-player/src/scene/door.js | 68 ++++++++++++++++++++++++++++++++--- tv-player/src/scene/root.js | 2 +- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/tv-player/src/core/animate.js b/tv-player/src/core/animate.js index 2ac70aa..04b7e3b 100644 --- a/tv-player/src/core/animate.js +++ b/tv-player/src/core/animate.js @@ -1,13 +1,14 @@ import * as THREE from 'three'; -import { state } from '../state.js'; import { updateVcrDisplay } from '../scene/vcr-display.js'; +import { updateDoor } from '../scene/door.js'; +import { state } from '../state.js'; function updateCamera() { const globalTime = Date.now() * 0.00005; const lookAtTime = Date.now() * 0.00003; - const camAmplitude = 0.7; + const camAmplitude = 0.5; const lookAmplitude = 0.05; // Base Camera Position in front of the TV @@ -97,6 +98,7 @@ export function animate() { updateScreenLight(); updateVideo(); updateVcr(); + updateDoor(); // RENDER! state.renderer.render(state.scene, state.camera); diff --git a/tv-player/src/scene/door.js b/tv-player/src/scene/door.js index dfa3a68..2132770 100644 --- a/tv-player/src/scene/door.js +++ b/tv-player/src/scene/door.js @@ -1,7 +1,19 @@ import * as THREE from 'three'; import { state } from '../state.js'; +let doorGroupPanel; + +const DOOR_STATES = { + RESTING: 'resting', + OPENING: 'opening', + CLOSING: 'closing', +}; +let doorState = DOOR_STATES.RESTING; +let stateTimer = 0; + export function createDoor(x, z, rotY) { + const doorWidth = 1; + const doorGroup = new THREE.Group(); doorGroup.position.set(x, 1.1, z); // Centered vertically for a 2.2m door doorGroup.rotation.set(0, rotY, 0); @@ -23,19 +35,67 @@ export function createDoor(x, z, rotY) { frameRight.castShadow = true; doorGroup.add(frameRight); + // Outside darkness + const outsideMaterial = new THREE.MeshBasicMaterial({ color: 0x150505, shininess: 50 }); + const outside = new THREE.Mesh(new THREE.BoxGeometry(doorWidth, 2.2, 0.04), outsideMaterial); + outside.position.set(0, 0, 0); + doorGroup.add(outside); + + // Door group + doorGroupPanel = new THREE.Group(); // Main Door Panel const doorMaterial = new THREE.MeshPhongMaterial({ color: 0x8b5a2b, shininess: 10 }); // Lighter wood for door - const door = new THREE.Mesh(new THREE.BoxGeometry(1.0, 2.2, 0.08), doorMaterial); + const door = new THREE.Mesh(new THREE.BoxGeometry(doorWidth, 2.2, 0.08), doorMaterial); + door.position.set(doorWidth/2, 0, 0); door.castShadow = true; door.receiveShadow = true; - doorGroup.add(door); + doorGroupPanel.add(door); // Door Knob const knobMaterial = new THREE.MeshPhongMaterial({ color: 0xd4af37, shininess: 100 }); // Gold/Brass const knob = new THREE.Mesh(new THREE.SphereGeometry(0.05, 16, 16), knobMaterial); - knob.position.set(0.4, 0, 0.06); // Position on the right side of the door + knob.position.set(doorWidth/2 + 0.4, 0, 0.06); // Position on the right side of the door knob.castShadow = true; - doorGroup.add(knob); + doorGroupPanel.add(knob); + doorGroupPanel.position.x = -doorWidth/2; + doorGroupPanel.rotation.y = 0; + + doorGroup.add(doorGroupPanel); state.scene.add(doorGroup); +} + +export function updateDoor() { + const speed = 0.0002; + const minAngle = 0; + const maxAngle = -0.7; + + stateTimer -= 1 / 60; // Assuming 60fps + + if (stateTimer <= 0) { + const nextState = Math.random(); + if (nextState < 0.4) { + doorState = DOOR_STATES.RESTING; + stateTimer = 5 + Math.random() * 5; + } else if (nextState < 0.7) { + doorState = DOOR_STATES.OPENING; + stateTimer = 2 + Math.random() * 3; // Open for 2-5 seconds + } else { + doorState = DOOR_STATES.CLOSING; + stateTimer = 2 + Math.random() * 3; // Close for 2-5 seconds + } + } + + switch (doorState) { + case DOOR_STATES.OPENING: + if (doorGroupPanel.rotation.y > maxAngle) { + doorGroupPanel.rotation.y -= speed; + } + break; + case DOOR_STATES.CLOSING: + if (doorGroupPanel.rotation.y < minAngle) { + doorGroupPanel.rotation.y += speed; + } + break; + } } \ No newline at end of file diff --git a/tv-player/src/scene/root.js b/tv-player/src/scene/root.js index a30bc39..a6868d8 100644 --- a/tv-player/src/scene/root.js +++ b/tv-player/src/scene/root.js @@ -35,7 +35,7 @@ export function createSceneObjects() { const ambientLight = new THREE.AmbientLight(0x111111, 1); state.scene.add(ambientLight); - const roomLight = new THREE.PointLight(0xffaa55, 0.5, state.roomSize); + const roomLight = new THREE.PointLight(0xffaa55, 0.8, state.roomSize); roomLight.position.set(0, 1.8, 0); state.scene.add(roomLight);