Add some entity garbage
This commit is contained in:
parent
09d8152c6c
commit
84eadde101
94
Engine/src/data/sprite.ts
Normal file
94
Engine/src/data/sprite.ts
Normal 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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import { MenuState } from './states/Menu'
|
||||||
import { StateI } from './states/StateI'
|
import { StateI } from './states/StateI'
|
||||||
import { decors } from './shared/decors'
|
import { decors } from './shared/decors'
|
||||||
import { segments } from './shared/segments'
|
import { segments } from './shared/segments'
|
||||||
|
import { sprites } from './shared/sprites'
|
||||||
|
|
||||||
export class Engine {
|
export class Engine {
|
||||||
ctx: ContextI
|
ctx: ContextI
|
||||||
|
@ -19,6 +20,7 @@ export class Engine {
|
||||||
console.log(
|
console.log(
|
||||||
decors,
|
decors,
|
||||||
segments,
|
segments,
|
||||||
|
sprites,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
|
|
35
Engine/src/shared/sprites.ts
Normal file
35
Engine/src/shared/sprites.ts
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,14 +3,89 @@ import { segments } from "../shared/segments"
|
||||||
import { StateI } from "./StateI"
|
import { StateI } from "./StateI"
|
||||||
import * as PIXI from 'pixi.js'
|
import * as PIXI from 'pixi.js'
|
||||||
import { DecorationInstance } from "../shared/decors"
|
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 {
|
export function GameState(ctx: ContextI): StateI {
|
||||||
|
|
||||||
let rootContainer = new PIXI.Container()
|
let rootContainer = new PIXI.Container()
|
||||||
let decorations: DecorationInstance[] = []
|
let decorations: DecorationInstance[] = []
|
||||||
|
let entities: Entity[] = []
|
||||||
|
|
||||||
let enter = () => {
|
let enter = () => {
|
||||||
console.log('less goooo')
|
hookKeyboard()
|
||||||
// Load the world segment.
|
// Load the world segment.
|
||||||
let w = segments.world
|
let w = segments.world
|
||||||
if (!w) return ctx.pop()
|
if (!w) return ctx.pop()
|
||||||
|
@ -28,7 +103,6 @@ export function GameState(ctx: ContextI): StateI {
|
||||||
di.container.x = d.x
|
di.container.x = d.x
|
||||||
di.container.y = d.y
|
di.container.y = d.y
|
||||||
if (d.flip) {
|
if (d.flip) {
|
||||||
console.log('friggin flip it')
|
|
||||||
di.container.pivot.y = 1
|
di.container.pivot.y = 1
|
||||||
di.container.scale.y *= -1
|
di.container.scale.y *= -1
|
||||||
di.container.position.y--
|
di.container.position.y--
|
||||||
|
@ -46,15 +120,88 @@ export function GameState(ctx: ContextI): StateI {
|
||||||
rootContainer.addChild(container)
|
rootContainer.addChild(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add bogus entity
|
||||||
|
addEntity(new PlayerEntity('animals.deer.animal.west.0'))
|
||||||
|
|
||||||
ctx.app.stage.addChild(rootContainer)
|
ctx.app.stage.addChild(rootContainer)
|
||||||
}
|
}
|
||||||
let leave = () => {
|
let leave = () => {
|
||||||
|
unhookKeyboard()
|
||||||
|
for (let entity of entities) {
|
||||||
|
removeEntity(entity)
|
||||||
|
}
|
||||||
ctx.app.stage.removeChild(rootContainer)
|
ctx.app.stage.removeChild(rootContainer)
|
||||||
}
|
}
|
||||||
let update = (delta: number) => {
|
let update = (delta: number) => {
|
||||||
for (let decoration of decorations) {
|
for (let decoration of decorations) {
|
||||||
decoration.update(delta)
|
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 {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user