Feature: door randomly opens and closes

This commit is contained in:
Dejvino 2025-11-16 14:07:06 +01:00
parent 15cb69a120
commit 6d54f4b15a
3 changed files with 69 additions and 7 deletions

View File

@ -1,13 +1,14 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { state } from '../state.js';
import { updateVcrDisplay } from '../scene/vcr-display.js'; import { updateVcrDisplay } from '../scene/vcr-display.js';
import { updateDoor } from '../scene/door.js';
import { state } from '../state.js';
function updateCamera() { function updateCamera() {
const globalTime = Date.now() * 0.00005; const globalTime = Date.now() * 0.00005;
const lookAtTime = Date.now() * 0.00003; const lookAtTime = Date.now() * 0.00003;
const camAmplitude = 0.7; const camAmplitude = 0.5;
const lookAmplitude = 0.05; const lookAmplitude = 0.05;
// Base Camera Position in front of the TV // Base Camera Position in front of the TV
@ -97,6 +98,7 @@ export function animate() {
updateScreenLight(); updateScreenLight();
updateVideo(); updateVideo();
updateVcr(); updateVcr();
updateDoor();
// RENDER! // RENDER!
state.renderer.render(state.scene, state.camera); state.renderer.render(state.scene, state.camera);

View File

@ -1,7 +1,19 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { state } from '../state.js'; 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) { export function createDoor(x, z, rotY) {
const doorWidth = 1;
const doorGroup = new THREE.Group(); const doorGroup = new THREE.Group();
doorGroup.position.set(x, 1.1, z); // Centered vertically for a 2.2m door doorGroup.position.set(x, 1.1, z); // Centered vertically for a 2.2m door
doorGroup.rotation.set(0, rotY, 0); doorGroup.rotation.set(0, rotY, 0);
@ -23,19 +35,67 @@ export function createDoor(x, z, rotY) {
frameRight.castShadow = true; frameRight.castShadow = true;
doorGroup.add(frameRight); 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 // Main Door Panel
const doorMaterial = new THREE.MeshPhongMaterial({ color: 0x8b5a2b, shininess: 10 }); // Lighter wood for door 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.castShadow = true;
door.receiveShadow = true; door.receiveShadow = true;
doorGroup.add(door); doorGroupPanel.add(door);
// Door Knob // Door Knob
const knobMaterial = new THREE.MeshPhongMaterial({ color: 0xd4af37, shininess: 100 }); // Gold/Brass const knobMaterial = new THREE.MeshPhongMaterial({ color: 0xd4af37, shininess: 100 }); // Gold/Brass
const knob = new THREE.Mesh(new THREE.SphereGeometry(0.05, 16, 16), knobMaterial); 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; 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); 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;
}
}

View File

@ -35,7 +35,7 @@ export function createSceneObjects() {
const ambientLight = new THREE.AmbientLight(0x111111, 1); const ambientLight = new THREE.AmbientLight(0x111111, 1);
state.scene.add(ambientLight); 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); roomLight.position.set(0, 1.8, 0);
state.scene.add(roomLight); state.scene.add(roomLight);