Feature: DJ has a gameboy music controller
This commit is contained in:
parent
6b292b32ad
commit
47b7645046
@ -123,6 +123,9 @@ export class ConfigUI extends SceneFeature {
|
||||
// Console RGB Toggle
|
||||
createToggle('Console RGB Panel', 'consoleRGBEnabled');
|
||||
|
||||
// Gameboy Toggle
|
||||
createToggle('Gameboy', 'gameboyEnabled');
|
||||
|
||||
// Guest Count Input
|
||||
const guestRow = document.createElement('div');
|
||||
guestRow.style.display = 'flex';
|
||||
@ -358,6 +361,7 @@ export class ConfigUI extends SceneFeature {
|
||||
sideScreensEnabled: true,
|
||||
consoleRGBEnabled: true,
|
||||
consoleEnabled: true,
|
||||
gameboyEnabled: false,
|
||||
guestCount: 150,
|
||||
djHat: 'None'
|
||||
};
|
||||
|
||||
@ -142,6 +142,42 @@ export class DJ extends SceneFeature {
|
||||
topHatGroup.visible = false;
|
||||
this.head.add(topHatGroup);
|
||||
this.hats['Top Hat'] = topHatGroup;
|
||||
|
||||
// --- Gameboy / Portable Console ---
|
||||
const gbGroup = new THREE.Group();
|
||||
// Body
|
||||
const gbGeo = new THREE.BoxGeometry(0.2, 0.3, 0.05);
|
||||
const gbMat = new THREE.MeshStandardMaterial({ color: 0x222222, roughness: 0.4 });
|
||||
const gbBody = new THREE.Mesh(gbGeo, gbMat);
|
||||
gbGroup.add(gbBody);
|
||||
|
||||
// Screen (Emissive)
|
||||
const screenGeo = new THREE.PlaneGeometry(0.16, 0.12);
|
||||
this.gbScreenMat = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
|
||||
const screen = new THREE.Mesh(screenGeo, this.gbScreenMat);
|
||||
screen.position.set(0, 0.05, 0.026);
|
||||
gbGroup.add(screen);
|
||||
|
||||
// Knobs/Buttons
|
||||
const knobGeo = new THREE.CylinderGeometry(0.02, 0.02, 0.02, 8);
|
||||
const knobMat = new THREE.MeshStandardMaterial({ color: 0xcccccc });
|
||||
|
||||
const k1 = new THREE.Mesh(knobGeo, knobMat);
|
||||
k1.rotation.x = Math.PI/2;
|
||||
k1.position.set(-0.05, -0.08, 0.026);
|
||||
gbGroup.add(k1);
|
||||
|
||||
const k2 = new THREE.Mesh(knobGeo, knobMat);
|
||||
k2.rotation.x = Math.PI/2;
|
||||
k2.position.set(0.05, -0.08, 0.026);
|
||||
gbGroup.add(k2);
|
||||
|
||||
// Attach to Left Arm (Hand position)
|
||||
gbGroup.position.set(0, -0.9, 0.1);
|
||||
gbGroup.rotation.x = -Math.PI / 4; // Tilted up
|
||||
gbGroup.rotation.z = Math.PI; // Upside down
|
||||
this.leftArm.add(gbGroup);
|
||||
this.gameboy = gbGroup;
|
||||
}
|
||||
|
||||
update(deltaTime) {
|
||||
@ -162,9 +198,16 @@ export class DJ extends SceneFeature {
|
||||
// Update Arm State
|
||||
this.armTimer -= deltaTime;
|
||||
if (this.armTimer <= 0) {
|
||||
this.armState = Math.floor(Math.random() * 5);
|
||||
this.armState = Math.floor(Math.random() * 4); // 0-3: Dance moves
|
||||
this.armTimer = 2 + Math.random() * 4;
|
||||
if (Math.random() < 0.3 && state.config.consoleEnabled) this.armState = 4; // Twiddling some more
|
||||
|
||||
const rand = Math.random();
|
||||
// Gameboy Fiddling
|
||||
if (state.config.gameboyEnabled && rand < 0.35) {
|
||||
this.armState = 5;
|
||||
} else if (state.config.consoleEnabled && rand < 0.65) {
|
||||
this.armState = 4; // Console Twiddling
|
||||
}
|
||||
}
|
||||
|
||||
const upAngle = Math.PI * 0.85;
|
||||
@ -182,6 +225,13 @@ export class DJ extends SceneFeature {
|
||||
targetRightZ = 0.2;
|
||||
targetLeftX = twiddleX;
|
||||
targetRightX = twiddleX;
|
||||
} else if (this.armState === 5 && state.config.gameboyEnabled) {
|
||||
targetLeftZ = -0.3;
|
||||
targetRightZ = -0.5; // Cross inwards
|
||||
const timeRotX = Math.cos(time * 0.5) * 0.3;
|
||||
const consoleRotX = state.config.consoleEnabled ? -0.5 : 0;
|
||||
targetLeftX = -1.0 + timeRotX + consoleRotX; // Lift up
|
||||
targetRightX = -1.1 + timeRotX + consoleRotX; // Lift up
|
||||
} else {
|
||||
targetLeftZ = (this.armState === 1 || this.armState === 3) ? upAngle : downAngle;
|
||||
targetRightZ = (this.armState === 2 || this.armState === 3) ? upAngle : downAngle;
|
||||
@ -198,6 +248,12 @@ export class DJ extends SceneFeature {
|
||||
this.rightArm.rotation.z = this.currentRightAngle + Math.sin(t) * 0.05;
|
||||
this.leftArm.rotation.x = this.currentLeftAngleX + Math.sin(t) * 0.1;
|
||||
this.rightArm.rotation.x = this.currentRightAngleX + Math.cos(t) * 0.1;
|
||||
} else if (this.armState === 5 && state.config.gameboyEnabled) {
|
||||
const t = time * 20;
|
||||
this.leftArm.rotation.z = -this.currentLeftAngle + Math.sin(t * 0.2) * 0.01;
|
||||
this.rightArm.rotation.z = this.currentRightAngle + Math.sin(t) * 0.05;
|
||||
this.leftArm.rotation.x = this.currentLeftAngleX + Math.cos(t * 0.2) * 0.01;
|
||||
this.rightArm.rotation.x = this.currentRightAngleX + Math.cos(t) * 0.05;
|
||||
} else {
|
||||
const wave = Math.sin(time * 8) * 0.1;
|
||||
const beatBounce = beatIntensity * 0.2;
|
||||
@ -233,6 +289,15 @@ export class DJ extends SceneFeature {
|
||||
for (const [name, mesh] of Object.entries(this.hats)) {
|
||||
mesh.visible = (state.config.djHat === name);
|
||||
}
|
||||
|
||||
// Update Gameboy
|
||||
if (this.gameboy) {
|
||||
this.gameboy.visible = state.config.gameboyEnabled;
|
||||
if (this.gameboy.visible && state.music) {
|
||||
const hue = (time * 0.5) % 1;
|
||||
this.gbScreenMat.color.setHSL(hue, 1.0, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPartyStart() {
|
||||
|
||||
@ -9,6 +9,7 @@ export function initState() {
|
||||
sideScreensEnabled: true,
|
||||
consoleRGBEnabled: true,
|
||||
consoleEnabled: true,
|
||||
gameboyEnabled: false,
|
||||
guestCount: 150,
|
||||
djHat: 'None' // 'None', 'Santa', 'Top Hat'
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user