aboutsummaryrefslogtreecommitdiff
path: root/static/src/engine
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-09-15 17:38:02 -0700
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-09-15 17:38:02 -0700
commit8ac11eda05e7159a7f762d3396cf7bb8ee51534b (patch)
tree6e1214ceebd209f3829aac73b2dd330452079d84 /static/src/engine
parentf7e7121fce7bd3f7fdabe836955e43b3d194c1c6 (diff)
downloadkennel.hatecomputers.club-main.tar.gz
kennel.hatecomputers.club-main.zip
render the spritesheet spec in the render systemHEADmain
Diffstat (limited to 'static/src/engine')
-rw-r--r--static/src/engine/component.ts2
-rw-r--r--static/src/engine/debounce_publisher.ts2
-rw-r--r--static/src/engine/render.ts84
-rw-r--r--static/src/engine/trailing_position.ts20
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);
- },
+ }
);
}
}