From 4443ca205812f4da4aa0ed1bf4897e731107616b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 21 Nov 2018 19:50:59 +0100 Subject: Move immutable parts of EntityContext into a new EntityView class --- src/controller/entitycontext.ts | 39 +++--------------- src/view/entity.ts | 87 +++++++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 58 deletions(-) diff --git a/src/controller/entitycontext.ts b/src/controller/entitycontext.ts index 6932227..434bf9b 100644 --- a/src/controller/entitycontext.ts +++ b/src/controller/entitycontext.ts @@ -1,49 +1,36 @@ -import { EntityAnimation, EntityData } from '../model/data/entity'; - -import { loadEntity } from '../view/entity'; +import { EntityView } from '../view/entity'; import { Renderer } from '../view/renderer/renderer'; -import { SpriteView } from '../view/sprite'; import { Collidable } from '../math/collision'; -import { getJSON } from '../util'; import { CollidableGroup, mkCollision } from './collision'; import { vec2 } from 'gl-matrix'; export class EntityContext implements CollidableGroup { public static async load(renderer: Renderer, name: string): Promise { - const entity = new EntityData(await getJSON(`resources/entity/${name}.json`)); - return new EntityContext( renderer, name, - await loadEntity(renderer, entity), - mkCollision(entity.collision), - entity.animation, + await EntityView.load(renderer, name), ); } public readonly pos: vec2 = vec2.create(); - private readonly totalTime: number; + private readonly collision: Collidable[]; private constructor( private readonly renderer: Renderer, private readonly name: string, - private readonly sprites: SpriteView[], - private readonly collision: Collidable[], - private readonly animation?: EntityAnimation, + private readonly view: EntityView, ) { - if (animation) - this.totalTime = animation.sequence.reduce((a, s) => a + s[0], 0); - else - this.totalTime = 0; + this.collision = mkCollision(view.data.collision); } public render(time: number) { this.renderer.setTranslation(this.pos); - this.getSprite(time).render(); + this.view.renderByTime(time); } public getTranslation(): vec2 { @@ -57,18 +44,4 @@ export class EntityContext implements CollidableGroup { public interact() { alert(`You've interacted with ${this.name}!`); } - - private getSprite(time: number): SpriteView { - time %= this.totalTime; - - if (this.animation) { - for (const [len, sprite] of this.animation.sequence) { - time -= len; - if (time < 0) - return this.sprites[sprite]; - } - } - - return this.sprites[0]; - } } diff --git a/src/view/entity.ts b/src/view/entity.ts index 3b30e3c..ec91503 100644 --- a/src/view/entity.ts +++ b/src/view/entity.ts @@ -3,33 +3,70 @@ import { Renderer } from './renderer/renderer'; import { SpriteCoords, SpriteView, SpriteViewBuilder } from './sprite'; import { loadImage, mkTexture } from './util/image'; +import { getJSON } from '../util'; + import { vec2 } from 'gl-matrix'; -export async function loadEntity( - r: Renderer, - data: EntityData, -): Promise { - const tile = await loadImage(`resources/sprite/entity/${data.sprite}.png`); - const [texture, size] = mkTexture(r, tile); - const frameSize = [size[0], size[1] / data.frames]; - - const offset = vec2.mul(vec2.create(), frameSize, data.anchor); - r.snapToGrid(offset, offset); - - const coords: SpriteCoords = [ - -offset[0], - -offset[1], - -offset[0] + frameSize[0], - -offset[1] + frameSize[1], - ]; - - const sprites: SpriteView[] = []; - - for (let frame = 0; frame < data.frames; frame++) { - const builder = new SpriteViewBuilder(r, texture); - builder.addSprite(coords, [0, frame / data.frames, 1, (frame + 1) / data.frames]); - sprites.push(builder.build()); +export class EntityView { + public static async load(r: Renderer, name: string): Promise { + const data = new EntityData(await getJSON(`resources/entity/${name}.json`)); + const tile = await loadImage(`resources/sprite/entity/${data.sprite}.png`); + + const [texture, size] = mkTexture(r, tile); + const frameSize = [size[0], size[1] / data.frames]; + + const offset = vec2.mul(vec2.create(), frameSize, data.anchor); + r.snapToGrid(offset, offset); + + const coords: SpriteCoords = [ + -offset[0], + -offset[1], + -offset[0] + frameSize[0], + -offset[1] + frameSize[1], + ]; + + const sprites: SpriteView[] = []; + + for (let frame = 0; frame < data.frames; frame++) { + const builder = new SpriteViewBuilder(r, texture); + builder.addSprite(coords, [0, frame / data.frames, 1, (frame + 1) / data.frames]); + sprites.push(builder.build()); + } + + return new EntityView( + data, + sprites, + ); + } + + private readonly totalTime: number; + + private constructor( + public readonly data: EntityData, + public readonly sprites: SpriteView[], + ) { + if (data.animation) + this.totalTime = data.animation.sequence.reduce((a, s) => a + s[0], 0); + else + this.totalTime = 0; + } + + public getSpriteByTime(time: number): SpriteView { + time %= this.totalTime; + + if (this.data.animation) { + for (const [len, sprite] of this.data.animation.sequence) { + time -= len; + if (time < 0) + return this.sprites[sprite]; + } + } + + return this.sprites[0]; + } + + public renderByTime(time: number) { + this.getSpriteByTime(time).render(); } - return sprites; } -- cgit v1.2.3