Add some entity garbage

This commit is contained in:
Ketchetwahmeegwun T. Southall 2022-01-29 04:57:01 -08:00
parent 09d8152c6c
commit 84eadde101
4 changed files with 280 additions and 2 deletions

94
Engine/src/data/sprite.ts Normal file
View File

@ -0,0 +1,94 @@
import * as PIXI from 'pixi.js'
export class Sprite {
uuid: string
texture: PIXI.Texture
originX: number = 0
originY: number = 0
x: number = 0
y: number = 0
width: number = 0
height: number = 0
root: SpritePart
constructor(o: any) {
this.uuid = o.uuid
this.texture = PIXI.Texture.from('./Assets/Sprites/'+o.source)
this.texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST
this.root = new SpritePart(o, {
texture: this.texture,
originX: 0,
originY: 0,
x: 0,
y: 0,
width: 0,
height: 0,
time: 0,
source: '',
}, this.texture)
}
}
export interface SpritePartI {
texture: PIXI.Texture
originX: number
originY: number
x: number
y: number
width: number
height: number
time: number
source: string
children?: Record<string, SpritePart>
}
export class SpritePart {
texture: PIXI.Texture
originX: number = 0
originY: number = 0
x: number = 0
y: number = 0
width: number = 0
height: number = 0
time: number = 0
source: string = ''
children: Record<string, SpritePart> = {}
frames?: SpritePart[]
constructor(o: any, p: SpritePartI, t: PIXI.Texture) {
this.time = o.time ?? p.time
this.x = o.x ?? p.x
this.y = o.y ?? p.y
this.width = o.width ?? p.width
this.height = o.height ?? p.height
this.originX = o.origin_x ?? p.originX
this.originY = o.origin_y ?? p.originY
if (o.source) {
t = PIXI.Texture.from('./Assets/Sprites/'+o.source)
t.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST
}
if (this.x === p.x && this.y === p.y && this.width === p.width && this.height === p.height && o.source === p.source) {
this.texture = p.texture
} else {
this.texture = new PIXI.Texture(t.baseTexture, new PIXI.Rectangle(this.x, this.y, this.width, this.height))
}
if (o.animations) {
for (let [key, value] of Object.entries(o.animations)) {
this.children[key] = new SpritePart(value, this, t)
}
} else if (o.sets) {
for (let [key, value] of Object.entries(o.sets)) {
this.children[key] = new SpritePart(value, this, t)
}
} else if (o.subsets) {
for (let [key, value] of Object.entries(o.subsets)) {
this.children[key] = new SpritePart(value, this, t)
}
} else if (o.frames) {
this.frames = o.frames.map((v: any) => {
return new SpritePart(v, this, t)
})
}
}
}

View File

@ -4,6 +4,7 @@ import { MenuState } from './states/Menu'
import { StateI } from './states/StateI'
import { decors } from './shared/decors'
import { segments } from './shared/segments'
import { sprites } from './shared/sprites'
export class Engine {
ctx: ContextI
@ -19,6 +20,7 @@ export class Engine {
console.log(
decors,
segments,
sprites,
)
// Setup

View File

@ -0,0 +1,35 @@
import assets from '../../../Assets/Sprites/**/*.yaml'
import { Sprite } from '../data/sprite'
import * as PIXI from 'pixi.js'
export const sprites: Record<string, Sprite> = {}
for (let [key, value] of Object.entries(assets)) {
sprites[key] = new Sprite(value)
}
export class SpriteInstance {
container: PIXI.Container
constructor(ctor: string) {
this.container = new PIXI.Container()
let [spriteKey, animationKey, setKey, subsetKey, frameKey] = ctor.split('.')
let frameIndex = Number(frameKey)
let sprite = sprites[spriteKey]
if (!sprite) {
this.container.addChild(new PIXI.Text('missing sprite'))
return
}
let animation = sprite.root.children[animationKey]
let set = animation.children[setKey]
let subset = set.children[subsetKey]
//
if (subset.frames) {
let frame = subset.frames[frameIndex]
let s = new PIXI.Sprite(frame.texture)
s.x -= frame.originX
s.y -= frame.originY
this.container.addChild(s)
}
}
}

View File

@ -3,14 +3,89 @@ import { segments } from "../shared/segments"
import { StateI } from "./StateI"
import * as PIXI from 'pixi.js'
import { DecorationInstance } from "../shared/decors"
import { SpriteInstance } from "../shared/sprites"
interface Action {
type: string
priority: number
}
class Entity {
sprite: SpriteInstance
constructor(ctor: string) {
this.sprite = new SpriteInstance(ctor)
}
update(delta: number) {
// TODO: Update sprite.
}
get x(): number {
return this.sprite.container.x
}
set x(v: number) {
this.sprite.container.x = v
}
get y(): number {
return this.sprite.container.y
}
set y(v: number) {
this.sprite.container.y = v
}
}
class PlayerEntity extends Entity {
action?: Action
constructor(ctor: string) {
super(ctor)
this.x = 100
this.y = 100
// TODO: Hooks for key state check input, perhaps?
}
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.
switch(this.action.type) {
case 'west':
this.x--
break
case 'east':
this.x++
break
case 'north':
this.y--
break
case 'south':
this.y++
break
}
}
}
}
function isPlayerEntity(o: any): o is PlayerEntity {
return o.act
}
export function GameState(ctx: ContextI): StateI {
let rootContainer = new PIXI.Container()
let decorations: DecorationInstance[] = []
let entities: Entity[] = []
let enter = () => {
console.log('less goooo')
hookKeyboard()
// Load the world segment.
let w = segments.world
if (!w) return ctx.pop()
@ -28,7 +103,6 @@ export function GameState(ctx: ContextI): StateI {
di.container.x = d.x
di.container.y = d.y
if (d.flip) {
console.log('friggin flip it')
di.container.pivot.y = 1
di.container.scale.y *= -1
di.container.position.y--
@ -46,15 +120,88 @@ export function GameState(ctx: ContextI): StateI {
rootContainer.addChild(container)
}
// Add bogus entity
addEntity(new PlayerEntity('animals.deer.animal.west.0'))
ctx.app.stage.addChild(rootContainer)
}
let leave = () => {
unhookKeyboard()
for (let entity of entities) {
removeEntity(entity)
}
ctx.app.stage.removeChild(rootContainer)
}
let update = (delta: number) => {
for (let decoration of decorations) {
decoration.update(delta)
}
for (let entity of entities) {
if (isPlayerEntity(entity)) {
entity.act(desiredActions)
// FIXME: This isn't the right place for this.
rootContainer.position.set(Math.round(ctx.app.renderer.width/2), Math.round(ctx.app.renderer.height/2))
rootContainer.pivot.set(entity.x, entity.y)
}
entity.update(delta)
}
}
let addEntity = (entity: Entity) => {
if (entities.find(v=>v===entity)) return
entities.push(entity)
rootContainer.addChild(entity.sprite.container)
}
let removeEntity = (entity: Entity) => {
entities = entities.filter(v=>v!==entity)
rootContainer.removeChild(entity.sprite.container)
}
let desiredActions: Action[] = []
let adjustAction = (type: string, v: number) => {
let action = desiredActions.find(v=>v.type===type)
if (!action) {
desiredActions.push({
type: type,
priority: v,
})
} else {
action.priority += v
if (action.priority <= 0) {
desiredActions = desiredActions.filter(v=>v!==action)
}
}
}
let keyup = (e: KeyboardEvent) => {
if (e.key === 'ArrowLeft') {
adjustAction('west', -1)
} else if (e.key === 'ArrowRight') {
adjustAction('east', -1)
} else if (e.key === 'ArrowUp') {
adjustAction('north', -1)
} else if (e.key === 'ArrowDown') {
adjustAction('south', -1)
}
}
let keydown = (e: KeyboardEvent) => {
if (e.repeat) return
if (e.key === 'ArrowLeft') {
adjustAction('west', 1)
} else if (e.key === 'ArrowRight') {
adjustAction('east', 1)
} else if (e.key === 'ArrowUp') {
adjustAction('north', 1)
} else if (e.key === 'ArrowDown') {
adjustAction('south', 1)
}
}
let hookKeyboard = () => {
window.addEventListener('keyup', keyup)
window.addEventListener('keydown', keydown)
}
let unhookKeyboard = () => {
window.removeEventListener('keyup', keyup)
window.removeEventListener('keydown', keydown)
}
return {