From bc835348268615f3388b4f5552637fb239f65783 Mon Sep 17 00:00:00 2001 From: kolaflash Date: Mon, 1 Dec 2025 19:21:57 +0100 Subject: [PATCH] Some animations --- engine/Entity.ts | 1 + entities/testEntity/index.ts | 66 +++++++++++++++++------------------- lib/Animation.ts | 38 +++++++++++++++++++++ lib/Sprite.ts | 16 ++++----- 4 files changed, 79 insertions(+), 42 deletions(-) create mode 100644 lib/Animation.ts diff --git a/engine/Entity.ts b/engine/Entity.ts index 4b1af00..53c9ceb 100644 --- a/engine/Entity.ts +++ b/engine/Entity.ts @@ -1,6 +1,7 @@ import { createVector, type Vector } from "#/lib/Vector.ts"; export type Entity = { + [x: string]: any; id: string; position: Vector; state: T; diff --git a/entities/testEntity/index.ts b/entities/testEntity/index.ts index 4a58f08..f16f77d 100644 --- a/entities/testEntity/index.ts +++ b/entities/testEntity/index.ts @@ -1,54 +1,52 @@ -import { type Entity, useEntity } from "#/engine/Entity.ts"; +import { useEntity } from "#/engine/Entity.ts"; import { viewport } from "#/engine/Viewport.ts"; +import { + type Animation, + animateSprite, + createAnimation, +} from "#/lib/Animation.ts"; import { loadImage } from "#/lib/loadImage.ts"; -import { createSprite, drawSprite, type Sprite } from "#/lib/Sprite.ts"; +import { createSprite } from "#/lib/Sprite.ts"; -const spriteIdle = createSprite(await loadImage("/assets/char-idle.png"), 2, 4); -const spriteWalk = createSprite(await loadImage("/assets/char-walk.png"), 4, 4); -spriteWalk.yIndex = 2; +const sprites = { + idle: createSprite(await loadImage("/assets/char-idle.png"), 2, 4), + walk: createSprite(await loadImage("/assets/char-walk.png"), 4, 4), +}; -function animateSprite( - ctx: CanvasRenderingContext2D, - sprite: Sprite, - entity: Entity, - delta: number, -): void { - entity.state.animations.walk.frameDelta += delta; - if ( - entity.state.animations.walk.frameDelta > - entity.state.animations.walk.frameTime - ) { - entity.state.animations.walk.frameDelta = - entity.state.animations.walk.frameDelta % - entity.state.animations.walk.frameTime; - - spriteWalk.xIndex += 1; - if (spriteWalk.xIndex >= spriteWalk.xFrames) { - spriteWalk.xIndex = 0; - } - } - drawSprite(ctx, spriteWalk, entity.position.x, entity.position.y); -} - -const { animate, process } = useEntity("testEntity", { +const { animate, process } = useEntity<{ animations: { - walk: { - frameTime: 222, - frameDelta: 0, - }, + idle: Animation; + walk: Animation; + }; + currentAnimation: "idle" | "walk"; + stuff: number; +}>("testEntity", { + animations: { + idle: createAnimation(2, 250), + walk: createAnimation(2, 250), }, + currentAnimation: "idle", stuff: 1, }); animate((entity, ctx, delta) => { - animateSprite(ctx, spriteIdle, entity, delta); + animateSprite( + ctx, + sprites[entity.state.currentAnimation], + entity.state.animations[entity.state.currentAnimation], + entity.position.x, + entity.position.y, + delta, + ); }); process((entity, delta) => { entity.position.x += entity.state.stuff * 0.05 * delta; if (entity.position.x > viewport.canvas.width - 16) { entity.state.stuff = -1; + entity.state.currentAnimation = "walk"; } else if (entity.position.x < 0) { entity.state.stuff = 1; + entity.state.currentAnimation = "idle"; } }); diff --git a/lib/Animation.ts b/lib/Animation.ts new file mode 100644 index 0000000..9333faa --- /dev/null +++ b/lib/Animation.ts @@ -0,0 +1,38 @@ +import { drawSprite, type Sprite } from "#/lib/Sprite.ts"; + +export type Animation = { + xIndex: number; + yIndex: number; + frameTime: number; + frameDelta: number; +}; + +export function createAnimation(yIndex: number, frameTime: number): Animation { + return { + xIndex: 0, + yIndex, + frameTime, + frameDelta: 0, + }; +} + +export function animateSprite( + ctx: CanvasRenderingContext2D, + sprite: Sprite, + animation: Animation, + x: number, + y: number, + delta: number, +): void { + drawSprite(ctx, sprite, animation.xIndex, animation.yIndex, x, y); + + animation.frameDelta += delta; + if (animation.frameDelta >= animation.frameTime) { + animation.frameDelta = animation.frameDelta - animation.frameTime; + + animation.xIndex += 1; + if (animation.xIndex >= sprite.xFrames) { + animation.xIndex = 0; + } + } +} diff --git a/lib/Sprite.ts b/lib/Sprite.ts index e5af89e..b1a2754 100644 --- a/lib/Sprite.ts +++ b/lib/Sprite.ts @@ -4,8 +4,6 @@ export type Sprite = { yFrames: number; frameWidth: number; frameHeight: number; - xIndex: number; - yIndex: number; }; export function createSprite( @@ -19,26 +17,28 @@ export function createSprite( yFrames, frameWidth: image.width / xFrames, frameHeight: image.height / yFrames, - xIndex: 0, - yIndex: 0, }; } export function drawSprite( ctx: CanvasRenderingContext2D, sprite: Sprite, + xIndex: number, + yIndex: number, x: number, y: number, + width?: number, + height?: number, ): void { ctx.drawImage( sprite.image, - sprite.xIndex * sprite.frameWidth, - sprite.yIndex * sprite.frameHeight, + xIndex * sprite.frameWidth, + yIndex * sprite.frameHeight, sprite.frameWidth, sprite.frameHeight, x, y, - sprite.frameWidth, - sprite.frameHeight, + width || sprite.frameWidth, + height || sprite.frameHeight, ); }