Move immutable parts of EntityContext into a new EntityView class
This commit is contained in:
parent
38e90fc2e3
commit
4443ca2058
2 changed files with 64 additions and 54 deletions
|
@ -1,49 +1,36 @@
|
||||||
import { EntityAnimation, EntityData } from '../model/data/entity';
|
import { EntityView } from '../view/entity';
|
||||||
|
|
||||||
import { loadEntity } from '../view/entity';
|
|
||||||
import { Renderer } from '../view/renderer/renderer';
|
import { Renderer } from '../view/renderer/renderer';
|
||||||
import { SpriteView } from '../view/sprite';
|
|
||||||
|
|
||||||
import { Collidable } from '../math/collision';
|
import { Collidable } from '../math/collision';
|
||||||
|
|
||||||
import { getJSON } from '../util';
|
|
||||||
import { CollidableGroup, mkCollision } from './collision';
|
import { CollidableGroup, mkCollision } from './collision';
|
||||||
|
|
||||||
import { vec2 } from 'gl-matrix';
|
import { vec2 } from 'gl-matrix';
|
||||||
|
|
||||||
export class EntityContext implements CollidableGroup {
|
export class EntityContext implements CollidableGroup {
|
||||||
public static async load(renderer: Renderer, name: string): Promise<EntityContext> {
|
public static async load(renderer: Renderer, name: string): Promise<EntityContext> {
|
||||||
const entity = new EntityData(await getJSON(`resources/entity/${name}.json`));
|
|
||||||
|
|
||||||
return new EntityContext(
|
return new EntityContext(
|
||||||
renderer,
|
renderer,
|
||||||
name,
|
name,
|
||||||
await loadEntity(renderer, entity),
|
await EntityView.load(renderer, name),
|
||||||
mkCollision(entity.collision),
|
|
||||||
entity.animation,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly pos: vec2 = vec2.create();
|
public readonly pos: vec2 = vec2.create();
|
||||||
|
|
||||||
private readonly totalTime: number;
|
private readonly collision: Collidable[];
|
||||||
|
|
||||||
private constructor(
|
private constructor(
|
||||||
private readonly renderer: Renderer,
|
private readonly renderer: Renderer,
|
||||||
private readonly name: string,
|
private readonly name: string,
|
||||||
private readonly sprites: SpriteView[],
|
private readonly view: EntityView,
|
||||||
private readonly collision: Collidable[],
|
|
||||||
private readonly animation?: EntityAnimation,
|
|
||||||
) {
|
) {
|
||||||
if (animation)
|
this.collision = mkCollision(view.data.collision);
|
||||||
this.totalTime = animation.sequence.reduce((a, s) => a + s[0], 0);
|
|
||||||
else
|
|
||||||
this.totalTime = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(time: number) {
|
public render(time: number) {
|
||||||
this.renderer.setTranslation(this.pos);
|
this.renderer.setTranslation(this.pos);
|
||||||
this.getSprite(time).render();
|
this.view.renderByTime(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTranslation(): vec2 {
|
public getTranslation(): vec2 {
|
||||||
|
@ -57,18 +44,4 @@ export class EntityContext implements CollidableGroup {
|
||||||
public interact() {
|
public interact() {
|
||||||
alert(`You've interacted with ${this.name}!`);
|
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,15 @@ import { Renderer } from './renderer/renderer';
|
||||||
import { SpriteCoords, SpriteView, SpriteViewBuilder } from './sprite';
|
import { SpriteCoords, SpriteView, SpriteViewBuilder } from './sprite';
|
||||||
import { loadImage, mkTexture } from './util/image';
|
import { loadImage, mkTexture } from './util/image';
|
||||||
|
|
||||||
|
import { getJSON } from '../util';
|
||||||
|
|
||||||
import { vec2 } from 'gl-matrix';
|
import { vec2 } from 'gl-matrix';
|
||||||
|
|
||||||
export async function loadEntity(
|
export class EntityView {
|
||||||
r: Renderer,
|
public static async load(r: Renderer, name: string): Promise<EntityView> {
|
||||||
data: EntityData,
|
const data = new EntityData(await getJSON(`resources/entity/${name}.json`));
|
||||||
): Promise<SpriteView[]> {
|
|
||||||
const tile = await loadImage(`resources/sprite/entity/${data.sprite}.png`);
|
const tile = await loadImage(`resources/sprite/entity/${data.sprite}.png`);
|
||||||
|
|
||||||
const [texture, size] = mkTexture(r, tile);
|
const [texture, size] = mkTexture(r, tile);
|
||||||
const frameSize = [size[0], size[1] / data.frames];
|
const frameSize = [size[0], size[1] / data.frames];
|
||||||
|
|
||||||
|
@ -31,5 +33,40 @@ export async function loadEntity(
|
||||||
sprites.push(builder.build());
|
sprites.push(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprites;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue