diff --git a/engine/Entity.ts b/engine/Entity.ts index 5619153..4b1af00 100644 --- a/engine/Entity.ts +++ b/engine/Entity.ts @@ -1,52 +1,42 @@ -import type { Sprite } from "#/lib/Sprite.ts"; -import type { Vector } from "#/lib/Vector.ts"; +import { createVector, type Vector } from "#/lib/Vector.ts"; -export type Entity = { +export type Entity = { id: string; - src: string; - width: number; - height: number; -}; - -export type EntityInstance = { position: Vector; - width: number; - height: number; - sprite: Sprite; + state: T; }; -export type Draw = ( - entity: EntityInstance, +export type Animate = ( + entity: Entity, ctx: CanvasRenderingContext2D, + delta: number, ) => void; -export type Process = (entity: EntityInstance, delta: number) => void; +export type Process = (entity: Entity, delta: number) => void; -export function createEntity( +export const entityMap = new Map>(); +export const entityAnimateMap = new Map>(); +export const entityProcessMap = new Map>(); + +export function useEntity( id: string, - src: string, - width: number = 16, - height: number = 16, -): Entity { - return { id, width, height, src }; -} - -export const entityMap = new Map(); -export const entityDrawMap = new Map(); -export const entityProcessMap = new Map(); - -export function useEntity(data: Entity): { - draw: (fn: Draw) => void; - process: (fn: Process) => void; + state: T, +): { + animate: (fn: Animate) => void; + process: (fn: Process) => void; } { - entityMap.set(data.id, data); + entityMap.set(id, { + id, + position: createVector(), + state, + }); return { - draw(fn: Draw): void { - entityDrawMap.set(data.id, fn); + animate(fn: Animate): void { + entityAnimateMap.set(id, fn); }, - process(fn: Process): void { - entityProcessMap.set(data.id, fn); + process(fn: Process): void { + entityProcessMap.set(id, fn); }, }; } diff --git a/engine/Scene.ts b/engine/Scene.ts index c93d0fb..174c2a1 100644 --- a/engine/Scene.ts +++ b/engine/Scene.ts @@ -1,11 +1,9 @@ -import { loadImage } from "#/lib/loadImage.ts"; -import { createSprite } from "#/lib/Sprite.ts"; -import { createVector, type Vector } from "#/lib/Vector.ts"; +import type { Vector } from "#/lib/Vector.ts"; import { - type Draw as EntityDraw, - type EntityInstance, + type Entity, + type Animate as EntityDraw, type Process as EntityProcess, - entityDrawMap, + entityAnimateMap, entityMap, entityProcessMap, } from "./Entity.ts"; @@ -23,9 +21,9 @@ export type SceneData = { export type Scene = { data: SceneData; entityPool: Array<{ - draw: EntityDraw; - process: EntityProcess; - entity: EntityInstance; + draw: EntityDraw; + process: EntityProcess; + entity: Entity; }>; process: Process; }; @@ -50,9 +48,9 @@ export const currentScene: Scene = { entityPool: [], }; -function drawEntities(ctx: CanvasRenderingContext2D): void { +function animateEntities(ctx: CanvasRenderingContext2D, delta: number): void { for (const entry of currentScene.entityPool) { - entry.draw(entry.entity, ctx); + entry.draw(entry.entity, ctx, delta); } } @@ -70,7 +68,7 @@ export function useScene(data: SceneData): { return { process(fn: Process): void { sceneProcessMap.set(data.id, (ctx, delta) => { - drawEntities(ctx); + animateEntities(ctx, delta); processEntities(delta); fn(ctx, delta); }); @@ -94,21 +92,20 @@ export async function loadScene(name: string): Promise { const data = sceneDataMap.get(name)!; currentScene.data = data; - for (const entity of data.entities) { - await import(`#/entities/${entity.id}/index.ts`); + for (const entry of data.entities) { + await import(`#/entities/${entry.id}/index.ts`); - const e = entityMap.get(entity.id)!; - const entityInstance: EntityInstance = { - position: entity.position, - width: e.width, - height: e.height, - sprite: createSprite(await loadImage(e.src), 2, 4), // FIXME + const e = entityMap.get(entry.id) as Entity; + const entity: Entity = { + id: e.id, + position: entry.position, + state: structuredClone(e.state), }; currentScene.entityPool.push({ - draw: entityDrawMap.get(entity.id)!, - process: entityProcessMap.get(entity.id)!, - entity: entityInstance, + draw: entityAnimateMap.get(entry.id)!, + process: entityProcessMap.get(entry.id)!, + entity: entity, }); } diff --git a/entities/testEntity/data.json b/entities/testEntity/data.json deleted file mode 100644 index 522e0d8..0000000 --- a/entities/testEntity/data.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": "testEntity", - "src": "/assets/char-idle.png", - "width": 16, - "height": 16 -} diff --git a/entities/testEntity/index.ts b/entities/testEntity/index.ts index 1fcf6a5..7da2df1 100644 --- a/entities/testEntity/index.ts +++ b/entities/testEntity/index.ts @@ -1,18 +1,26 @@ -import { type EntityInstance, useEntity } from "#/engine/Entity.ts"; -import { drawSprite } from "#/lib/Sprite.ts"; -import data from "./data.json"; +import { useEntity } from "#/engine/Entity.ts"; +import { loadImage } from "#/lib/loadImage.ts"; +import { createSprite, drawSprite } from "#/lib/Sprite.ts"; -const { draw, process } = useEntity(data); +const sprite = createSprite(await loadImage("/assets/char-idle.png"), 2, 4); -draw((entity: EntityInstance, ctx: CanvasRenderingContext2D) => { - drawSprite( - ctx, - entity.sprite, - entity.position.x, - entity.position.y, - entity.width, - entity.height, - ); +const { animate, process } = useEntity("testEntity", { + animation: { + xFrame: 0, + yFrame: 0, + }, + stuff: 1, }); -process((_entity, _delta) => {}); +animate((entity, ctx, _delta) => { + drawSprite(ctx, sprite, entity.position.x, entity.position.y, 16, 16); +}); + +process((entity, _delta) => { + if (entity.state.stuff === 1) { + entity.position.x += 1; + if (entity.position.x > 164) { + entity.state.stuff = 0; + } + } +}); diff --git a/scenes/testScene/data.json b/scenes/testScene/data.json index ef49572..634646a 100644 --- a/scenes/testScene/data.json +++ b/scenes/testScene/data.json @@ -1,6 +1,6 @@ { "id": "testScene", - "width": 48, + "width": 180, "height": 48, "entities": [ { @@ -16,6 +16,13 @@ "x": 16, "y": 16 } + }, + { + "id": "testEntity", + "position": { + "x": 32, + "y": 32 + } } ] }