feat: initialize mini program map engine
This commit is contained in:
98
miniprogram/engine/camera/camera.ts
Normal file
98
miniprogram/engine/camera/camera.ts
Normal 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user