import * as THREE from 'three/build/three.module'; import { Ship } from './Ship'; import { Laser } from './Laser'; export const scene = ({ ref }) => { // TODO: add waves of ships // TODO: add stars // TODO: use aspect ratio to determine space docking point let t = 0.01; const shipInterval = 1; let nextShip = shipInterval; var scene = new THREE.Scene(); let renderer = null; try { renderer = new THREE.WebGLRenderer({ antialias: true }); } catch (error) { console.log('Problem creating WebGLRenderer:', error); return; } const width = ref.current.clientWidth; const height = ref.current.clientHeight; renderer.setSize(width, height); const camera = new THREE.PerspectiveCamera(65, width / height, 0.01, 1000000); camera.position.set(5, 2, 1); camera.lookAt(new THREE.Vector3(0, 0, 0)); scene.add(camera); ref.current.appendChild(renderer.domElement); const light1 = new THREE.DirectionalLight('#fff', 1); light1.position.x = 3; light1.position.z = 1; scene.add(light1); const light2 = new THREE.PointLight('#fff', 2); light2.position.x = 5; light2.position.y = 5; light2.position.z = 1; scene.add(light2); const star_material = new THREE.MeshBasicMaterial( { side: THREE.DoubleSide, color: 0xaaaaaa } ); let stars = []; for (let i = 0; i < 200; i++) { const star_geometry = new THREE.CircleGeometry( Math.random() * 200 + 100, 8 ); const star_circle = new THREE.Mesh( star_geometry, star_material ); scene.add(star_circle); //star_circle.rotation.y = Math.PI / 2; const u = Math.random() - 0.5; const v = Math.random() - 0.5; star_circle.position.set(-100000*Math.sin(v*Math.PI+Math.PI/2), 300000*u, 100000*Math.cos(v*Math.PI+Math.PI/2)); star_circle.lookAt(camera.position); stars.push(star_circle); } let ships = []; let bolts = []; window.addEventListener('resize', () => { camera.updateProjectionMatrix(); renderer.setSize(ref.current.clientWidth, ref.current.clientHeight); }); ref.current.addEventListener('mousemove', (e) => { const x = e.clientX; const ratio = x / ref.current.clientWidth; camera.position.set(5, 2, ratio * 4 - 2); camera.lookAt(new THREE.Vector3(0, 0, 0)); }); const animate = () => { const deltaTime = 0.075; t += deltaTime; const direction = Math.random() > 0.5 ? 1 : -1; if (t > nextShip) { const ship = new Ship(direction); scene.add(ship.mesh); ships.push(ship); nextShip += shipInterval + (Math.random() - 0.5) * 2; } for (const ship of ships) { ship.update({ deltaTime }); if (ship.firing) { const bolt = new Laser(ship); bolts.push(bolt); scene.add(bolt.mesh); ship.firing = false; } if (ship.kill) { scene.remove(ship.mesh); } } for (const bolt of bolts) { bolt.update({ deltaTime }); if (bolt.kill) { scene.remove(bolt.mesh); } } ships = ships.filter((s) => !s.kill); bolts = bolts.filter((s) => !s.kill); try { requestAnimationFrame(animate); renderer.render(scene, camera); } catch(err) { return; } }; try { animate(); renderer.render(scene, camera); } catch(err) { renderer.dispose(); return; } };