diff --git a/Engine/src/data/decor.ts b/Engine/src/data/decor.ts index 851bd54..9e511c6 100644 --- a/Engine/src/data/decor.ts +++ b/Engine/src/data/decor.ts @@ -1,11 +1,14 @@ import * as PIXI from 'pixi.js' export class Decor { + uuid: string texture: PIXI.Texture decorations: Decoration[] = [] constructor(o: any) { + this.uuid = o.uuid this.texture = PIXI.Texture.from('./Assets/Decors/'+o.image) + this.texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST // Load decorations. for (let d of o.decorations) { this.decorations.push(new Decoration(this.texture.baseTexture, d)) @@ -14,8 +17,18 @@ export class Decor { } export class Decoration { + uuid: string frames: DecorationFrame[] = [] + width: number = 0 + height: number = 0 + timeOffset: number = 0 constructor(t: PIXI.BaseTexture, o: any) { + this.width = o.width + this.height = o.height + this.uuid = o.uuid + if (!isNaN(o.timeOffset)) { + this.timeOffset = o.timeOffset + } for (let frame of o.frames) { this.frames.push(new DecorationFrame(t, frame)) } diff --git a/Engine/src/data/segment.ts b/Engine/src/data/segment.ts new file mode 100644 index 0000000..f591aa2 --- /dev/null +++ b/Engine/src/data/segment.ts @@ -0,0 +1,71 @@ +export class Segment { + title: string + width: number + height: number + bg: string | string[] + zones: Zone[] = [] + layers: SegmentLayer[] = [] + + constructor(o: any) { + this.title = o.title + this.height = o.rows * o.cellHeight + this.width = o.columns * o.cellWidth + this.bg = o.backgroundColor + + for (let z of o.zones) { + this.zones.push(new Zone(z)) + } + + for (let l of o.layers) { + this.layers.push(new SegmentLayer(l)) + } + } +} + +export class SegmentLayer { + title: string + darkness: number = 0 + contrast: number = 100 + decorations: SegmentDecoration[] = [] + + constructor(o: any) { + this.title = o.title + this.darkness = o.darkness + this.contrast = o.contrast + + for (let d of o.decorations) { + this.decorations.push(new SegmentDecoration(d)) + } + } +} + +export class SegmentDecoration { + decor: string + decoration: string + x: number + y: number + mirror: boolean + flip: boolean + timeOffset: number = 0 + speed: number = 1.0 + constructor(o: any) { + this.decor = o.decor + this.decoration = o.decoration + this.x = o.x + this.y = o.y + this.mirror = o.mirror + this.flip = o.flip + if (!isNaN(o.timeOffset)) { + this.timeOffset = o.timeOffset + } + if (!isNaN(o.speed)) { + this.speed = o.speed + } + } +} + +export class Zone { + constructor(o: any) { + // ??? + } +} \ No newline at end of file diff --git a/Engine/src/engine.ts b/Engine/src/engine.ts index 8a6f7d8..dd51f7d 100644 --- a/Engine/src/engine.ts +++ b/Engine/src/engine.ts @@ -2,7 +2,8 @@ import * as PIXI from 'pixi.js' import { ContextI } from './ContextI' import { MenuState } from './states/Menu' import { StateI } from './states/StateI' -import decors from './shared/decors' +import { decors } from './shared/decors' +import { segments } from './shared/segments' export class Engine { ctx: ContextI @@ -15,6 +16,11 @@ export class Engine { constructor(target: HTMLElement) { this.element = target + console.log( + decors, + segments, + ) + // Setup this.states = [] this.ctx = { diff --git a/Engine/src/shared/decors.ts b/Engine/src/shared/decors.ts index bd7ccaa..1267e60 100644 --- a/Engine/src/shared/decors.ts +++ b/Engine/src/shared/decors.ts @@ -1,10 +1,104 @@ import assets from '../../../Assets/Decors/**/*.yaml' import { Decor } from '../data/decor' +import * as PIXI from 'pixi.js' -const decors: Record = {} +export const decors: Record = {} for (let [key, value] of Object.entries(assets)) { decors[key] = new Decor(value) } -export default decors \ No newline at end of file +export interface DecorationFrame { + time: number + container: PIXI.Container + sprites: (PIXI.Sprite|PIXI.Text)[] +} + +export class DecorationInstance { + elapsed: number = 0 + container: PIXI.Container + frames: DecorationFrame[] = [] + frameIndex: number = 0 + constructor(decorUUID: string, decorationUUID: string) { + this.container = new PIXI.Container() + let found = false + for (let decor of Object.values(decors)) { + if (decor.uuid === decorUUID) { + for (let decoration of decor.decorations) { + if (decoration.uuid === decorationUUID) { + this.container.width = decoration.width + this.container.height = decoration.height + + for (let frame of decoration.frames) { + let frameInstance: DecorationFrame = { + time: frame.time, + container: new PIXI.Container(), + sprites: frame.parts.map(v => { + let sprite = PIXI.Sprite.from(v.texture) + sprite.pivot.x += sprite.width/2 + sprite.pivot.y += sprite.height/2 + sprite.x = v.x + sprite.y = v.y + sprite.rotation = v.rotation + sprite.alpha = v.alpha + /*if (v.flip) { + sprite.pivot.y = -sprite.height + sprite.y += sprite.pivot.y + } + if (v.mirror) { + sprite.pivot.x = -sprite.width + sprite.x += sprite.pivot.x + }*/ + // TODO: mirror and flip + return sprite + }) + } + frameInstance.container.width = decoration.width + frameInstance.container.height = decoration.height + for (let s of frameInstance.sprites){ + frameInstance.container.addChild(s) + } + this.frames.push(frameInstance) + } + + found = true + break + } + } + } + if (found) { + break + } + } + if (!found) { + console.log('failed to find', decorUUID, decorationUUID) + // bogus sprite + let t = new PIXI.Text('missing') + this.frames.push({ + time: 0, + container: new PIXI.Container(), + sprites: [t], + }) + this.frames[this.frames.length-1].container.addChild(t) + } + // Add first frame to container. + if (this.frames.length > 0) { + this.container.addChild(this.frames[0].container) + } + } + update(delta: number) { + if (this.frames.length <= 1) return + this.elapsed += delta + let frameIndex = this.frameIndex + while (this.elapsed >= this.frames[frameIndex].time) { + this.elapsed -= this.frames[frameIndex].time + frameIndex++ + if (frameIndex >= this.frames.length) { + frameIndex = 0 + } + this.container.removeChild(this.frames[this.frameIndex].container) + this.frameIndex = frameIndex + this.container.addChild(this.frames[this.frameIndex].container) + } + } +} diff --git a/Engine/src/shared/segments.ts b/Engine/src/shared/segments.ts new file mode 100644 index 0000000..fe7326a --- /dev/null +++ b/Engine/src/shared/segments.ts @@ -0,0 +1,9 @@ +import assets from '../../../Assets/Segments/**/*.yaml' +import { Segment } from '../data/segment' + +export const segments: Record = {} +console.log('assets should be loaded', assets) + +for (let [key, value] of Object.entries(assets)) { + segments[key] = new Segment(value) +} diff --git a/Engine/src/states/Game.ts b/Engine/src/states/Game.ts index e7257bd..f418d08 100644 --- a/Engine/src/states/Game.ts +++ b/Engine/src/states/Game.ts @@ -1,14 +1,60 @@ import { ContextI } from "../ContextI" +import { segments } from "../shared/segments" import { StateI } from "./StateI" +import * as PIXI from 'pixi.js' +import { DecorationInstance } from "../shared/decors" export function GameState(ctx: ContextI): StateI { + let rootContainer = new PIXI.Container() + let decorations: DecorationInstance[] = [] + let enter = () => { console.log('less goooo') + // Load the world segment. + let w = segments.world + if (!w) return ctx.pop() + rootContainer.width = w.width + rootContainer.height = w.height + rootContainer.scale.set(2, 2) + for (let l of w.layers) { + let container = new PIXI.Container() + container.width = w.width + container.height = w.height + + for (let d of l.decorations) { + let di = new DecorationInstance(d.decor, d.decoration) + di.elapsed = d.timeOffset + 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-- + } + if (d.mirror) { + di.container.pivot.x = 1 + di.container.scale.x *= -1 + di.container.position.x-- + } + + container.addChild(di.container) + decorations.push(di) + } + + rootContainer.addChild(container) + } + + ctx.app.stage.addChild(rootContainer) } let leave = () => { + ctx.app.stage.removeChild(rootContainer) } let update = (delta: number) => { + for (let decoration of decorations) { + decoration.update(delta) + } } return {