2023-08-25 18:48:17 -04:00
|
|
|
import { Component, ComponentNames } from '.';
|
|
|
|
import type { Dimension2D, DrawArgs, Coord2D } from '../interfaces';
|
2023-07-19 23:38:24 -04:00
|
|
|
|
|
|
|
export class Sprite extends Component {
|
|
|
|
private sheet: HTMLImageElement;
|
|
|
|
|
|
|
|
private spriteImgPos: Coord2D;
|
|
|
|
private spriteImgDimensions: Dimension2D;
|
|
|
|
|
|
|
|
private msPerFrame: number;
|
|
|
|
private msSinceLastFrame: number;
|
|
|
|
private currentFrame: number;
|
|
|
|
private numFrames: number;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
sheet: HTMLImageElement,
|
|
|
|
spriteImgPos: Coord2D,
|
|
|
|
spriteImgDimensions: Dimension2D,
|
|
|
|
msPerFrame: number,
|
2023-08-25 18:48:17 -04:00
|
|
|
numFrames: number
|
2023-07-19 23:38:24 -04:00
|
|
|
) {
|
|
|
|
super(ComponentNames.Sprite);
|
|
|
|
|
|
|
|
this.sheet = sheet;
|
|
|
|
this.spriteImgPos = spriteImgPos;
|
|
|
|
this.spriteImgDimensions = spriteImgDimensions;
|
|
|
|
this.msPerFrame = msPerFrame;
|
|
|
|
this.numFrames = numFrames;
|
|
|
|
|
|
|
|
this.msSinceLastFrame = 0;
|
|
|
|
this.currentFrame = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public update(dt: number) {
|
|
|
|
this.msSinceLastFrame += dt;
|
|
|
|
if (this.msSinceLastFrame >= this.msPerFrame) {
|
|
|
|
this.currentFrame = (this.currentFrame + 1) % this.numFrames;
|
|
|
|
this.msSinceLastFrame = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public draw(ctx: CanvasRenderingContext2D, drawArgs: DrawArgs) {
|
|
|
|
const { center, rotation, tint, opacity } = drawArgs;
|
|
|
|
|
|
|
|
ctx.save();
|
|
|
|
ctx.translate(center.x, center.y);
|
2023-08-12 15:49:16 -04:00
|
|
|
if (rotation != undefined && rotation != 0) {
|
2023-07-19 23:38:24 -04:00
|
|
|
ctx.rotate(rotation * (Math.PI / 180));
|
|
|
|
}
|
|
|
|
ctx.translate(-center.x, -center.y);
|
|
|
|
|
|
|
|
if (opacity) {
|
|
|
|
ctx.globalAlpha = opacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.drawImage(
|
|
|
|
this.sheet,
|
|
|
|
...this.getSpriteArgs(),
|
2023-08-25 18:48:17 -04:00
|
|
|
...this.getDrawArgs(drawArgs)
|
2023-07-19 23:38:24 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
if (tint) {
|
|
|
|
ctx.globalAlpha = 0.5;
|
2023-08-25 18:48:17 -04:00
|
|
|
ctx.globalCompositeOperation = 'source-atop';
|
2023-07-19 23:38:24 -04:00
|
|
|
ctx.fillStyle = tint;
|
|
|
|
ctx.fillRect(...this.getDrawArgs(drawArgs));
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
private getSpriteArgs(): [sx: number, sy: number, sw: number, sh: number] {
|
|
|
|
return [
|
|
|
|
this.spriteImgPos.x + this.currentFrame * this.spriteImgDimensions.width,
|
|
|
|
this.spriteImgPos.y,
|
|
|
|
this.spriteImgDimensions.width,
|
2023-08-25 18:48:17 -04:00
|
|
|
this.spriteImgDimensions.height
|
2023-07-19 23:38:24 -04:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
private getDrawArgs({
|
|
|
|
center,
|
2023-08-25 18:48:17 -04:00
|
|
|
dimension
|
2023-07-19 23:38:24 -04:00
|
|
|
}: DrawArgs): [dx: number, dy: number, dw: number, dh: number] {
|
|
|
|
return [
|
|
|
|
center.x - dimension.width / 2,
|
|
|
|
center.y - dimension.height / 2,
|
|
|
|
dimension.width,
|
2023-08-25 18:48:17 -04:00
|
|
|
dimension.height
|
2023-07-19 23:38:24 -04:00
|
|
|
];
|
|
|
|
}
|
2023-08-25 18:48:17 -04:00
|
|
|
|
|
|
|
public getSpriteDimensions() {
|
|
|
|
return this.spriteImgDimensions;
|
|
|
|
}
|
2023-07-19 23:38:24 -04:00
|
|
|
}
|