Files
the-nexus/modules/effects/energy-beam.js
Claude (Opus 4.6) 35dd6c5f17
Some checks failed
Deploy Nexus / deploy (push) Failing after 4s
[claude] Phase 4: Effects modules — matrix rain, lightning, beam, runes, gravity, shockwave (#423) (#444)
Co-authored-by: Claude (Opus 4.6) <claude@hermes.local>
Co-committed-by: Claude (Opus 4.6) <claude@hermes.local>
2026-03-24 18:19:26 +00:00

57 lines
1.6 KiB
JavaScript

/**
* energy-beam.js — Vertical energy beam above the Batcave terminal
*
* Category: DATA-TETHERED AESTHETIC
* Data source: state.activeAgentCount (0 = faint, 3+ = full intensity)
*
* A glowing cyan cylinder rising from the Batcave area.
* Intensity and pulse amplitude are driven by the number of active agents.
*/
import * as THREE from 'three';
const BEAM_RADIUS = 0.2;
const BEAM_HEIGHT = 50;
const BEAM_X = -10;
const BEAM_Y = 0;
const BEAM_Z = -10;
let _state = null;
let _beamMaterial = null;
let _pulse = 0;
/**
* @param {THREE.Scene} scene
* @param {object} state Shared state bus (reads state.activeAgentCount)
* @param {object} theme Theme bus (reads theme.colors.accent)
*/
export function init(scene, state, theme) {
_state = state;
const accentColor = theme?.colors?.accent ?? 0x4488ff;
const geo = new THREE.CylinderGeometry(BEAM_RADIUS, BEAM_RADIUS * 2.5, BEAM_HEIGHT, 32, 16, true);
_beamMaterial = new THREE.MeshBasicMaterial({
color: accentColor,
transparent: true,
opacity: 0.6,
blending: THREE.AdditiveBlending,
side: THREE.DoubleSide,
depthWrite: false,
});
const beam = new THREE.Mesh(geo, _beamMaterial);
beam.position.set(BEAM_X, BEAM_Y + BEAM_HEIGHT / 2, BEAM_Z);
scene.add(beam);
}
export function update(_elapsed, _delta) {
if (!_beamMaterial) return;
_pulse += 0.02;
const agentCount = _state?.activeAgentCount ?? 0;
const agentIntensity = agentCount === 0 ? 0.1 : Math.min(0.1 + agentCount * 0.3, 1.0);
const pulseEffect = Math.sin(_pulse) * 0.15 * agentIntensity;
_beamMaterial.opacity = agentIntensity * 0.6 + pulseEffect;
}