diff --git a/webclient/src/spaceport/Laser.js b/webclient/src/spaceport/Laser.js new file mode 100644 index 0000000..a2c5a40 --- /dev/null +++ b/webclient/src/spaceport/Laser.js @@ -0,0 +1,32 @@ +import * as THREE from 'three'; + +const LASER_SIZE = 0.5; + +export class Laser { + constructor(ship) { + const position = new THREE.Vector3(); + this.direction = ship.direction; + + ship.mesh.getWorldPosition(position) + + const shipGeo = new THREE.BoxGeometry( + LASER_SIZE * 0.03, + LASER_SIZE * 0.03, + LASER_SIZE + ); + this.mesh = new THREE.Mesh( + shipGeo, + new THREE.MeshStandardMaterial(this.direction > 0 ? 0xff0000 : 0x0000ff, { flatShading: true }) + ); + + this.mesh.material.color.set( + new THREE.Color(`hsl(${ship.direction > 0 ? 0 : 180},100%,70%)`) + ); + + this.mesh.position.set(position.x, position.y, position.z); + } + + update({ deltaTime }) { + this.mesh.position.z += 0.5 * this.direction; + } +} diff --git a/webclient/src/spaceport/Ship.js b/webclient/src/spaceport/Ship.js index 322df54..e49e502 100644 --- a/webclient/src/spaceport/Ship.js +++ b/webclient/src/spaceport/Ship.js @@ -3,9 +3,13 @@ import * as THREE from 'three'; const SHIP_SIZE = 1; export class Ship { - constructor() { - this.life = Math.random() * 5 + 7; + constructor(direction) { + this.direction = direction; + this.life = Math.random() * 5 + 12; + this.nextShot = 3; + this.shotInterval = 3; this.flyIn = true; + this.firing = false; const shipGeo = new THREE.BoxGeometry( SHIP_SIZE * 0.1, @@ -14,33 +18,32 @@ export class Ship { ); this.mesh = new THREE.Mesh( shipGeo, - new THREE.MeshStandardMaterial(0xff0000, { flatShading: true }) + new THREE.MeshStandardMaterial(this.direction > 0 ? 0xff0000 : 0x0000ff, { flatShading: true }) ); this.y = (Math.random() - 0.5) * 2; - - this.hue = Math.floor(Math.random() * 360); + this.x = (Math.random() - 0.5) * 2; this.mesh.material.color.set( - new THREE.Color(`hsl(${this.hue},10%,40%)`) + new THREE.Color(`hsl(${direction > 0 ? 0 : 180},30%,40%)`) ); - this.mesh.position.x = (Math.random() - 0.5) * 2; this.mesh.position.y = this.y; - this.mesh.position.z = -105 + Math.random(); + this.mesh.position.x = this.x; + this.mesh.position.z = (-475/4 - 6) * this.direction; //+ Math.random() } update({ deltaTime }) { if (this.flyIn) { this.mesh.scale.z = 10; - this.mesh.position.z += 4.75; + this.mesh.position.z += 4.75 * this.direction; // ship accelerating decreasing - // checvk if in space - if (this.mesh.position.z > -1 && this.flyIn) { + // check if in space + if (Math.abs(this.mesh.position.z) <= 6 && this.flyIn) { this.flyIn = false; this.mesh.scale.z = 0.5; - this.mesh.material.color.set( - new THREE.Color(`hsl(${this.hue},0%,30%)`) - ); + //this.mesh.material.color.set( + // new THREE.Color(`hsl(${this.hue},0%,30%)`) + //); } } else { this.mesh.scale.z = 0.5; @@ -48,15 +51,27 @@ export class Ship { this.life -= deltaTime; - this.mesh.position.y = this.y + Math.sin(this.life + this.y) * 0.02; + if (!this.flyIn) { + const xs = Math.sin(this.life*0.5 + this.x); + this.mesh.position.y = this.y + Math.sin(this.life + this.y) * 0.08; + this.mesh.position.x = this.x + xs * 0.08; + this.mesh.rotation.y = xs*0.25; + this.mesh.position.z += 0.01 * this.direction; + this.nextShot -= deltaTime; + if (this.nextShot <= 0) { + this.firing = true; + this.nextShot = this.shotInterval; + } + } if (this.life < 0) { const a = Math.abs(this.life); - this.mesh.position.z += a * 2; + this.mesh.position.z += a * 2 * this.direction; this.mesh.scale.z = a * 4; + this.firing = false; } - if (this.mesh.position.z > 55) { + if (Math.abs(this.mesh.position.z > 475/2)) { this.kill = true; } } diff --git a/webclient/src/spaceport/scene.js b/webclient/src/spaceport/scene.js index 36a66a5..d6ea549 100644 --- a/webclient/src/spaceport/scene.js +++ b/webclient/src/spaceport/scene.js @@ -1,5 +1,6 @@ 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 @@ -7,7 +8,7 @@ export const scene = ({ ref }) => { // TODO: use aspect ratio to determine space docking point let t = 0.01; - const shipInterval = 2; + const shipInterval = 1; let nextShip = shipInterval; var scene = new THREE.Scene(); @@ -21,8 +22,9 @@ export const scene = ({ ref }) => { const camera = new THREE.PerspectiveCamera(65, width / height, 0.01, 1000); - camera.position.set(3, 0.5, 5); + camera.position.set(5, 0.5, 1); camera.lookAt(new THREE.Vector3(-9, 0, 3)); + camera.lookAt(new THREE.Vector3(0, 0, 0)); scene.add(camera); ref.current.appendChild(renderer.domElement); @@ -32,18 +34,8 @@ export const scene = ({ ref }) => { light.position.z = 1; scene.add(light); - var sphere = new THREE.SphereBufferGeometry(1); - var object = new THREE.Mesh( - sphere, - new THREE.MeshStandardMaterial(0xff0000, { flatShading: true }) - ); - var boxHelp = new THREE.BoxHelper(object, 0xffff00); - // scene.add(boxHelp); - let ships = []; - const ship = new Ship(); - scene.add(ship.mesh); - ships.push(ship); + let bolts = []; window.addEventListener('resize', () => { camera.updateProjectionMatrix(); @@ -61,9 +53,12 @@ export const scene = ({ ref }) => { // camera.x = sin(mu * Math.PI * 2) // camera.z = cos(mu * Math.PI * 2) + // + + const direction = Math.random() > 0.5 ? 1 : -1; if (t > nextShip) { - const ship = new Ship(); + const ship = new Ship(direction); scene.add(ship.mesh); ships.push(ship); nextShip += shipInterval + (Math.random() - 0.5) * 2; @@ -71,11 +66,24 @@ export const scene = ({ ref }) => { for (const ship of ships) { ship.update({ deltaTime }); + + if (ship.firing) { + const bolt = new Laser(ship); + bolts.push(bolt); + scene.add(bolt.mesh); + console.log(bolt.mesh.position); + ship.firing = false; + } + if (ship.kill) { scene.remove(ship.mesh); } } + for (const bolt of bolts) { + bolt.update({ deltaTime }); + } + ships = ships.filter((s) => !s.kill); requestAnimationFrame(animate);