Source code for rubato.structure.gameobject.tilemap.simple

"""
A simple tilemap doesn't need to use the Tiled editor. It uses an array of
numbers to keep track of tile types.
"""
from __future__ import annotations
from .. import Component, Rectangle
from .... import Vector, Surface, Draw
from copy import deepcopy


[docs]class SimpleTilemap(Component): """ A simple tilemap doesn't need to use the Tiled editor. It uses an array of numbers to keep track of tile types. Args: tilemap: A 2D array of integers representing the tilemap. tiles: A list of surfaces representing the tiles. The index of the surface in the list is the number used in the tilemap array. tile_size: The size of each tile in the tilemap. Defaults to (32, 32). collision: A list of integers representing the tiles that should have collision. Defaults to []. collider_tag: A list of strings representing the tags of the colliders. The index of the tag in the list is the number used in the tilemap array. Defaults to []. scale: The scale of the tilemap. Defaults to (1, 1). offset: The offset of the tilemap. Defaults to (0, 0). rot_offset: The rotation offset of the tilemap. Defaults to 0. z_index: The z-index of the tilemap. Defaults to 0. hidden: Whether the tilemap is hidden. Defaults to False. """ def __init__( self, tilemap: list[list[int]], tiles: list[Surface], tile_size: Vector | tuple[int, int] = (32, 32), collision: list[int] | None = None, collider_tag: list[str] | None = None, scale: Vector | tuple[float, float] = (1, 1), offset: Vector | tuple[float, float] = (0, 0), rot_offset: float = 0, z_index: int = 0, hidden: bool = False ): super().__init__(offset, rot_offset, z_index, hidden) self._map = tilemap self._tiles = tiles self._tile_size = Vector.create(tile_size) self._collision = [] if collision is None else collision self._collider_tag = [] if collider_tag is None else collider_tag self.scale = Vector.create(scale) """The scale of the tilemap.""" self._result = Surface(1, 1, scale) self.uptodate = False """Whether the tilemap is up to date.""" def _regen(self): dims = max([len(row) for row in self._map]), len(self._map) self._result = Surface(int(dims[0] * self._tile_size.x), int(dims[1] * self._tile_size.y)) for i, row in enumerate(self._map): y = (i * self._tile_size.y) - self._result.height / 2 + self._tile_size.y / 2 for j, tile in enumerate(row): x = (j * self._tile_size.x) - self._result.width / 2 + self._tile_size.x / 2 self._result.blit(self._tiles[tile], dst=(int(x), int(y))) if tile in self._collision: self.gameobj.add( # TODO: add to a child gameobject when that's a thing Rectangle( *(self._tile_size * self.scale).tuple_int(), tag=self._collider_tag[tile] if tile < len(self._collider_tag) else "", offset=(x, y) * self.scale, ) )
[docs] def update(self): if not self.uptodate: self._regen() self.uptodate = True
[docs] def draw(self, camera): self._result.scale = self.scale self._result.rotation = self.true_rotation() Draw.queue_surface(self._result, self.true_pos(), self.true_z(), camera)
[docs] def clone(self) -> SimpleTilemap: s = SimpleTilemap( deepcopy(self._map), [surf.clone() for surf in self._tiles], self._tile_size.clone(), deepcopy(self._collision), deepcopy(self._collider_tag), self.scale.clone(), self.offset.clone(), self.rot_offset, self.z_index, self.hidden, ) s._result = self._result.clone() return s