import { Vec3 } from 'cannon-es' import * as RE from 'rogue-engine' import CannonBody from '../../rogue_packages/rogue-cannon/Components/CannonBody.re' export default class Player extends RE.Component { @RE.Prop("Number") speed = 6 @RE.Prop("Number") angle = 0 @RE.Prop("Number") rotationSpeed = Math.PI / 32 @RE.Prop("Boolean") isThrusting = false @RE.Prop("Object3D") thrustFlames @RE.PropList("Object3D") shipTypes = [] @RE.Prop("Object3D") activeShipType @RE.Prop("Color") shipColor @RE.Prop("Material") shipColorMaterial @RE.Prop("Audio") thrustSound awake() { // RE.Input.mouse.lock(); } start() { this.bodyComponent = RE.getComponent(CannonBody, this.object3d) this.thrustFlames = this.object3d.getObjectByName("ThrustFlames") this.thrustFlames.visible = false this.targetAngle = this.angle this.refreshShipDisplay() window.addEventListener('keydown', event => { if(["Tab"].includes(event.code)) event.preventDefault() }) // THREE.AudioContext.getContext().resume() this.thrustSound.setVolume(0) this.thrustSound.setLoop(true) this.thrustSound.play() } refreshShipDisplay() { this.shipTypes.forEach(obj3d => { obj3d.visible = false }) this.activeShipType.visible = true this.shipColorMaterial.color = this.shipColor } worldInputControl() { let keysDown = false if(RE.Input.keyboard.getKeyPressed("KeyW")) { keysDown = true this.targetAngle = Math.PI / 2 if(RE.Input.keyboard.getKeyPressed("KeyA")) { this.targetAngle = 3 * Math.PI / 4 } else if (RE.Input.keyboard.getKeyPressed("KeyD")) { this.targetAngle = Math.PI / 4 } } else if(RE.Input.keyboard.getKeyPressed("KeyS")) { keysDown = true this.targetAngle = -Math.PI / 2 if(RE.Input.keyboard.getKeyPressed("KeyA")) { this.targetAngle = -3 * Math.PI / 4 } else if (RE.Input.keyboard.getKeyPressed("KeyD")) { this.targetAngle = -Math.PI / 4 } } else if(RE.Input.keyboard.getKeyPressed("KeyA")) { keysDown = true this.targetAngle = Math.PI } else if(RE.Input.keyboard.getKeyPressed("KeyD")) { keysDown = true this.targetAngle = 0 } this.bodyComponent.body.quaternion.setFromAxisAngle(new Vec3(0,1,0), this.angle) if(keysDown) { if(this.targetAngle != this.angle) { this.rotateTowardsTarget() } this.thrust() } } thrust() { this.isThrusting = true let modelOffset = Math.PI this.bodyComponent.body.force.x = this.speed * Math.sin(this.angle + modelOffset) this.bodyComponent.body.force.z = this.speed * Math.cos(this.angle + modelOffset) } shipInputControl() { let keyControlled = false if(RE.Input.keyboard.getKeyPressed("KeyA") || RE.Input.keyboard.getKeyPressed("ArrowLeft")) { this.angle += this.rotationSpeed this.targetAngle = this.angle keyControlled = true } if(RE.Input.keyboard.getKeyPressed("KeyD") || RE.Input.keyboard.getKeyPressed("ArrowRight")) { this.angle -= this.rotationSpeed this.targetAngle = this.angle keyControlled = true } if(!keyControlled && this.targetAngle != this.angle) { this.rotateTowardsTarget() } if(RE.Input.keyboard.getKeyPressed("KeyW") || RE.Input.keyboard.getKeyPressed("ArrowUp") || RE.Input.mouse.getButtonPressed(0) ) { this.thrust() } if(this.bodyComponent.body) { this.bodyComponent.body.quaternion.setFromAxisAngle(new Vec3(0,1,0), this.angle) } } rotateTowardsTarget() { let delta = this.targetAngle - this.angle if(Math.abs(delta) > Math.PI) { this.angle += Math.sign(delta) * (2 * Math.PI) } if(Math.abs(delta) < this.rotationSpeed ) { this.angle += delta; } else { this.angle += Math.sign(delta) * this.rotationSpeed } } update() { if(RE.Input.keyboard.getKeyDown("Tab") || RE.Input.keyboard.getKeyDown("Digit1")) { let index = this.shipTypes.indexOf(this.activeShipType) + 1 this.activeShipType = this.shipTypes[index % this.shipTypes.length] this.refreshShipDisplay() } this.isThrusting = false // this.worldInputControl() this.shipInputControl() this.thrustFlames.visible = this.isThrusting if (this.isThrusting && this.thrustSound && this.thrustSound.context.state === "running") { this.thrustSound.setVolume(1) } else { this.thrustSound.setVolume(0) } // this.bodyComponent.body.quaternion.setFromAxisAngle(new Vec3(0,0,1), 0.5 * Math.sin(0.01 * new Date().getTime())) // this.bodyComponent.body.position.y = 0.4 * Math.sin(0.001 * new Date().getTime()) } } RE.registerComponent(Player)