Engine refactors 1

This commit is contained in:
2025-02-01 20:30:03 -08:00
parent 786a1d2e8d
commit 501d0e4dff
19 changed files with 515 additions and 363 deletions

147
src/engine/datatypes.ts Normal file
View File

@ -0,0 +1,147 @@
export interface IGame {
update(): void;
draw(): void;
}
export class Color {
readonly r: number;
readonly g: number;
readonly b: number;
readonly a: number;
constructor(r: number, g: number, b: number, a?: number) {
this.r = r;
this.g = g;
this.b = b;
this.a = a ?? 255;
}
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})?/;
let result = regex1.exec(hexCode) ?? regex2.exec(hexCode);
if (result == null) {
throw `could not parse color: ${hexCode}`
}
let parseGroup = (s: string | undefined): number => {
if (s === undefined) {
return 255;
}
if (s.length == 1) {
return 17 * parseInt(s, 16);
}
return parseInt(s, 16);
}
return new Color(
parseGroup(result[1]),
parseGroup(result[2]),
parseGroup(result[3]),
parseGroup(result[4]),
);
}
toStyle(): string {
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a / 255.0})`
}
}
export class Point {
readonly x: number;
readonly y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
offset(other: Point | Size): Point {
if (other instanceof Point) {
return new Point(this.x + other.x, this.y + other.y);
}
return new Point(this.x + other.w, this.y + other.h);
}
negate() {
return new Point(-this.x, -this.y);
}
}
export class Size {
readonly w: number;
readonly h: number;
constructor(w: number, h: number) {
this.w = w;
this.h = h;
}
}
export class Grid<T> {
data: T[][];
constructor({size, cbDefault}: {size: Size, cbDefault: (xy: Point) => T}) {
this.data = [];
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)))
}
this.data.push(row);
}
}
static createGridFromStringArray(ary: Array<string>): Grid<string> {
let w = 0;
let h = ary.length;
for (let i = 0; i < h - 1; i++) {
let w1 = ary[i].length;
let w2 = ary[i + 1].length;
if (w1 != w2) {
throw `createGridFromStringArray: must be grid-shaped, got ${ary}`
}
w = w1;
}
return new Grid({
size: new Size(w, h),
cbDefault: (xy) => {
return ary[xy.y].charAt(xy.x);
}
})
}
static createGridFromJaggedArray<T>(ary: Array<Array<T>>): Grid<T> {
let w = 0;
let h = ary.length;
for (let i = 0; i < h - 1; i++) {
let w1 = ary[i].length;
let w2 = ary[i + 1].length;
if (w1 != w2) {
throw `createGridFromJaggedArray: must be grid-shaped, got ${ary}`
}
w = w1;
}
return new Grid({
size: new Size(w, h),
cbDefault: (xy) => {
return ary[xy.y][xy.x];
}
})
}
}
export enum AlignX {
Left = 0,
Center = 1,
Right = 2
}
export enum AlignY {
Top = 0,
Middle = 1,
Right = 2,
}