Run prettier over everything

This commit is contained in:
2025-02-17 18:38:40 -08:00
parent 462f5ce751
commit 5939384b7c
46 changed files with 2315 additions and 1471 deletions

View File

@ -17,11 +17,13 @@ export class Color {
}
static parseHexCode(hexCode: string) {
const regex1 = /#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})?/;
const regex2 = /#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})?/;
const regex1 =
/#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})?/;
const regex2 =
/#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})?/;
let result = regex1.exec(hexCode) ?? regex2.exec(hexCode);
if (result == null) {
throw `could not parse color: ${hexCode}`
throw `could not parse color: ${hexCode}`;
}
let parseGroup = (s: string | undefined): number => {
@ -32,7 +34,7 @@ export class Color {
return 17 * parseInt(s, 16);
}
return parseInt(s, 16);
}
};
return new Color(
parseGroup(result[1]),
parseGroup(result[2]),
@ -42,7 +44,7 @@ export class Color {
}
toStyle(): string {
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a / 255.0})`
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a / 255.0})`;
}
}
@ -56,7 +58,7 @@ export class Point {
}
toString(): string {
return `${this.x},${this.y}`
return `${this.x},${this.y}`;
}
offset(other: Point | Size): Point {
@ -109,7 +111,7 @@ export class Size {
}
toString(): string {
return `${this.w}x${this.h}`
return `${this.w}x${this.h}`;
}
}
@ -127,7 +129,12 @@ export class Rect {
}
contains(other: Point) {
return (other.x >= this.top.x && other.y >= this.top.y && other.x < this.top.x + this.size.w && other.y < this.top.y + this.size.h);
return (
other.x >= this.top.x &&
other.y >= this.top.y &&
other.x < this.top.x + this.size.w &&
other.y < this.top.y + this.size.h
);
}
overlaps(other: Rect) {
@ -156,20 +163,20 @@ export class Grid<T> {
for (let y = 0; y < size.h; y++) {
let row = [];
for (let x = 0; x < size.w; x++) {
row.push(cbDefault(new Point(x, y)))
row.push(cbDefault(new Point(x, y)));
}
this.#data.push(row);
}
}
static createGridFromMultilineString(multiline: string): Grid<string> {
let lines = []
let lines = [];
for (let line of multiline.split("\n")) {
let trimmedLine = line.trim();
if (trimmedLine == "") {
continue;
}
lines.push(trimmedLine)
lines.push(trimmedLine);
}
return this.createGridFromStringArray(lines);
}
@ -181,17 +188,14 @@ export class Grid<T> {
let w1 = ary[i].length;
let w2 = ary[i + 1].length;
if (w1 != w2) {
throw `createGridFromStringArray: must be grid-shaped, got ${ary}`
throw `createGridFromStringArray: must be grid-shaped, got ${ary}`;
}
w = w1;
}
return new Grid(
new Size(w, h),
(xy) => {
return ary[xy.y].charAt(xy.x);
}
)
return new Grid(new Size(w, h), (xy) => {
return ary[xy.y].charAt(xy.x);
});
}
static createGridFromJaggedArray<T>(ary: Array<Array<T>>): Grid<T> {
@ -201,17 +205,14 @@ export class Grid<T> {
let w1 = ary[i].length;
let w2 = ary[i + 1].length;
if (w1 != w2) {
throw `createGridFromJaggedArray: must be grid-shaped, got ${ary}`
throw `createGridFromJaggedArray: must be grid-shaped, got ${ary}`;
}
w = w1;
}
return new Grid(
new Size(w, h),
(xy) => {
return ary[xy.y][xy.x];
}
)
return new Grid(new Size(w, h), (xy) => {
return ary[xy.y][xy.x];
});
}
map<T2>(cbCell: (content: T, position: Point) => T2) {
@ -220,10 +221,14 @@ export class Grid<T> {
#checkPosition(position: Point) {
if (
(position.x < 0 || position.x >= this.size.w || Math.floor(position.x) != position.x) ||
(position.y < 0 || position.y >= this.size.h || Math.floor(position.y) != position.y)
position.x < 0 ||
position.x >= this.size.w ||
Math.floor(position.x) != position.x ||
position.y < 0 ||
position.y >= this.size.h ||
Math.floor(position.y) != position.y
) {
throw new Error(`invalid position for ${this.size}: ${position}`)
throw new Error(`invalid position for ${this.size}: ${position}`);
}
}
@ -241,7 +246,7 @@ export class Grid<T> {
export enum AlignX {
Left = 0,
Center = 1,
Right = 2
Right = 2,
}
export enum AlignY {

View File

@ -13,7 +13,7 @@ class Assets {
// and then wait for isLoaded to return true)
for (let filename in this.#images) {
if (!this.#images[filename].complete) {
return false
return false;
}
}
@ -29,7 +29,7 @@ class Assets {
element.src = filename;
this.#images[filename] = element;
}
return element
return element;
}
}
@ -38,4 +38,3 @@ let active: Assets = new Assets();
export function getAssets(): Assets {
return active;
}

View File

@ -1,18 +1,17 @@
const MAX_UPDATES_BANKED: number = 20.0;
// always run physics at 240 hz
const UPDATES_PER_MS: number = 1/(1000.0/240.0);
const UPDATES_PER_MS: number = 1 / (1000.0 / 240.0);
class Clock {
#lastTimestamp: number | undefined;
#updatesBanked: number
#updatesBanked: number;
constructor() {
this.#lastTimestamp = undefined;
this.#updatesBanked = 0.0
this.#updatesBanked = 0.0;
}
recordTimestamp(timestamp: number) {
if (this.#lastTimestamp) {
let delta = timestamp - this.#lastTimestamp;
@ -26,7 +25,7 @@ class Clock {
// and remove one draw from the bank
if (this.#updatesBanked > 1) {
this.#updatesBanked -= 1;
return true
return true;
}
return false;
}
@ -40,5 +39,3 @@ let active: Clock = new Clock();
export function getClock(): Clock {
return active;
}

View File

@ -1,7 +1,7 @@
import {getScreen} from "./screen.ts";
import {AlignX, AlignY, Color, Point, Size} from "../datatypes.ts";
import {mainFont} from "./font.ts";
import {Sprite} from "./sprite.ts";
import { getScreen } from "./screen.ts";
import { AlignX, AlignY, Color, Point, Size } from "../datatypes.ts";
import { mainFont } from "./font.ts";
import { Sprite } from "./sprite.ts";
class Drawing {
camera: Point;
@ -19,7 +19,9 @@ class Drawing {
this.camera = oldCamera;
}
get size() { return getScreen().size; }
get size() {
return getScreen().size;
}
invertRect(position: Point, size: Size) {
position = this.camera.negate().offset(position);
@ -31,8 +33,8 @@ class Drawing {
Math.floor(position.x),
Math.floor(position.y),
Math.floor(size.w),
Math.floor(size.h)
)
Math.floor(size.h),
);
}
fillRect(position: Point, size: Size, color: Color) {
@ -44,7 +46,7 @@ class Drawing {
Math.floor(position.x),
Math.floor(position.y),
Math.floor(size.w),
Math.floor(size.h)
Math.floor(size.h),
);
}
@ -57,11 +59,16 @@ class Drawing {
Math.floor(position.x) + 0.5,
Math.floor(position.y) + 0.5,
Math.floor(size.w) - 1,
Math.floor(size.h) - 1
)
Math.floor(size.h) - 1,
);
}
drawText(text: string, position: Point, color: Color, options?: {alignX?: AlignX, alignY?: AlignY, forceWidth?: number}) {
drawText(
text: string,
position: Point,
color: Color,
options?: { alignX?: AlignX; alignY?: AlignY; forceWidth?: number },
) {
position = this.camera.negate().offset(position);
let ctx = getScreen().unsafeMakeContext();
@ -72,19 +79,30 @@ class Drawing {
alignX: options?.alignX,
alignY: options?.alignY,
forceWidth: options?.forceWidth,
color
})
color,
});
}
measureText(text: string, forceWidth?: number): Size {
return mainFont.measureText({text, forceWidth})
return mainFont.measureText({ text, forceWidth });
}
drawSprite(sprite: Sprite, position: Point, ix?: number, options?: {xScale?: number, yScale: number, angle?: number}) {
drawSprite(
sprite: Sprite,
position: Point,
ix?: number,
options?: { xScale?: number; yScale: number; angle?: number },
) {
position = this.camera.negate().offset(position);
let ctx = getScreen().unsafeMakeContext();
sprite.internalDraw(ctx, {position, ix, xScale: options?.xScale, yScale: options?.yScale, angle: options?.angle})
sprite.internalDraw(ctx, {
position,
ix,
xScale: options?.xScale,
yScale: options?.yScale,
angle: options?.angle,
});
}
}
@ -93,5 +111,3 @@ let active: Drawing = new Drawing();
export function getDrawing(): Drawing {
return active;
}

View File

@ -1,6 +1,6 @@
import {getAssets} from "./assets.ts";
import fontSheet from '../../art/fonts/vga_8x16.png';
import {AlignX, AlignY, Color, Point, Size} from "../datatypes.ts";
import { getAssets } from "./assets.ts";
import fontSheet from "../../art/fonts/vga_8x16.png";
import { AlignX, AlignY, Color, Point, Size } from "../datatypes.ts";
class Font {
#filename: string;
@ -14,18 +14,28 @@ class Font {
this.#cellsPerSheet = cellsPerSheet;
this.#pixelsPerCell = pixelsPerCell;
this.#tintingCanvas = document.createElement("canvas");
this.#tintedVersions = {}
this.#tintedVersions = {};
}
get #cx(): number { return this.#cellsPerSheet.w }
get #cy(): number { return this.#cellsPerSheet.h }
get #px(): number { return this.#pixelsPerCell.w }
get #py(): number { return this.#pixelsPerCell.h }
get #cx(): number {
return this.#cellsPerSheet.w;
}
get #cy(): number {
return this.#cellsPerSheet.h;
}
get #px(): number {
return this.#pixelsPerCell.w;
}
get #py(): number {
return this.#pixelsPerCell.h;
}
#getTintedImage(color: string): HTMLImageElement | null {
let image = getAssets().getImage(this.#filename);
if (!image.complete) { return null; }
if (!image.complete) {
return null;
}
let tintedVersion = this.#tintedVersions[color];
if (tintedVersion != undefined) {
@ -36,7 +46,7 @@ class Font {
let h = image.height;
if (!(w == this.#cx * this.#px && h == this.#cy * this.#py)) {
throw `unexpected image dimensions for font ${this.#filename}: ${w} x ${h}`
throw `unexpected image dimensions for font ${this.#filename}: ${w} x ${h}`;
}
this.#tintingCanvas.width = w;
@ -55,17 +65,28 @@ class Font {
return result;
}
internalDrawText({ctx, text, position, alignX, alignY, forceWidth, color}: {
ctx: CanvasRenderingContext2D,
text: string,
position: Point, alignX?: AlignX, alignY?: AlignY,
forceWidth?: number, color: Color
internalDrawText({
ctx,
text,
position,
alignX,
alignY,
forceWidth,
color,
}: {
ctx: CanvasRenderingContext2D;
text: string;
position: Point;
alignX?: AlignX;
alignY?: AlignY;
forceWidth?: number;
color: Color;
}) {
alignX = alignX == undefined ? AlignX.Left : alignX;
alignY = alignY == undefined ? AlignY.Top : alignY;
forceWidth = forceWidth == undefined ? 65535 : forceWidth;
let image = this.#getTintedImage(color.toStyle())
let image = this.#getTintedImage(color.toStyle());
if (image == null) {
return;
}
@ -73,43 +94,80 @@ class Font {
let sz = this.#glyphwise(text, forceWidth, () => {});
let offsetX = position.x;
let offsetY = position.y;
offsetX += (alignX == AlignX.Left ? 0 : alignX == AlignX.Center ? -sz.w / 2 : - sz.w)
offsetY += (alignY == AlignY.Top ? 0 : alignY == AlignY.Middle ? -sz.h / 2 : - sz.h)
offsetX +=
alignX == AlignX.Left ? 0 : alignX == AlignX.Center ? -sz.w / 2 : -sz.w;
offsetY +=
alignY == AlignY.Top ? 0 : alignY == AlignY.Middle ? -sz.h / 2 : -sz.h;
this.#glyphwise(text, forceWidth, (cx, cy, char) => {
let srcIx = char.charCodeAt(0);
this.#drawGlyph({ctx: ctx, image: image, ix: srcIx, x: offsetX + cx * this.#px, y: offsetY + cy * this.#py});
})
this.#drawGlyph({
ctx: ctx,
image: image,
ix: srcIx,
x: offsetX + cx * this.#px,
y: offsetY + cy * this.#py,
});
});
}
#drawGlyph({ctx, image, ix, x, y}: {ctx: CanvasRenderingContext2D, image: HTMLImageElement, ix: number, x: number, y: number}) {
#drawGlyph({
ctx,
image,
ix,
x,
y,
}: {
ctx: CanvasRenderingContext2D;
image: HTMLImageElement;
ix: number;
x: number;
y: number;
}) {
let srcCx = ix % this.#cx;
let srcCy = Math.floor(ix / this.#cx);
let srcPx = srcCx * this.#px;
let srcPy = srcCy * this.#py;
ctx.drawImage(
image,
srcPx, srcPy, this.#px, this.#py,
Math.floor(x), Math.floor(y), this.#px, this.#py
srcPx,
srcPy,
this.#px,
this.#py,
Math.floor(x),
Math.floor(y),
this.#px,
this.#py,
);
}
measureText({text, forceWidth}: {text: string, forceWidth?: number}): Size {
measureText({
text,
forceWidth,
}: {
text: string;
forceWidth?: number;
}): Size {
return this.#glyphwise(text, forceWidth, () => {});
}
#glyphwise(text: string, forceWidth: number | undefined, callback: (x: number, y: number, char: string) => void): Size {
#glyphwise(
text: string,
forceWidth: number | undefined,
callback: (x: number, y: number, char: string) => void,
): Size {
let cx = 0;
let cy = 0;
let cw = 0;
let ch = 0;
let wcx = forceWidth == undefined ? undefined : Math.floor(forceWidth / this.#px);
let wcx =
forceWidth == undefined ? undefined : Math.floor(forceWidth / this.#px);
text = betterWordWrap(text, wcx);
for (let i = 0; i < text.length; i++) {
let char = text[i]
if (char == '\n') {
let char = text[i];
if (char == "\n") {
cx = 0;
cy += 1;
ch = cy + 1;
@ -121,7 +179,7 @@ class Font {
ch = cy + 1;
}
callback(cx, cy, char)
callback(cx, cy, char);
cx += 1;
cw = Math.max(cw, cx);
ch = cy + 1;
@ -132,15 +190,15 @@ class Font {
}
}
// https://stackoverflow.com/users/1993501/edi9999
function betterWordWrap(s: string, wcx?: number) {
if (wcx === undefined) {
return s;
}
return s.replace(
new RegExp(`(?![^\\n]{1,${wcx}}$)([^\\n]{1,${wcx}})\\s`, 'g'), '$1\n'
new RegExp(`(?![^\\n]{1,${wcx}}$)([^\\n]{1,${wcx}})\\s`, "g"),
"$1\n",
);
}
export let mainFont = new Font(fontSheet, new Size(32, 8), new Size(8, 16));
export let mainFont = new Font(fontSheet, new Size(32, 8), new Size(8, 16));

View File

@ -1,14 +1,14 @@
import './style.css'
import "./style.css";
import {pollAndTouch} from "./screen.ts";
import {getClock} from "./clock.ts";
import {getInput, setupInput} from "./input.ts";
import {IGame} from "../datatypes.ts";
import { pollAndTouch } from "./screen.ts";
import { getClock } from "./clock.ts";
import { getInput, setupInput } from "./input.ts";
import { IGame } from "../datatypes.ts";
export function hostGame(game: IGame) {
let gameCanvas = document.getElementById("game") as HTMLCanvasElement;
setupInput(gameCanvas);
onFrame(game, undefined); // start on-frame draw loop, set up screen
onFrame(game, undefined); // start on-frame draw loop, set up screen
}
function onFrame(game: IGame, timestamp: number | undefined) {
@ -31,4 +31,3 @@ function onFrame(game: IGame, timestamp: number | undefined) {
function onFrameFixScreen(canvas: HTMLCanvasElement) {
pollAndTouch(canvas);
}

View File

@ -1,5 +1,5 @@
import {getScreen} from "./screen.ts";
import {Point} from "../datatypes.ts";
import { getScreen } from "./screen.ts";
import { Point } from "../datatypes.ts";
function handleKey(e: KeyboardEvent, down: boolean) {
active.handleKeyDown(e.key, down);
@ -12,25 +12,31 @@ function handleMouseMove(canvas: HTMLCanvasElement, m: MouseEvent) {
if (canvas.offsetWidth == 0 || canvas.offsetHeight == 0) {
return;
}
active.handleMouseMove(m.offsetX / canvas.offsetWidth, m.offsetY / canvas.offsetHeight);
active.handleMouseMove(
m.offsetX / canvas.offsetWidth,
m.offsetY / canvas.offsetHeight,
);
}
function handleMouseButton(canvas: HTMLCanvasElement, m: MouseEvent, down: boolean) {
function handleMouseButton(
canvas: HTMLCanvasElement,
m: MouseEvent,
down: boolean,
) {
if (canvas.offsetWidth == 0 || canvas.offsetHeight == 0) {
return;
}
active.handleMouseMove(m.offsetX / canvas.offsetWidth, m.offsetY / canvas.offsetHeight);
let button: MouseButton | null = (
m.button == 0 ? "leftMouse" :
m.button == 1 ? "rightMouse" :
null
)
active.handleMouseMove(
m.offsetX / canvas.offsetWidth,
m.offsetY / canvas.offsetHeight,
);
let button: MouseButton | null =
m.button == 0 ? "leftMouse" : m.button == 1 ? "rightMouse" : null;
if (button != null) {
active.handleMouseDown(button, down);
}
}
export function setupInput(canvas: HTMLCanvasElement) {
canvas.addEventListener("keyup", (k) => handleKey(k, false));
document.addEventListener("keyup", (k) => handleKey(k, false));
@ -38,8 +44,12 @@ export function setupInput(canvas: HTMLCanvasElement) {
document.addEventListener("keydown", (k) => handleKey(k, true));
canvas.addEventListener("mouseout", (_) => handleMouseOut());
canvas.addEventListener("mousemove", (m) => handleMouseMove(canvas, m));
canvas.addEventListener("mousedown", (m) => handleMouseButton(canvas, m, true));
canvas.addEventListener("mouseup", (m) => handleMouseButton(canvas, m, false));
canvas.addEventListener("mousedown", (m) =>
handleMouseButton(canvas, m, true),
);
canvas.addEventListener("mouseup", (m) =>
handleMouseButton(canvas, m, false),
);
}
export type MouseButton = "leftMouse" | "rightMouse";
@ -60,8 +70,8 @@ class Input {
}
update() {
this.#previousKeyDown = {...this.#keyDown};
this.#previousMouseDown = {...this.#mouseDown};
this.#previousKeyDown = { ...this.#keyDown };
this.#previousMouseDown = { ...this.#mouseDown };
}
handleMouseDown(name: string, down: boolean) {
@ -73,51 +83,56 @@ class Input {
handleMouseMove(x: number, y: number) {
let screen = getScreen();
if (x < 0.0 || x >= 1.0) { this.#mousePosition = null; }
if (y < 0.0 || y >= 1.0) { this.#mousePosition = null; }
if (x < 0.0 || x >= 1.0) {
this.#mousePosition = null;
}
if (y < 0.0 || y >= 1.0) {
this.#mousePosition = null;
}
let w = screen.size.w;
let h = screen.size.h;
this.#mousePosition = new Point(
Math.floor(x * w),
Math.floor(y * h),
)
this.#mousePosition = new Point(Math.floor(x * w), Math.floor(y * h));
}
isMouseDown(btn: MouseButton) : boolean {
isMouseDown(btn: MouseButton): boolean {
return this.#mouseDown[btn];
}
isMouseClicked(btn: MouseButton) : boolean {
isMouseClicked(btn: MouseButton): boolean {
return this.#mouseDown[btn] && !this.#previousMouseDown[btn];
}
isMouseReleased(btn: MouseButton) : boolean {
isMouseReleased(btn: MouseButton): boolean {
return !this.#mouseDown[btn] && this.#previousMouseDown[btn];
}
get mousePosition(): Point | null {
return this.#mousePosition
return this.#mousePosition;
}
isKeyDown(key: string) : boolean {
isKeyDown(key: string): boolean {
return this.#keyDown[key];
}
isKeyPressed(key: string) : boolean {
isKeyPressed(key: string): boolean {
return this.#keyDown[key] && !this.#previousKeyDown[key];
}
isKeyReleased(key: string) : boolean {
isKeyReleased(key: string): boolean {
return !this.#keyDown[key] && this.#previousKeyDown[key];
}
isAnythingPressed(): boolean {
for (let k of Object.keys(this.#keyDown)) {
if (this.#keyDown[k] && !this.#previousKeyDown[k]) { return true }
if (this.#keyDown[k] && !this.#previousKeyDown[k]) {
return true;
}
}
for (let k of Object.keys(this.#mouseDown)) {
if (this.#mouseDown[k] && !this.#previousMouseDown[k]) { return true }
if (this.#mouseDown[k] && !this.#previousMouseDown[k]) {
return true;
}
}
return false;
}
@ -127,4 +142,4 @@ let active = new Input();
export function getInput(): Input {
return active;
}
}

View File

@ -1,14 +1,14 @@
import {Size} from "../datatypes.ts";
import { Size } from "../datatypes.ts";
// TODO: Just switch to the same pattern as everywhere else
// (without repeatedly reassigning the variable)
class Screen {
#canvas: HTMLCanvasElement
size: Size
#canvas: HTMLCanvasElement;
size: Size;
constructor(canvas: HTMLCanvasElement, size: Size) {
this.#canvas = canvas;
this.size = size
this.size = size;
}
unsafeMakeContext(): CanvasRenderingContext2D {
@ -26,8 +26,7 @@ class Screen {
}
}
let active: Screen | undefined = undefined
let active: Screen | undefined = undefined;
// TODO: Move these to Game?
export let desiredWidth = 400;
@ -45,9 +44,9 @@ export function pollAndTouch(canvas: HTMLCanvasElement) {
let div = 0;
while (
(div < divisors.length - 1) &&
(realWidth / divisors[div + 1] >= desiredWidth) &&
(realHeight / divisors[div + 1] >= desiredHeight)
div < divisors.length - 1 &&
realWidth / divisors[div + 1] >= desiredWidth &&
realHeight / divisors[div + 1] >= desiredHeight
) {
div += 1;
}
@ -60,9 +59,7 @@ export function pollAndTouch(canvas: HTMLCanvasElement) {
export function getScreen(): Screen {
if (active === undefined) {
throw `screen should have been defined: ${active}`
throw `screen should have been defined: ${active}`;
}
return active;
}

View File

@ -1,6 +1,5 @@
import {getAssets} from "./assets.ts";
import {Point, Size} from "../datatypes.ts";
import { getAssets } from "./assets.ts";
import { Point, Size } from "../datatypes.ts";
export class Sprite {
readonly imageSet: string;
@ -11,7 +10,13 @@ export class Sprite {
// number of frames
readonly nFrames: number;
constructor(imageSet: string, pixelsPerSubimage: Size, origin: Point, cellsPerSheet: Size, nFrames: number) {
constructor(
imageSet: string,
pixelsPerSubimage: Size,
origin: Point,
cellsPerSheet: Size,
nFrames: number,
) {
this.imageSet = imageSet;
this.pixelsPerSubimage = pixelsPerSubimage;
this.origin = origin;
@ -24,7 +29,22 @@ export class Sprite {
}
}
internalDraw(ctx: CanvasRenderingContext2D, {position, ix, xScale, yScale, angle}: {position: Point, ix?: number, xScale?: number, yScale?: number, angle?: number}) {
internalDraw(
ctx: CanvasRenderingContext2D,
{
position,
ix,
xScale,
yScale,
angle,
}: {
position: Point;
ix?: number;
xScale?: number;
yScale?: number;
angle?: number;
},
) {
ix = ix == undefined ? 0 : ix;
xScale = xScale == undefined ? 1.0 : xScale;
yScale = yScale == undefined ? 1.0 : yScale;
@ -32,7 +52,7 @@ export class Sprite {
// ctx.translate(Math.floor(x), Math.floor(y));
ctx.translate(Math.floor(position.x), Math.floor(position.y));
ctx.rotate(angle * Math.PI / 180);
ctx.rotate((angle * Math.PI) / 180);
ctx.scale(xScale, yScale);
ctx.translate(-this.origin.x, -this.origin.y);
@ -41,6 +61,16 @@ export class Sprite {
let srcCy = Math.floor(ix / this.cellsPerSheet.w);
let srcPx = srcCx * this.pixelsPerSubimage.w;
let srcPy = srcCy * this.pixelsPerSubimage.h;
ctx.drawImage(me, srcPx, srcPy, this.pixelsPerSubimage.w, this.pixelsPerSubimage.h, 0, 0, this.pixelsPerSubimage.w, this.pixelsPerSubimage.h);
ctx.drawImage(
me,
srcPx,
srcPy,
this.pixelsPerSubimage.w,
this.pixelsPerSubimage.h,
0,
0,
this.pixelsPerSubimage.w,
this.pixelsPerSubimage.h,
);
}
}

View File

@ -1,4 +1,5 @@
html, body {
html,
body {
padding: 0;
margin: 0;
width: 100%;
@ -9,4 +10,4 @@ html, body {
image-rendering: pixelated;
width: 100%;
height: 100%;
}
}

View File

@ -1,5 +1,5 @@
import {getInput} from "./internal/input.ts";
import {getDrawing} from "./internal/drawing.ts";
import { getInput } from "./internal/input.ts";
import { getDrawing } from "./internal/drawing.ts";
// input reexports
export let I = getInput();