diff options
| author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-09-15 17:38:02 -0700 |
|---|---|---|
| committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-09-15 17:38:02 -0700 |
| commit | 8ac11eda05e7159a7f762d3396cf7bb8ee51534b (patch) | |
| tree | 6e1214ceebd209f3829aac73b2dd330452079d84 /static | |
| parent | f7e7121fce7bd3f7fdabe836955e43b3d194c1c6 (diff) | |
| download | kennel.hatecomputers.club-8ac11eda05e7159a7f762d3396cf7bb8ee51534b.tar.gz kennel.hatecomputers.club-8ac11eda05e7159a7f762d3396cf7bb8ee51534b.zip | |
Diffstat (limited to 'static')
| -rw-r--r-- | static/src/engine/component.ts | 2 | ||||
| -rw-r--r-- | static/src/engine/debounce_publisher.ts | 2 | ||||
| -rw-r--r-- | static/src/engine/render.ts | 84 | ||||
| -rw-r--r-- | static/src/engine/trailing_position.ts | 20 |
4 files changed, 89 insertions, 19 deletions
diff --git a/static/src/engine/component.ts b/static/src/engine/component.ts index a16215b..eb6fdd6 100644 --- a/static/src/engine/component.ts +++ b/static/src/engine/component.ts @@ -36,7 +36,7 @@ export interface SpriteSpec { export interface SpriteSheetComponent extends Component { name: ComponentType.SPRITESHEET; source: string; - sheet: HTMLImageElement; + sheet?: HTMLImageElement; current_frame: number; last_update: number; diff --git a/static/src/engine/debounce_publisher.ts b/static/src/engine/debounce_publisher.ts index bc5e95f..8ee4bb0 100644 --- a/static/src/engine/debounce_publisher.ts +++ b/static/src/engine/debounce_publisher.ts @@ -5,7 +5,7 @@ export class DebouncePublisher<T> { constructor( private readonly publisher: (data: T) => void | Promise<void>, - private readonly debounce_ms = 150, + private readonly debounce_ms = 100, ) {} public start() { diff --git a/static/src/engine/render.ts b/static/src/engine/render.ts index 8f0343a..4ff1ec0 100644 --- a/static/src/engine/render.ts +++ b/static/src/engine/render.ts @@ -2,6 +2,8 @@ import { ComponentType, PositionComponent, TrailingPositionComponent, + SpriteSheetComponent, + SpriteSpec, } from "./component"; import { Game } from "./game"; import { System, SystemType } from "./system"; @@ -17,7 +19,7 @@ export class RenderSystem extends System { this.canvas.height = height; } - public update(_dt: number, game: Game) { + public update(dt: number, game: Game) { const ctx = this.canvas.getContext("2d"); if (ctx === null) return; ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); @@ -32,15 +34,87 @@ export class RenderSystem extends System { return; } - if (ComponentType.POSITION in entity.components) { + if ( + ComponentType.POSITION in entity.components && + ComponentType.SPRITESHEET in entity.components + ) { const position = entity.components[ ComponentType.POSITION ] as PositionComponent; - ctx.beginPath(); - ctx.arc(position.x, position.y, 50, 0, 2 * Math.PI); - ctx.stroke(); + const spritesheet = entity.components[ + ComponentType.SPRITESHEET + ] as SpriteSheetComponent; + + if (typeof spritesheet.sheet === "undefined") { + const img = new Image(); + img.src = spritesheet.source; + spritesheet.sheet = img; + } + const spritespec = + spritesheet.state_to_spritespec[spritesheet.current_state]; + + this.blit_sprite(ctx, spritesheet, position); + + spritesheet.last_update += dt; + if (spritesheet.last_update > spritespec.ms_per_frame) { + spritesheet.current_frame++; + spritesheet.current_frame %= spritespec.frames; + spritesheet.last_update = 0; + } + return; } }); } + + private blit_sprite( + ctx: CanvasRenderingContext2D, + spritesheet: SpriteSheetComponent, + position: { x: number; y: number }, + ) { + ctx.save(); + ctx.translate(position.x, position.y); + ctx.translate(-position.x, -position.y); + + if (typeof spritesheet.sheet === "undefined") return; + + const spritespec = + spritesheet.state_to_spritespec[spritesheet.current_state]; + + ctx.drawImage( + spritesheet.sheet, + ...this.get_sprite_args(spritesheet.current_frame, spritespec), + ...this.get_draw_args(spritespec, position), + ); + + ctx.restore(); + } + + private get_sprite_args( + current_frame: number, + sprite_spec: SpriteSpec, + ): [sx: number, sy: number, sw: number, sh: number] { + const [width, height] = this.get_dimensions(sprite_spec); + return [ + sprite_spec.top_x, + sprite_spec.top_y + current_frame * height, + width, + height, + ]; + } + + private get_draw_args( + sprite_spec: SpriteSpec, + position: { x: number; y: number }, + ): [dx: number, dy: number, dw: number, dh: number] { + const [width, height] = this.get_dimensions(sprite_spec); + return [position.x - width / 2, position.y - height / 2, width, height]; + } + + private get_dimensions(sprite_spec: SpriteSpec): [number, number] { + return [ + sprite_spec.end_x - sprite_spec.top_x, + (sprite_spec.end_y - sprite_spec.top_y) / sprite_spec.frames, + ]; + } } diff --git a/static/src/engine/trailing_position.ts b/static/src/engine/trailing_position.ts index 1ea22d3..5b41682 100644 --- a/static/src/engine/trailing_position.ts +++ b/static/src/engine/trailing_position.ts @@ -2,19 +2,15 @@ import { ComponentType, TrailingPositionComponent } from "./component"; import { Game } from "./game"; import { System, SystemType } from "./system"; +interface Point { + x: number; + y: number; + time: number; +} + export class TrailingPositionSystem extends System { constructor( - private readonly point_filter: ( - trail_point: { - x: number; - y: number; - time: number; - }[], - ) => { - x: number; - y: number; - time: number; - }[], + private readonly point_filter: (trail_point: Array<Point>) => Array<Point> ) { super(SystemType.TRAILING_POSITION); } @@ -27,7 +23,7 @@ export class TrailingPositionSystem extends System { ComponentType.TRAILING_POSITION ] as TrailingPositionComponent; trailing_position.trails = this.point_filter(trailing_position.trails); - }, + } ); } } |
