added docstrings to every file and function. (with claude, checked it)
tower and game_play dont meet pylint check yet.
This commit is contained in:
+81
-28
@@ -1,11 +1,21 @@
|
||||
import pygame, json
|
||||
"""Tilemap module - tile storage, serialisation, placement rules, and rendering.
|
||||
|
||||
"""
|
||||
Todo:
|
||||
* Add prop system for Trees, etc. (like off_grid), handle blocked with game objects over props
|
||||
"""
|
||||
import json
|
||||
import pygame
|
||||
|
||||
class Tilemap:
|
||||
"""Stores and manages the tile grid, waypoints, and rendering.
|
||||
|
||||
Attributes:
|
||||
tile_size (int): Width and height of a single tile in pixels.
|
||||
tilemap (dict): Tile data keyed by ``"x;y"`` string positions.
|
||||
planned: offgrid_tiles (list): Tiles placed outside the main grid (e.g. decorations).
|
||||
waypoints (list): Ordered world positions enemies follow.
|
||||
tower_placeable (list[dict]): Tile descriptors that allow tower placement.
|
||||
"""
|
||||
def __init__(self, game, tile=16):
|
||||
self.game = game
|
||||
self.tile_size = tile
|
||||
@@ -16,20 +26,42 @@ class Tilemap:
|
||||
self.tower_placeable = [{"type": "desert", "variant": 0}]
|
||||
|
||||
def save(self, path):
|
||||
f = open(path, 'w')
|
||||
json.dump({'tilemap': self.tilemap, 'tile_size': self.tile_size, 'waypoints': self.waypoints}, f)
|
||||
f.close()
|
||||
"""Serialise the tilemap, tile size, and waypoints to a JSON file.
|
||||
|
||||
Args:
|
||||
path (str): File path to write to.
|
||||
"""
|
||||
with open(path, 'w', encoding='utf-8') as f:
|
||||
json.dump({
|
||||
'tilemap': self.tilemap,
|
||||
'tile_size': self.tile_size,
|
||||
'waypoints': self.waypoints
|
||||
}, f)
|
||||
f.close()
|
||||
|
||||
def load(self, path):
|
||||
f = open(path, 'r')
|
||||
map_data = json.load(f)
|
||||
f.close()
|
||||
"""Load tilemap data from a JSON file, replacing current state.
|
||||
|
||||
self.tilemap = map_data['tilemap']
|
||||
self.tile_size = map_data['tile_size']
|
||||
self.waypoints = map_data['waypoints']
|
||||
Args:
|
||||
path (str): File path to read from.
|
||||
"""
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
map_data = json.load(f)
|
||||
f.close()
|
||||
|
||||
self.tilemap = map_data['tilemap']
|
||||
self.tile_size = map_data['tile_size']
|
||||
self.waypoints = map_data['waypoints']
|
||||
|
||||
def placeable(self, tile_pos):
|
||||
"""Check whether a tower can be placed on the tile at tile_pos.
|
||||
|
||||
Args:
|
||||
tile_pos (tuple[int, int]): Grid position ``(x, y)`` to check.
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if the tile exists and is in ``tower_placeable``.
|
||||
"""
|
||||
str_tile_pos = f'{tile_pos[0]};{tile_pos[1]}'
|
||||
if str_tile_pos not in self.tilemap:
|
||||
return False
|
||||
@@ -41,14 +73,39 @@ class Tilemap:
|
||||
return False
|
||||
|
||||
def render(self, surf, offset=(0, 0)):
|
||||
for x in range(offset[0] // self.tile_size, (offset[0] + surf.get_width()) // self.tile_size + 1):
|
||||
for y in range(offset[1] // self.tile_size, (offset[1] + surf.get_height()) // self.tile_size + 1):
|
||||
"""Draw only the tiles visible within surf, using a pixel offset (editor).
|
||||
|
||||
Args:
|
||||
surf (pygame.Surface): Target surface to draw onto.
|
||||
offset (tuple[int, int]): Pixel scroll offset ``(x, y)``.
|
||||
"""
|
||||
start_x = offset[0] // self.tile_size
|
||||
end_x = (offset[0] + surf.get_width()) // self.tile_size + 1
|
||||
|
||||
start_y = offset[1] // self.tile_size
|
||||
end_y = (offset[1] + surf.get_height()) // self.tile_size + 1
|
||||
for x in range(start_x, end_x):
|
||||
for y in range(start_y, end_y):
|
||||
loc = str(x) + ';' + str(y)
|
||||
if loc in self.tilemap:
|
||||
tile = self.tilemap[loc]
|
||||
surf.blit(self.game.assets[tile['type']][tile['variant']], (tile['pos'][0] * self.tile_size - offset[0], tile['pos'][1] * self.tile_size - offset[1]))
|
||||
|
||||
surf.blit(
|
||||
self.game.assets[tile['type']][tile['variant']],
|
||||
(
|
||||
tile['pos'][0] * self.tile_size - offset[0],
|
||||
tile['pos'][1] * self.tile_size - offset[1]
|
||||
)
|
||||
)
|
||||
|
||||
def render_game(self, surf, camera):
|
||||
"""Draw only the tiles visible within surf, scaled to the camera zoom and pixel offset.
|
||||
|
||||
Args:
|
||||
surf (pygame.Surface): Target surface to draw onto.
|
||||
camera (Camera): Active camera for zoom level and coordinate conversion.
|
||||
|
||||
Todo: document this code below, not full understanding
|
||||
"""
|
||||
tile_size = self.tile_size
|
||||
zoom = camera.zoom
|
||||
scaled_tile_size = int(tile_size * zoom)
|
||||
@@ -67,16 +124,12 @@ class Tilemap:
|
||||
tile = self.tilemap[loc]
|
||||
image = self.game.assets[tile["type"]][tile["variant"]]
|
||||
|
||||
scaled_image = pygame.transform.scale(
|
||||
image,
|
||||
(scaled_tile_size, scaled_tile_size)
|
||||
)
|
||||
|
||||
world_pos = (
|
||||
tile["pos"][0] * tile_size,
|
||||
tile["pos"][1] * tile_size
|
||||
)
|
||||
|
||||
screen_pos = camera.world_to_screen(world_pos)
|
||||
|
||||
surf.blit(scaled_image, screen_pos)
|
||||
surf.blit(pygame.transform.scale(
|
||||
image,
|
||||
(scaled_tile_size, scaled_tile_size)
|
||||
), camera.world_to_screen(
|
||||
(
|
||||
tile["pos"][0] * tile_size,
|
||||
tile["pos"][1] * tile_size
|
||||
)
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user