import * as planck from 'planck' import { Action } from "./Action" import { Entity } from "./Entity" import { PuddleEntity } from './PuddleEntity' import { WorldContext } from './World' export class PlayerEntity extends Entity { action?: Action puddleTimer: number = 0 constructor(ctor: string) { super(ctor) } act(actions: Action[]) { this.action = actions.sort((a, b) => { if (a.priority < b.priority) { return 1 } if (a.priority > b.priority) { return -1 } return 0 })[0] } update(delta: number, ctx: WorldContext) { super.update(delta) let waterZones = this.zones.filter(v=>v.type==='fluid') if (waterZones.length) { this.puddleTimer += delta if (this.puddleTimer >= 600) { if (ctx) { let p = this.position p[0] += (this.sprite.frame?.originX??0) + ((this.sprite.frame?.width??0)/2??0) p[1] += (this.sprite.frame?.originY??0) + ((this.sprite.frame?.height??0)/2??0) ctx.addEntity(new PuddleEntity('effects.water.ripple.small.0'), 'ground', p[0], p[1]) } this.puddleTimer = 0 } } let shouldMove = false if (this.action) { // FIXME: Use physics. switch(this.action.type) { case 'west': if (this.direction !== 0) { if (this.direction < 180) { this.direction -= this.turnRate } else { this.direction += this.turnRate } } shouldMove = true break case 'east': if (this.direction !== 180) { if (this.direction < 180) { this.direction += this.turnRate } else { this.direction -= this.turnRate } } shouldMove = true break case 'north': if (this.direction !== 90) { if (this.direction < 90 || this.direction > 270) { this.direction += this.turnRate } else { this.direction -= this.turnRate } } shouldMove = true break case 'south': if (this.direction !== 270) { if (this.direction > 90 && this.direction < 270) { this.direction += this.turnRate } else { this.direction -= this.turnRate } } shouldMove = true break } if (this.direction > 360) { this.direction = 0 } else if (this.direction < 0) { this.direction = 360 } } if (shouldMove) { let r = this.direction * (Math.PI/180) if (Math.abs(this.velocity[0]) < this.maxSpeed) { this.velocity[0] -= Math.cos(r) * this.acceleration } if (Math.abs(this.velocity[1]) < this.maxSpeed) { this.velocity[1] -= Math.sin(r) * this.acceleration } let cardinal = this.getCardinal() this.sprite.setKey = 'run' if (this.sprite.subsetKey !== cardinal || this.sprite.subsetKey !== 'run') { this.sprite.setCtor(`${this.sprite.spriteKey}.${this.sprite.animationKey}.${this.sprite.setKey}.${cardinal}.${this.sprite.frameIndex}`) } this.sprite.animate = true } else { this.sprite.animate = false this.sprite.setKey = 'stand' this.sprite.setCtor(`${this.sprite.spriteKey}.${this.sprite.animationKey}.${this.sprite.setKey}.${this.getCardinal()}.0`) } // this.velocity[0] *= 0.7 this.velocity[1] *= 0.7 // Eh... let's manually handle velocity this.body?.setLinearVelocity(planck.Vec2(this.velocity[0], this.velocity[1])) } getCardinal(): string { const degreesPerDirection = 360 / 4 const angle = this.direction + degreesPerDirection / 2 if (angle >= 0 * degreesPerDirection && angle < 1 * degreesPerDirection) { return 'west' } else if (angle >= 1 * degreesPerDirection && angle < 2 * degreesPerDirection) { return 'north' } else if (angle >= 2 * degreesPerDirection && angle < 3 * degreesPerDirection) { return 'east' } return 'south' } } export function isPlayerEntity(o: any): o is PlayerEntity { return o.act }