Add gibbing

This commit is contained in:
Ketchetwahmeegwun T. Southall 2022-01-30 06:23:50 -08:00
parent 15370173ad
commit ca4fc063e9
4 changed files with 100 additions and 4 deletions

View File

@ -3,6 +3,7 @@ import { AnimalDefinition, CreatureDefinition } from '../data/animals'
import { playSong, playSound } from '../shared/audio'
import { Action, adjustAction } from "./Action"
import { Entity, Sensor } from "./Entity"
import { GibletEntity } from './GibletEntity'
import { PuddleEntity } from './PuddleEntity'
import { WorldContext } from './World'
@ -22,6 +23,8 @@ export class AnimalEntity extends Entity {
stepSoundElapsed: number = 0
lastYellElapsed: number = 0
nextYell: number = 1000
dead: boolean = false
shouldGib: boolean = false
constructor(def: AnimalDefinition) {
super(`${def.name}.animal.stand.west.0`)
@ -44,6 +47,16 @@ export class AnimalEntity extends Entity {
}
update(delta: number, ctx: WorldContext) {
super.update(delta)
if (this.dead) {
if (this.shouldGib) {
this.gib(ctx)
this.shouldGib = false
}
this.shouldRemove = true
return
}
this.lastYellElapsed += delta
let waterZones = this.zones.filter(v=>v.type==='fluid')
@ -262,6 +275,31 @@ export class AnimalEntity extends Entity {
}
}
}
gib(ctx: WorldContext) {
let p = this.position
p[0] += this.sprite.container.width/2
p[1] += this.sprite.container.height/2
this.dead = true
let force = -1 + Math.random() * 2
let dir = Math.random() * 320
// 50% head gib
if (Math.random() > 0.5) {
ctx.addEntity(new GibletEntity(`giblets.${this.sprite.spriteKey}.head.default.0`, dir+Math.random()*40, force+Math.random()*10), 'objects', p[0], p[1])
}
// 44% leg gib per leg
for (let i = 0; i < 4; i++) {
if (Math.random() > 0.66) {
ctx.addEntity(new GibletEntity(`giblets.${this.sprite.spriteKey}.leg.default.0`, dir+Math.random()*40, force+Math.random()*10), 'objects', p[0], p[1])
}
}
// 35% extra gibs per 8
for (let i = 0; i < 8; i++) {
if (Math.random() > 0.65) {
ctx.addEntity(new GibletEntity(`giblets.any.chunk${Math.floor(1+Math.random()*4)}.default.0`, dir+Math.random()*40, force+Math.random()*10), 'objects', p[0], p[1])
}
}
playSound(`action/splat-v${1+Math.floor(Math.random()*7)}`, 0.5)
}
}
export function isAnimalEntity(o: any): o is AnimalEntity {

View File

@ -24,6 +24,7 @@ export class Entity {
turnRate: number = 10
zones: Zone[] = []
contacts: Entity[] = []
shouldRemove: boolean = false
constructor(ctor: string) {
this.sprite = new SpriteInstance(ctor)

View File

@ -0,0 +1,32 @@
import * as planck from 'planck'
import { Entity } from "./Entity"
import { WorldContext } from "./World"
export class GibletEntity extends Entity {
lifetime: number = 10000
elapsed: number = 0
constructor(ctor: string, dir: number, force: number) {
super(ctor)
console.log('dir', dir, 'force', force)
let r = dir * (Math.PI/180)
this.velocity[0] = Math.cos(r) * force
this.velocity[1] = Math.sin(r) * force
console.log('velocity', this.velocity)
}
update(delta: number, ctx?: WorldContext) {
super.update(delta)
this.elapsed += delta
this.velocity[0] *= 0.85
this.velocity[1] *= 0.85
// Eh... let's manually handle velocity
this.x += this.velocity[0]
this.y += this.velocity[1]
if (this.elapsed >= this.lifetime) {
ctx?.removeEntity(this)
}
}
}

View File

@ -14,6 +14,7 @@ import { AnimalEntity, isAnimalEntity } from "../live/AnimalEntity"
import { Action, adjustAction } from "../live/Action"
import { WorldContext } from "../live/World"
import { animals } from "../data/animals"
import { GibletEntity } from "../live/GibletEntity"
export interface PIXIMissingColorMatrix extends PIXI.Filter {
night(intensity: number, multiply: boolean): void
@ -46,7 +47,15 @@ export function GameState(ctx: ContextI, selectedAnimal: string, selectedSegment
})
let worldBody: planck.Body = world.createBody({
type: 'static',
linearDamping: 1,
})
worldBody.setPosition(planck.Vec2(0, 0))
let worldFixture = worldBody.createFixture({
shape: planck.Box(1, 1),
friction: 10,
density: 100,
})
world.on('begin-contact', (contact: planck.Contact) => {
let a = contact.getFixtureA().getUserData()
let b = contact.getFixtureB().getUserData()
@ -199,7 +208,14 @@ export function GameState(ctx: ContextI, selectedAnimal: string, selectedSegment
let x = bounds[0] + Math.floor(Math.random() * bounds[2])
let y = bounds[1] + Math.floor(Math.random() * bounds[3])
addEntity(new AnimalEntity(animals[animal]), 'objects', x, y)
let entity = new AnimalEntity(animals[animal])
setTimeout(() => {
entity.dead = true
entity.shouldGib = true
}, 1000+Math.random()*3000)
addEntity(entity, 'objects', x, y)
}
}
ctx.app.stage.addChild(rootContainer)
@ -231,9 +247,9 @@ export function GameState(ctx: ContextI, selectedAnimal: string, selectedSegment
nightfall(true)
}
// Run world sim.
while (elapsed >= 1/2) {
world.step(1/2)
elapsed -= 1/2
while (elapsed >= 1/6) {
world.step(1/6)
elapsed -= 1/6
}
// Update/render.
/*for (let layer of layers) {
@ -260,6 +276,15 @@ export function GameState(ctx: ContextI, selectedAnimal: string, selectedSegment
entity.sprite.container.y = entity.y
entity.sprite.container.zIndex = entity.y + (entity.sprite.frame?entity.sprite.frame.originY??0:0)
}
// I guess this is okay.
for (let entity of entities) {
if (entity.shouldRemove) {
if (entity instanceof AnimalEntity) {
removeEntity(entity)
}
}
}
//entities = entities.filter(v=>v.shouldRemove)
}
let addEntity = (entity: Entity, layerTitle: string, x: number, y: number) => {