2024-07-10 20:08:18 +02:00
import pygame
import numpy as np
2024-07-12 22:04:31 +02:00
from scripts . utils import TILE_DICT , to_isometric_pixel
2024-07-10 20:08:18 +02:00
BASE_MAP_PATH = ' data/maps/ '
2024-07-12 22:04:31 +02:00
NEIGHBOR_OFFSETS = [ np . array ( ( i , j ) ) for i in ( - 1 , 0 , 1 ) for j in ( - 1 , 0 , 1 ) ]
2024-07-10 20:08:18 +02:00
class Tilemap :
2024-07-17 00:08:42 +02:00
def __init__ ( self , game , tile_size , map_path = None ) :
2024-07-10 20:08:18 +02:00
self . game = game
self . tile_size = np . array ( tile_size )
self . offgrid_tiles = [ ]
2024-07-17 00:08:42 +02:00
if map_path :
self . load_map ( map_path )
2024-07-10 20:08:18 +02:00
def load_map ( self , map_path ) :
print ( map_path )
tile_arr = np . transpose ( np . loadtxt ( BASE_MAP_PATH + map_path , delimiter = ' , ' , dtype = np . int8 ) )
self . tilemap = np . empty_like ( tile_arr , dtype = object )
for row in range ( tile_arr . shape [ 0 ] ) :
for col in range ( tile_arr . shape [ 1 ] ) :
type_var = TILE_DICT [ tile_arr [ row , col ] ]
2024-07-12 22:04:31 +02:00
self . tilemap [ row , col ] = { ' type ' : type_var [ 0 ] , ' variant ' : type_var [ 1 ] , ' pos ' : np . array ( [ row , col ] ) , ' walkable ' : type_var [ 2 ] }
def render ( self , surface , offset = np . array ( [ 0 , 0 ] ) ) :
2024-07-10 20:08:18 +02:00
for x in range ( self . tilemap . shape [ 0 ] ) :
for y in range ( self . tilemap . shape [ 1 ] ) :
tile = self . tilemap [ x , y ]
2024-07-12 22:04:31 +02:00
surface . blit ( self . game . assets [ tile [ ' type ' ] ] [ tile [ ' variant ' ] ] , ( to_isometric_pixel ( tile [ ' pos ' ] ) * self . tile_size ) - offset )
2024-07-10 20:08:18 +02:00
for tile in self . offgrid_tiles :
2024-07-12 22:04:31 +02:00
surface . blit ( self . game . assets [ tile [ ' type ' ] ] [ tile [ ' variant ' ] ] , ( to_isometric_pixel ( tile [ ' pos ' ] ) * self . tile_size ) - offset ) #this tile is written offgrid so no mult by tile_size
def tiles_around ( self , pos ) :
tiles = [ ]
tile_loc = np . array ( pos / / np . array ( ( self . tile_size [ 0 ] , self . tile_size [ 0 ] ) ) , dtype = int ) #gotta use this and not just self.tile_size to normalize wrt the change of variables for the isometric view
for offset in NEIGHBOR_OFFSETS :
check_loc = tile_loc + offset
if np . all ( check_loc > = 0 ) and np . all ( check_loc < self . tilemap . shape ) :
tiles . append ( self . tilemap [ tuple ( check_loc ) ] )
return tiles
def physics_rects_around ( self , pos ) :
rects = [ ]
for tile in self . tiles_around ( pos ) :
if not tile [ ' walkable ' ] :
rects . append ( pygame . Rect ( tile [ ' pos ' ] * np . array ( ( self . tile_size [ 0 ] , self . tile_size [ 0 ] ) ) , np . array ( ( self . tile_size [ 0 ] , self . tile_size [ 0 ] ) ) ) )
return rects