feat: initialize mini program map engine

This commit is contained in:
2026-03-19 15:58:48 +08:00
commit 03abe28d8c
49 changed files with 28584 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
export interface CameraState {
centerWorldX: number
centerWorldY: number
viewportWidth: number
viewportHeight: number
visibleColumns: number
translateX?: number
translateY?: number
rotationRad?: number
}
export interface ScreenPoint {
x: number
y: number
}
export interface WorldPoint {
x: number
y: number
}
export function getTileSizePx(camera: CameraState): number {
if (!camera.viewportWidth || !camera.visibleColumns) {
return 0
}
return camera.viewportWidth / camera.visibleColumns
}
export function rotateScreenPoint(point: ScreenPoint, centerX: number, centerY: number, rotationRad: number): ScreenPoint {
if (!rotationRad) {
return point
}
const deltaX = point.x - centerX
const deltaY = point.y - centerY
const cos = Math.cos(rotationRad)
const sin = Math.sin(rotationRad)
return {
x: centerX + deltaX * cos - deltaY * sin,
y: centerY + deltaX * sin + deltaY * cos,
}
}
export function worldToScreen(
camera: CameraState,
world: WorldPoint,
includeTranslate = false,
): ScreenPoint {
const tileSize = getTileSizePx(camera)
const translateX = includeTranslate ? (camera.translateX || 0) : 0
const translateY = includeTranslate ? (camera.translateY || 0) : 0
const centerX = camera.viewportWidth / 2
const centerY = camera.viewportHeight / 2
const rotated = rotateScreenPoint(
{
x: centerX + (world.x - camera.centerWorldX) * tileSize,
y: centerY + (world.y - camera.centerWorldY) * tileSize,
},
centerX,
centerY,
camera.rotationRad || 0,
)
return {
x: rotated.x + translateX,
y: rotated.y + translateY,
}
}
export function screenToWorld(
camera: CameraState,
screen: ScreenPoint,
includeTranslate = true,
): WorldPoint {
const tileSize = getTileSizePx(camera)
const translateX = includeTranslate ? (camera.translateX || 0) : 0
const translateY = includeTranslate ? (camera.translateY || 0) : 0
const centerX = camera.viewportWidth / 2
const centerY = camera.viewportHeight / 2
const unrotated = rotateScreenPoint(
{
x: screen.x - translateX,
y: screen.y - translateY,
},
centerX,
centerY,
-(camera.rotationRad || 0),
)
return {
x: camera.centerWorldX + (unrotated.x - centerX) / tileSize,
y: camera.centerWorldY + (unrotated.y - centerY) / tileSize,
}
}