from __future__ import annotations
from collections import OrderedDict
from typing import List, Optional, Tuple, TYPE_CHECKING
import miniworlds.worlds.tiled_world.tile_elements as tile_elements
import miniworlds.base.app as app
if TYPE_CHECKING:
from miniworlds.worlds.tiled_world.corner import Corner
from miniworlds.worlds.tiled_world.tiled_world import TiledWorld
from miniworlds.positions.vector import Vector
[Doku]
class Tile(tile_elements.TileBase):
tile_vectors: dict[str, Tuple[int, int]] = {
"w": (+1, 0),
"nw": (+1, +1),
"no": (-1, +1),
"o": (-1, 0),
"so": (-1, -1),
"sw": (+1, -1),
}
corner_vectors: OrderedDict[str, Tuple[float, float]] = OrderedDict([
("nw", (+0.5, +0.5)),
("no", (-0.5, +0.5)),
("so", (-0.5, -0.5)),
("sw", (+0.5, -0.5)),
])
edge_vectors: dict[str, Tuple[float, float]] = {
"w": (-0.5, 0),
"o": (+0.5, 0),
"s": (0, +0.5),
"n": (0, -0.5),
}
def __init__(self, position: Tuple[int, int], world: Optional[TiledWorld] = None):
super().__init__(position, world)
self._cached_corners: Optional[List[Corner]] = None # Cache explizit und privat
[Doku]
@classmethod
def from_position(cls, position: Tuple[int, int], world: TiledWorld) -> Tile:
return world.get_tile(position)
[Doku]
@classmethod
def from_actor(cls, actor) -> Tile:
return actor.world.get_tile(actor.position)
[Doku]
def get_neighbour_corners(self) -> List[Corner]:
if self._cached_corners is not None:
return self._cached_corners
neighbours = []
for vector in self.corner_vectors.values():
corner = self.world.get_corner(self.position + vector)
if corner:
neighbours.append(corner)
self._cached_corners = neighbours
return neighbours
[Doku]
def to_pixel(self) -> Tuple[float, float]:
x = self.position[0] * self.world.tile_size
y = self.position[1] * self.world.tile_size
return x, y
[Doku]
@staticmethod
def get_position_pixel_dict(world: TiledWorld) -> dict:
return world.get_center_points()
[Doku]
def to_center(self) -> Tuple[float, float]:
x, y = self.to_pixel()
dx, dy = self.get_local_center_coordinate(self.world)
return x + dx, y + dy
[Doku]
@classmethod
def from_pixel(cls, pixel_position: Tuple[float, float], world: Optional[TiledWorld] = None) -> Tile:
if world is None:
world = app.App.get_running_world()
x = int(pixel_position[0] // world.tile_size)
y = int(pixel_position[1] // world.tile_size)
return cls((x, y), world)
def __sub__(self, other: Tile) -> Vector:
from miniworlds.positions.vector import Vector
return Vector(self.position[0] - other.position[0], self.position[1] - other.position[1])
[Doku]
def distance_to(self, other: Tile) -> float:
return (self - other).length()