Add fancy space battle
This commit is contained in:
parent
5af88cf479
commit
8a37626106
32
webclient/src/spaceport/Laser.js
Normal file
32
webclient/src/spaceport/Laser.js
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user