<!DOCTYPE html> <html> <head> <style> body { margin: 0; overflow: hidden; background: #000; } #ui { position: fixed; top: 10px; left: 10px; color: #0f0; background: rgba(0,20,0,0.7); padding: 15px; border: 1px solid #0f0; font-family: monospace; z-index: 100; } .control { margin: 10px 0; } #matrix { position: fixed; top: 0; left: 0; z-index: -1; color: #0f0; font-family: monospace; font-size: 12px; opacity: 0.2; } </style> </head> <body> <div id="ui"> <div class="control"> <button onclick="initAudio()">Start Audio</button> </div> <div class="control"> <label>Particle Speed: <input type="range" id="speed" min="1" max="200" value="100"></label> </div> <div class="control"> <label>Energy Level: <input type="range" id="energy" min="1" max="100" value="50"></label> </div> <div class="control"> <label>Power: <input type="range" id="power" min="1" max="100" value="75"></label> </div> <div class="control"> <button onclick="addParticle()">Add Particle</button> <button onclick="addDarkMatter()">Add Dark Matter</button> </div> <div>Particles: <span id="particleCount">0</span></div> </div> <div id="matrix"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> let scene, camera, renderer, particles = [], darkMatter = [], plasmaParticles = []; let audioContext; const TUBE_RADIUS = 20; function initAudio() { audioContext = new (window.AudioContext || window.webkitAudioContext)(); } function playCollisionSound() { const oscillator1 = audioContext.createOscillator(); const oscillator2 = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator1.connect(gainNode); oscillator2.connect(gainNode); gainNode.connect(audioContext.destination); oscillator1.frequency.setValueAtTime(440 + Math.random() * 220, audioContext.currentTime); oscillator2.frequency.setValueAtTime(220 + Math.random() * 110, audioContext.currentTime); oscillator1.type = 'sine'; oscillator2.type = 'square'; gainNode.gain.setValueAtTime(0.2, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3); oscillator1.start(); oscillator2.start(); oscillator1.stop(audioContext.currentTime + 0.3); oscillator2.stop(audioContext.currentTime + 0.3); } function init() { initAudio(); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Torus (Accelerator Tube) const tubeGeometry = new THREE.TorusGeometry(TUBE_RADIUS, 2, 32, 100); const tubeMaterial = new THREE.MeshPhongMaterial({ color: 0x00ff00, transparent: true, opacity: 0.3, wireframe: true }); const tube = new THREE.Mesh(tubeGeometry, tubeMaterial); scene.add(tube); // Lighting const light = new THREE.PointLight(0xffffff, 1); light.position.set(0, 0, 50); scene.add(light); scene.add(new THREE.AmbientLight(0x404040)); camera.position.z = 50; // Matrix Rain initMatrix(); } function initMatrix() { const matrix = document.getElementById('matrix'); const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()"; setInterval(() => { let str = ''; for(let i = 0; i < 50; i++) { for(let j = 0; j < 100; j++) { str += chars[Math.floor(Math.random() * chars.length)]; } str += '\n'; } matrix.textContent = str; }, 50); } function addParticle() { const geometry = new THREE.SphereGeometry(0.3, 16, 16); const material = new THREE.MeshPhongMaterial({ color: 0x00ff00, emissive: 0x00ff00, emissiveIntensity: 0.5 }); const particle = new THREE.Mesh(geometry, material); particle.userData = { angle: Math.random() * Math.PI * 2, speed: Math.random() * 0.02 + 0.01, direction: Math.random() > 0.5 ? 1 : -1, phase: Math.random() * Math.PI * 2, energy: 100 }; particles.push(particle); scene.add(particle); updateParticleCount(); } function addDarkMatter() { const geometry = new THREE.SphereGeometry(1, 32, 32); const material = new THREE.MeshPhongMaterial({ color: 0x000066, transparent: true, opacity: 0.3 }); const dm = new THREE.Mesh(geometry, material); dm.position.set( (Math.random() - 0.5) * TUBE_RADIUS * 2, (Math.random() - 0.5) * TUBE_RADIUS * 2, (Math.random() - 0.5) * TUBE_RADIUS * 2 ); darkMatter.push(dm); scene.add(dm); } function createPlasmaExplosion(position) { const particleCount = 30; for(let i = 0; i < particleCount; i++) { const geometry = new THREE.SphereGeometry(0.1, 8, 8); const material = new THREE.MeshPhongMaterial({ color: 0x00ff00, emissive: 0x00ff00, emissiveIntensity: 1 }); const plasma = new THREE.Mesh(geometry, material); plasma.position.copy(position); const velocity = new THREE.Vector3( (Math.random() - 0.5) * 0.5, (Math.random() - 0.5) * 0.5, (Math.random() - 0.5) * 0.5 ); plasma.userData = { velocity: velocity, lifetime: 100, maxLifetime: 100 }; plasmaParticles.push(plasma); scene.add(plasma); } } function updateParticles() { const speed = document.getElementById('speed').value / 50; const energy = document.getElementById('energy').value / 100; const power = document.getElementById('power').value / 100; // Update particles particles.forEach((particle, index) => { particle.userData.angle += particle.userData.speed * speed * particle.userData.direction; particle.position.x = Math.cos(particle.userData.angle) * TUBE_RADIUS; particle.position.y = Math.sin(particle.userData.angle) * TUBE_RADIUS; particle.position.z = Math.sin(particle.userData.phase) * 2; particle.userData.phase += 0.01 * particle.userData.direction; // Collision detection for(let i = index + 1; i < particles.length; i++) { const other = particles[i]; if(particle.position.distanceTo(other.position) < 0.6) { createPlasmaExplosion(particle.position); particle.userData.energy -= power * 10; other.userData.energy -= power * 10; playCollisionSound(); } } if(particle.userData.energy <= 0) { scene.remove(particle); particles.splice(index, 1); updateParticleCount(); } }); // Update plasma particles plasmaParticles.forEach((plasma, index) => { plasma.position.add(plasma.userData.velocity); plasma.userData.lifetime--; plasma.material.opacity = plasma.userData.lifetime / plasma.userData.maxLifetime; if(plasma.userData.lifetime <= 0) { scene.remove(plasma); plasmaParticles.splice(index, 1); } }); } function updateParticleCount() { document.getElementById('particleCount').textContent = particles.length; } function animate() { requestAnimationFrame(animate); updateParticles(); renderer.render(scene, camera); } init(); animate(); </script> </body> </html>