GGJ22/Engine/src/live/PlayerEntity.ts

120 lines
3.6 KiB
TypeScript

import * as planck from 'planck'
import { Action } from "./Action"
import { Entity } from "./Entity"
export class PlayerEntity extends Entity {
action?: Action
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) {
if (this.action) {
// FIXME: Use physics.
let shouldMove = false
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()
if (this.sprite.subsetKey !== cardinal) {
this.sprite.setCtor(`${this.sprite.spriteKey}.${this.sprite.animationKey}.${this.sprite.setKey}.${cardinal}.${this.sprite.frameIndex}`)
}
}
}
//
this.velocity[0] *= 0.5
this.velocity[1] *= 0.5
// Eh... let's manually handle velocity
this.body?.setLinearVelocity(planck.Vec2(this.velocity[0], this.velocity[1]))
}
getCardinal(): string {
const degreesPerDirection = 360 / 8
const angle = this.direction + degreesPerDirection / 2
if (angle >= 0 * degreesPerDirection && angle < 1 * degreesPerDirection) {
return 'w'
} else if (angle >= 1 * degreesPerDirection && angle < 2 * degreesPerDirection) {
return 'nw'
} else if (angle >= 2 * degreesPerDirection && angle < 3 * degreesPerDirection) {
return 'n'
} else if (angle >= 3 * degreesPerDirection && angle < 4 * degreesPerDirection) {
return 'ne'
} else if (angle >= 4 * degreesPerDirection && angle < 5 * degreesPerDirection) {
return 'e'
} else if (angle >= 5 * degreesPerDirection && angle < 6 * degreesPerDirection) {
return 'se'
} else if (angle >= 6 * degreesPerDirection && angle < 7 * degreesPerDirection) {
return 's'
}
return 'sw'
}
}
export function isPlayerEntity(o: any): o is PlayerEntity {
return o.act
}