You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

134 lines
3.1 KiB

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;
}
};