Too many changes

This commit is contained in:
Ketchetwahmeegwun T. Southall 2022-01-29 21:43:20 -08:00
parent a87d44aa82
commit 581da1473d
6 changed files with 154 additions and 35 deletions

View File

@ -1,5 +1,7 @@
import * as planck from 'planck'
import { SpriteInstance } from '../shared/sprites'
import { WorldContext } from './World'
import { Zone } from './Zone'
export class Entity {
sprite: SpriteInstance
@ -9,13 +11,15 @@ export class Entity {
maxSpeed: number = 4
direction: number = 0
turnRate: number = 10
zones: Zone[] = []
contacts: Entity[] = []
constructor(ctor: string) {
this.sprite = new SpriteInstance(ctor)
}
update(delta: number) {
// TODO: Update sprite.
update(delta: number, ctx?: WorldContext) {
this.sprite.update(delta)
}
get position(): [number, number] {
@ -65,4 +69,18 @@ export class Entity {
this.sprite.container.y = v
}
}
addZoneContact(zone: Zone) {
if (this.zones.find(v=>v===zone)) return
this.zones.push(zone)
}
removeZoneContact(zone: Zone) {
this.zones = this.zones.filter(v=>v!==zone)
}
addEntityContact(entity: Entity) {
if (this.contacts.find(v=>v===entity)) return
this.contacts.push(entity)
}
removeEntityContact(entity: Entity) {
this.contacts = this.contacts.filter(v=>v!==entity)
}
}

View File

@ -1,9 +1,12 @@
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)
}
@ -18,10 +21,23 @@ export class PlayerEntity extends Entity {
return 0
})[0]
}
update(delta: number) {
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) {
ctx.addEntity(new PuddleEntity('effects.water.ripple.small.0'), this.x, this.y)
console.log('add ripple')
}
this.puddleTimer = 0
}
}
let shouldMove = false
if (this.action) {
// FIXME: Use physics.
let shouldMove = false
switch(this.action.type) {
case 'west':
if (this.direction !== 0) {
@ -69,19 +85,26 @@ export class PlayerEntity extends Entity {
} 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}`)
}
}
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`)
}
//
@ -92,25 +115,17 @@ export class PlayerEntity extends Entity {
this.body?.setLinearVelocity(planck.Vec2(this.velocity[0], this.velocity[1]))
}
getCardinal(): string {
const degreesPerDirection = 360 / 8
const degreesPerDirection = 360 / 4
const angle = this.direction + degreesPerDirection / 2
if (angle >= 0 * degreesPerDirection && angle < 1 * degreesPerDirection) {
return 'w'
return 'west'
} else if (angle >= 1 * degreesPerDirection && angle < 2 * degreesPerDirection) {
return 'nw'
return 'north'
} 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 'east'
}
return 'sw'
return 'south'
}
}

View File

@ -0,0 +1,20 @@
import { Entity } from "./Entity"
import { WorldContext } from "./World"
export class PuddleEntity extends Entity {
lifetime: number = 400
elapsed: number = 0
constructor(ctor: string) {
super(ctor)
console.log(this.sprite)
}
update(delta: number, ctx?: WorldContext) {
super.update(delta)
this.elapsed += delta
if (this.elapsed >= this.lifetime) {
console.log('ah, remove ourself')
ctx?.removeEntity(this)
}
}
}

6
Engine/src/live/World.ts Normal file
View File

@ -0,0 +1,6 @@
import { Entity } from "./Entity"
export interface WorldContext {
addEntity(entity: Entity, x: number, y: number): void
removeEntity(entity: Entity): void
}

View File

@ -20,6 +20,9 @@ export class SpriteInstance {
subsetKey: string = ''
frame?: SpritePart
frameIndex: number = 0
frameCount: number = 0
animate: boolean = true
elapsed: number = 0
constructor(ctor: string) {
this.container = new PIXI.Container()
@ -34,6 +37,7 @@ export class SpriteInstance {
this.setKey = setKey
this.subsetKey = subsetKey
this.frameIndex = Number(frameKey)
this.frameCount = 0
this.sprite = sprites[spriteKey]
if (!this.sprite) {
this.container.addChild(new PIXI.Text('missing sprite'))
@ -44,6 +48,7 @@ export class SpriteInstance {
this.subset = this.set.children[subsetKey]
//
if (this.subset.frames) {
this.frameCount = this.subset.frames.length
this.frame = this.subset.frames[this.frameIndex]
let s = new PIXI.Sprite(this.frame.texture)
s.x -= this.frame.originX
@ -52,6 +57,19 @@ export class SpriteInstance {
}
}
update(delta: number) {
if (!this.animate) return
this.elapsed += delta
while (this.frameCount > 0 && this.frame && this.elapsed >= this.frame.time && this.frame.time > 0) {
this.elapsed -= this.frame.time
this.frameIndex++
if (this.frameIndex >= this.frameCount) {
this.frameIndex = 0
}
this.setCtor(`${this.spriteKey}.${this.animationKey}.${this.setKey}.${this.subsetKey}.${this.frameIndex}`)
}
}
getBodyShape(): Shape|undefined {
if (this.frame && this.frame.shapes) {
return this.frame.shapes.find(v=>v.key==='body')

View File

@ -12,6 +12,7 @@ import { Zone } from "../live/Zone"
import { Entity } from "../live/Entity"
import { isPlayerEntity, PlayerEntity } from "../live/PlayerEntity"
import { Action } from "../live/Action"
import { WorldContext } from "../live/World"
export interface PIXIMissingColorMatrix extends PIXI.Filter {
night(intensity: number, multiply: boolean): void
@ -34,8 +35,9 @@ export function GameState(ctx: ContextI): StateI {
//disableSound()
let isNight = false
let modeTimer = 0
let nightTime = 10 * 60
let dayTime = 10 * 60
let nightTime = 10 * 1000
let dayTime = 10 * 1000
let lastTime: number = performance.now()
let world: planck.World = planck.World({
gravity: planck.Vec2(0, 0),
@ -43,6 +45,34 @@ export function GameState(ctx: ContextI): StateI {
let worldBody: planck.Body = world.createBody({
type: 'static',
})
world.on('begin-contact', (contact: planck.Contact) => {
let a = contact.getFixtureA().getUserData()
let b = contact.getFixtureB().getUserData()
if (a instanceof Zone) {
if (b instanceof Entity) {
b.addZoneContact(a)
}
} else if (a instanceof Entity) {
if (b instanceof Entity) {
a.addEntityContact(b)
b.addEntityContact(a)
}
}
})
world.on('end-contact', (contact: planck.Contact) => {
let a = contact.getFixtureA().getUserData()
let b = contact.getFixtureB().getUserData()
if (a instanceof Zone) {
if (b instanceof Entity) {
b.removeZoneContact(a)
}
} else if (a instanceof Entity) {
if (b instanceof Entity) {
a.removeEntityContact(b)
b.removeEntityContact(a)
}
}
})
let rootContainer = new PIXI.Container()
let playLayer: Layer
@ -51,6 +81,7 @@ export function GameState(ctx: ContextI): StateI {
let zones: Zone[] = []
let enter = () => {
lastTime = performance.now()
hookKeyboard()
// Load the world segment.
let w = segments.world
@ -115,7 +146,7 @@ export function GameState(ctx: ContextI): StateI {
}
// Add bogus entity
addEntity(new PlayerEntity('bogus-arrows.player.normal.w.0'), 0, 0)
addEntity(new PlayerEntity('deer.animal.stand.west.0'), 300, 100)
ctx.app.stage.addChild(rootContainer)
}
@ -128,9 +159,12 @@ export function GameState(ctx: ContextI): StateI {
}
let elapsed: number = 0
let update = (delta: number) => {
let time = performance.now()
let realDelta = time - lastTime
lastTime = time
checkGamepads()
elapsed += delta
modeTimer += delta
modeTimer += realDelta
if (isNight && modeTimer >= nightTime) {
modeTimer = 0
nightfall(false)
@ -146,7 +180,7 @@ export function GameState(ctx: ContextI): StateI {
// Update/render.
for (let layer of layers) {
for (let decoration of layer.decorations) {
decoration.update(delta)
decoration.update(realDelta)
}
}
for (let entity of entities) {
@ -156,7 +190,7 @@ export function GameState(ctx: ContextI): StateI {
rootContainer.position.set(Math.round(ctx.app.renderer.width/2), Math.round(ctx.app.renderer.height/2))
rootContainer.pivot.set(Math.max(rootContainer.width/6, Math.min(entity.x, rootContainer.width/3)), Math.max(rootContainer.height/6, Math.min(entity.y, rootContainer.height/3)))
}
entity.update(delta)
entity.update(realDelta, worldContext)
// I guess...
entity.sprite.container.x = entity.x
entity.sprite.container.y = entity.y
@ -166,6 +200,7 @@ export function GameState(ctx: ContextI): StateI {
let addEntity = (entity: Entity, x: number, y: number) => {
if (entities.find(v=>v===entity)) return
console.log('add somethin', entity)
entities.push(entity)
playLayer.container.addChild(entity.sprite.container)
// I guess this is a fair enough place to create physics and add it to the entity.
@ -188,6 +223,7 @@ export function GameState(ctx: ContextI): StateI {
friction: 0.9,
restitution: 0.05,
})
fixture.setUserData(entity)
entity.body = body
body.setUserData(entity)
}
@ -214,6 +250,7 @@ export function GameState(ctx: ContextI): StateI {
if (zone.type === 'fluid') {
zone.fixture.setSensor(true)
}
zone.fixture.setUserData(zone)
}
let removeZone = (zone: Zone) => {
zones = zones.filter(v=>v!==zone)
@ -222,6 +259,11 @@ export function GameState(ctx: ContextI): StateI {
}
}
let worldContext: WorldContext = {
addEntity,
removeEntity,
}
let desiredActions: Action[] = []
let adjustAction = (type: string, v: number, inc?: boolean) => {
let action = desiredActions.find(v=>v.type===type)