Add fancy space battle

This commit is contained in:
Tanner Collin 2021-03-21 01:44:09 +00:00
parent 0c5c20f1fc
commit 219f98dab4
3 changed files with 86 additions and 31 deletions

View File

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

View File

@ -3,9 +3,13 @@ import * as THREE from 'three';
const SHIP_SIZE = 1; const SHIP_SIZE = 1;
export class Ship { export class Ship {
constructor() { constructor(direction) {
this.life = Math.random() * 5 + 7; this.direction = direction;
this.life = Math.random() * 5 + 12;
this.nextShot = 3;
this.shotInterval = 3;
this.flyIn = true; this.flyIn = true;
this.firing = false;
const shipGeo = new THREE.BoxGeometry( const shipGeo = new THREE.BoxGeometry(
SHIP_SIZE * 0.1, SHIP_SIZE * 0.1,
@ -14,33 +18,32 @@ export class Ship {
); );
this.mesh = new THREE.Mesh( this.mesh = new THREE.Mesh(
shipGeo, 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.y = (Math.random() - 0.5) * 2;
this.x = (Math.random() - 0.5) * 2;
this.hue = Math.floor(Math.random() * 360);
this.mesh.material.color.set( 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.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 }) { update({ deltaTime }) {
if (this.flyIn) { if (this.flyIn) {
this.mesh.scale.z = 10; this.mesh.scale.z = 10;
this.mesh.position.z += 4.75; this.mesh.position.z += 4.75 * this.direction;
// ship accelerating decreasing // ship accelerating decreasing
// checvk if in space // check if in space
if (this.mesh.position.z > -1 && this.flyIn) { if (Math.abs(this.mesh.position.z) <= 6 && this.flyIn) {
this.flyIn = false; this.flyIn = false;
this.mesh.scale.z = 0.5; this.mesh.scale.z = 0.5;
this.mesh.material.color.set( //this.mesh.material.color.set(
new THREE.Color(`hsl(${this.hue},0%,30%)`) // new THREE.Color(`hsl(${this.hue},0%,30%)`)
); //);
} }
} else { } else {
this.mesh.scale.z = 0.5; this.mesh.scale.z = 0.5;
@ -48,15 +51,27 @@ export class Ship {
this.life -= deltaTime; 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) { if (this.life < 0) {
const a = Math.abs(this.life); 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.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; this.kill = true;
} }
} }

View File

@ -1,5 +1,6 @@
import * as THREE from 'three/build/three.module'; import * as THREE from 'three/build/three.module';
import { Ship } from './Ship'; import { Ship } from './Ship';
import { Laser } from './Laser';
export const scene = ({ ref }) => { export const scene = ({ ref }) => {
// TODO: add waves of ships // TODO: add waves of ships
@ -7,7 +8,7 @@ export const scene = ({ ref }) => {
// TODO: use aspect ratio to determine space docking point // TODO: use aspect ratio to determine space docking point
let t = 0.01; let t = 0.01;
const shipInterval = 2; const shipInterval = 1;
let nextShip = shipInterval; let nextShip = shipInterval;
var scene = new THREE.Scene(); var scene = new THREE.Scene();
@ -21,8 +22,9 @@ export const scene = ({ ref }) => {
const camera = new THREE.PerspectiveCamera(65, width / height, 0.01, 1000); 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(-9, 0, 3));
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera); scene.add(camera);
ref.current.appendChild(renderer.domElement); ref.current.appendChild(renderer.domElement);
@ -32,18 +34,8 @@ export const scene = ({ ref }) => {
light.position.z = 1; light.position.z = 1;
scene.add(light); 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 = []; let ships = [];
const ship = new Ship(); let bolts = [];
scene.add(ship.mesh);
ships.push(ship);
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
@ -61,9 +53,12 @@ export const scene = ({ ref }) => {
// camera.x = sin(mu * Math.PI * 2) // camera.x = sin(mu * Math.PI * 2)
// camera.z = cos(mu * Math.PI * 2) // camera.z = cos(mu * Math.PI * 2)
//
const direction = Math.random() > 0.5 ? 1 : -1;
if (t > nextShip) { if (t > nextShip) {
const ship = new Ship(); const ship = new Ship(direction);
scene.add(ship.mesh); scene.add(ship.mesh);
ships.push(ship); ships.push(ship);
nextShip += shipInterval + (Math.random() - 0.5) * 2; nextShip += shipInterval + (Math.random() - 0.5) * 2;
@ -71,11 +66,24 @@ export const scene = ({ ref }) => {
for (const ship of ships) { for (const ship of ships) {
ship.update({ deltaTime }); 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) { if (ship.kill) {
scene.remove(ship.mesh); scene.remove(ship.mesh);
} }
} }
for (const bolt of bolts) {
bolt.update({ deltaTime });
}
ships = ships.filter((s) => !s.kill); ships = ships.filter((s) => !s.kill);
requestAnimationFrame(animate); requestAnimationFrame(animate);