import * as THREE from './threejs/build/three.module.js'; import { keys } from './Core.js'; import { GLTFLoader } from './threejs/examples/jsm/loaders/GLTFLoader.js'; export class Ship { constructor(scene) { this.scene = scene; this.targetAngle = 0; this.angle = 0; this.speed = 0.01; this.turnSpeed = 60 * Math.PI / 180; this.position = new THREE.Vector3(); this.velocity = new THREE.Vector3(); this.acceleration = new THREE.Vector3(); this.drag = new THREE.Vector3(0.97, 1, 0.97); this.clock = new THREE.Clock(); } static loadShip() { return new Promise((resolve, reject) => { var gltfloader = new GLTFLoader(); return gltfloader.load( './models/Models/glTF format/ship_light.gltf', function (gltf) { resolve(gltf); }, function (xhr) { }, function (error) { reject(error); } ); }); } init() { this.scene.traverse(function (node) { if (node.isMesh) { /*node.castShadow = true;*/ node.receiveShadow = true; } }); let starboardLight = new THREE.PointLight(0x80ffff, 0.8, 5, 1); starboardLight.position.set(1.25, 2.05, 2); starboardLight.castShadow = true; this.scene.add(starboardLight); let portLight = new THREE.PointLight(0xff80ff, 0.8, 5, 1); portLight.position.set(-2.5, 2.05, 2); portLight.castShadow = true; this.scene.add(portLight); let bowLight = new THREE.PointLight(0xffff80, 0.8, 5, 1); bowLight.position.set(-0.75, 1.40, -4.75); bowLight.castShadow = true; this.scene.add(bowLight); } handleInput() { if (keys["KeyA"]) { //left this.targetAngle += this.turnSpeed; } if (keys["KeyD"]) { //right this.targetAngle += -this.turnSpeed; } this.acceleration.set(0, 0, 0); if (keys["KeyW"]) { //up this.acceleration.set(this.speed * Math.sin((180 + this.angle) * Math.PI / 180), 0, this.speed * Math.cos((180 + this.angle) * Math.PI / 180)); //this.targetAngle = 0; } if (keys["KeyS"]) { //down //this.acceleration.set(this.speed * Math.cos(this.angle), 0, this.speed * Math.sin(this.angle)); //this.targetAngle = 180; } } computeWave() { let u_time = this.clock.getElapsedTime(); let p = this.position; let wave = { x: 0, z: 0 }; wave.x = Math.sin(2.5 * (u_time + (p.z * 0.1))); wave.x += Math.sin(3.5 * (u_time + (p.x * 0.1))); wave.z = Math.sin(2.5 * (u_time + (p.z * 0.1))); wave.z += Math.sin(3.5 * (u_time + (p.x * 0.1))); return wave; } updateModel() { if (this.angle != this.targetAngle) { this.angle += this.turnSpeed * (this.angle - this.targetAngle > 0 ? -1 : 1); if (Math.abs(this.angle - this.targetAngle) < this.turnSpeed) { this.angle = this.targetAngle; } } let wave = this.computeWave(); this.position.add(this.velocity.add(this.acceleration).multiply(this.drag)); this.position.setY(0.3 * wave.x + 0.4); //this.position.setY(0.20 * Math.sin(new Date().getTime() / 500) - 0.5); this.scene.rotation.set( 0.05 * wave.x, this.angle * Math.PI / 180, 0.05 * wave.z); this.scene.position.set(this.position.x, this.position.y, this.position.z); } }