nodes/iso.pyΒΆ
Part of Tiny Yurts.
1"""Isometric projection helpers and the colour palette.
2
3The original Tiny Yurts board is flat and top-down; this port deviates into a
4shallow isometric (~30 deg) projection, so every cell has to be projected to
5screen space before it is drawn or hit-tested. World coordinates are grid cells
6(i, j); screen coordinates are pixels.
7"""
8
9from __future__ import annotations
10
11# Iso tile half-extents (pixels on screen).
12TILE_W_HALF = 36.0
13TILE_H_HALF = 18.0
14
15# Grid dimensions (cells).
16GRID_COLS = 12
17GRID_ROWS = 8
18
19# Where the (0, 0) cell sits on screen. Re-anchored on every layout pass.
20ORIGIN_X = 640.0
21ORIGIN_Y = 200.0
22
23
24def set_origin(x: float, y: float) -> None:
25 """Re-anchor the iso projection (called on resize)."""
26 global ORIGIN_X, ORIGIN_Y
27 ORIGIN_X = x
28 ORIGIN_Y = y
29
30
31def world_to_screen(i: float, j: float) -> tuple[float, float]:
32 """Cell space (i, j) -> screen pixel."""
33 return (
34 ORIGIN_X + (i - j) * TILE_W_HALF,
35 ORIGIN_Y + (i + j) * TILE_H_HALF,
36 )
37
38
39def screen_to_cell(x: float, y: float) -> tuple[int, int]:
40 """Screen pixel -> nearest grid cell. Returns (i, j); may be out of bounds."""
41 dx = x - ORIGIN_X
42 dy = y - ORIGIN_Y
43 fi = (dx / TILE_W_HALF + dy / TILE_H_HALF) * 0.5
44 fj = (dy / TILE_H_HALF - dx / TILE_W_HALF) * 0.5
45 return (int(round(fi)), int(round(fj)))
46
47
48def tile_corners(i: float, j: float) -> list[tuple[float, float]]:
49 """Diamond corners (top, right, bottom, left) for a tile at (i, j)."""
50 cx, cy = world_to_screen(i, j)
51 return [
52 (cx, cy - TILE_H_HALF),
53 (cx + TILE_W_HALF, cy),
54 (cx, cy + TILE_H_HALF),
55 (cx - TILE_W_HALF, cy),
56 ]
57
58
59def in_bounds(i: int, j: int) -> bool:
60 return 0 <= i < GRID_COLS and 0 <= j < GRID_ROWS
61
62
63# Palette
64COLOUR_GRASS = (0.45, 0.70, 0.36, 1.0)
65COLOUR_GRASS_DARK = (0.36, 0.60, 0.28, 1.0)
66COLOUR_GRID = (0.32, 0.52, 0.24, 1.0)
67COLOUR_PATH = (0.78, 0.65, 0.42, 1.0)
68COLOUR_PATH_PREVIEW = (0.95, 0.85, 0.55, 1.0)
69COLOUR_OX = (0.55, 0.30, 0.20, 1.0)
70COLOUR_GOAT = (0.85, 0.78, 0.62, 1.0)
71COLOUR_FISH = (0.40, 0.65, 0.85, 1.0)
72COLOUR_YURT = (0.92, 0.84, 0.60, 1.0)
73COLOUR_YURT_ROOF = (0.55, 0.36, 0.22, 1.0)
74COLOUR_WARN = (0.90, 0.30, 0.25, 1.0)
75COLOUR_OK = (0.30, 0.85, 0.40, 1.0)
76COLOUR_HUD_BG = (0.12, 0.16, 0.14, 0.85)
77COLOUR_CONTROLS_BG = (0.85, 0.85, 0.85, 1.0)