Non-grid-based movement

This commit is contained in:
2025-02-22 15:50:03 -08:00
parent a528ffd9e0
commit b45f81e6c6
4 changed files with 303 additions and 84 deletions

View File

@ -84,6 +84,13 @@ export class Point {
return new Point(this.x * other.w, this.y * other.h);
}
unscale(other: Point | Size) {
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);
}
subtract(top: Point): Size {
return new Size(this.x - top.x, this.y - top.y);
}
@ -91,6 +98,13 @@ export class Point {
manhattan(other: Point) {
return Math.abs(this.x - other.x) + Math.abs(this.y - other.y);
}
snap(x: number, y: number) {
return new Point(
lerp(x, Math.floor(this.x), Math.ceil(this.x)),
lerp(y, Math.floor(this.y), Math.ceil(this.y))
);
}
}
export class Size {
@ -118,12 +132,16 @@ export class Size {
export class Rect {
readonly top: Point;
readonly size: Size;
constructor(top: Point, size: Size) {
this.top = top;
this.size = size;
}
toString(): string {
return `Rect(${this.top},${this.size})`;
}
offset(offset: Point) {
return new Rect(this.top.offset(offset), this.size);
}
@ -137,6 +155,28 @@ export class Rect {
);
}
overlappedCells(size: Size) {
let x0 = this.top.x;
let y0 = this.top.y;
let x1 = x0 + this.size.w;
let y1 = y0 + this.size.w;
let cx0 = Math.floor(x0 / size.w);
let cy0 = Math.floor(y0 / size.h);
let cx1 = Math.ceil(x1 / size.w);
let cy1 = Math.ceil(y1 / size.h);
let cells = [];
for (let cy = cy0; cy < cy1; cy++) {
for (let cx = cx0; cx < cx1; cx++) {
let px0 = cx * size.w;
let py0 = cy * size.h;
cells.push(new Rect(new Point(px0, py0), size));
}
}
return cells;
}
overlaps(other: Rect) {
let ax0 = this.top.x;
let ay0 = this.top.y;
@ -254,3 +294,13 @@ export enum AlignY {
Middle = 1,
Bottom = 2,
}
export function lerp(amt: number, lo: number, hi: number) {
if (amt <= 0) {
return lo;
}
if (amt >= 1) {
return hi;
}
return lo + (hi - lo) * amt;
};