UNPKG

@matematrolii/sketchbook

Version:

3D matematrolii playground built on three.js and cannon.js

154 lines (136 loc) 3.92 kB
import * as THREE from 'three'; import * as Utils from '../../core/FunctionLibrary'; import { DropIdle, DropRolling, DropRunning, Falling, Sprint, StartWalkBackLeft, StartWalkBackRight, StartWalkForward, StartWalkLeft, StartWalkRight, Walk, } from './_stateLibrary'; import { Character } from '../Character'; import { ICharacterState } from '../../interfaces/ICharacterState'; export abstract class CharacterStateBase implements ICharacterState { public character: Character; public timer: number; public animationLength: any; public canFindVehiclesToEnter: boolean; public canLeaveVehicles: boolean; public canPickItems: boolean; constructor(character: Character) { this.character = character; this.character.velocitySimulator.damping = this.character.defaultVelocitySimulatorDamping; this.character.velocitySimulator.mass = this.character.defaultVelocitySimulatorMass; this.character.rotationSimulator.damping = this.character.defaultRotationSimulatorDamping; this.character.rotationSimulator.mass = this.character.defaultRotationSimulatorMass; this.character.arcadeVelocityIsAdditive = false; this.character.setArcadeVelocityInfluence(1, 0, 1); this.canFindVehiclesToEnter = true; this.canPickItems = true; this.canLeaveVehicles = true; this.timer = 0; } public update(timeStep: number): void { this.timer += timeStep; } public onInputChange(): void { if(this.canPickItems && this.character.actions.pick.justPressed) { this.character.findItemToPick(); } } public noDirection(): boolean { return !this.character.actions.up.isPressed && !this.character.actions.down.isPressed && !this.character.actions.left.isPressed && !this.character.actions.right.isPressed; } public anyDirection(): boolean { return this.character.actions.up.isPressed || this.character.actions.down.isPressed || this.character.actions.left.isPressed || this.character.actions.right.isPressed; } public fallInAir(): void { if (!this.character.rayHasHit) { this.character.setState(new Falling(this.character)); } } public animationEnded(timeStep: number): boolean { if (this.character.mixer !== undefined) { if (this.animationLength === undefined) { console.error(this.constructor.name + 'Error: Set this.animationLength in state constructor!'); return false; } else { return this.timer > this.animationLength - timeStep; } } else { return true; } } public setAppropriateDropState(): void { if (this.character.groundImpactData.velocity.y < -6) { this.character.setState(new DropRolling(this.character)); } else if (this.anyDirection()) { if (this.character.groundImpactData.velocity.y < -2) { this.character.setState(new DropRunning(this.character)); } else { if (this.character.actions.run.isPressed) { this.character.setState(new Sprint(this.character)); } else { this.character.setState(new Walk(this.character)); } } } else { this.character.setState(new DropIdle(this.character)); } } public setAppropriateStartWalkState(): void { let range = Math.PI; let angle = Utils.getSignedAngleBetweenVectors(this.character.orientation, this.character.getCameraRelativeMovementVector()); if (angle > range * 0.8) { this.character.setState(new StartWalkBackLeft(this.character)); } else if (angle < -range * 0.8) { this.character.setState(new StartWalkBackRight(this.character)); } else if (angle > range * 0.3) { this.character.setState(new StartWalkLeft(this.character)); } else if (angle < -range * 0.3) { this.character.setState(new StartWalkRight(this.character)); } else { this.character.setState(new StartWalkForward(this.character)); } } protected playAnimation(animName: string, fadeIn: number): void { this.animationLength = this.character.setAnimation(animName, fadeIn); } }