import pygame import random from settings import * class World: def __init__(self): self.width = WORLD_WIDTH self.height = WORLD_HEIGHT # 2D grid: world[y][x] self.grid = [ [AIR for _ in range(self.width)] for _ in range(self.height) ] self.generate_world() # ========================================================== # WORLD GENERATION # ========================================================== def generate_world(self): for x in range(self.width): # Simple terrain height variation surface_height = SURFACE_LEVEL + random.randint(-3, 3) for y in range(self.height): if y < surface_height: self.grid[y][x] = AIR elif y == surface_height: self.grid[y][x] = GRASS elif y < surface_height + 5: self.grid[y][x] = DIRT else: self.grid[y][x] = STONE # ========================================================== # DRAW # ========================================================== def draw(self, screen, camera): # Determine visible tile range start_x = max(0, camera.offset.x // TILE_SIZE) end_x = min(self.width, (camera.offset.x + SCREEN_WIDTH) // TILE_SIZE + 2) start_y = max(0, camera.offset.y // TILE_SIZE) end_y = min(self.height, (camera.offset.y + SCREEN_HEIGHT) // TILE_SIZE + 2) for y in range(int(start_y), int(end_y)): for x in range(int(start_x), int(end_x)): tile_id = self.grid[y][x] if tile_id != AIR: color = TILE_PROPERTIES[tile_id]["color"] world_rect = pygame.Rect( x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE ) screen_rect = camera.apply(world_rect) pygame.draw.rect(screen, color, screen_rect) # ========================================================== # COLLISION SUPPORT # ========================================================== def get_nearby_tiles(self, rect): tiles = [] # Determine tile range around player start_x = max(0, rect.left // TILE_SIZE - 1) end_x = min(self.width, rect.right // TILE_SIZE + 2) start_y = max(0, rect.top // TILE_SIZE - 1) end_y = min(self.height, rect.bottom // TILE_SIZE + 2) for y in range(start_y, end_y): for x in range(start_x, end_x): tile_id = self.grid[y][x] if tile_id != AIR: tile_rect = pygame.Rect( x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE ) tiles.append({ "rect": tile_rect, "solid": TILE_PROPERTIES[tile_id]["solid"], "id": tile_id, "x": x, "y": y }) return tiles # ========================================================== # BLOCK BREAKING # ========================================================== def break_block(self, mouse_pos, camera): world_x, world_y = camera.screen_to_world(mouse_pos) tile_x = int(world_x // TILE_SIZE) tile_y = int(world_y // TILE_SIZE) if self.in_bounds(tile_x, tile_y): if self.grid[tile_y][tile_x] != AIR: self.grid[tile_y][tile_x] = AIR # ========================================================== # BLOCK PLACING # ========================================================== def place_block(self, mouse_pos, camera, block_type=DIRT): world_x, world_y = camera.screen_to_world(mouse_pos) tile_x = int(world_x // TILE_SIZE) tile_y = int(world_y // TILE_SIZE) if self.in_bounds(tile_x, tile_y): if self.grid[tile_y][tile_x] == AIR: self.grid[tile_y][tile_x] = block_type # ========================================================== # UTIL # ========================================================== def in_bounds(self, x, y): return 0 <= x < self.width and 0 <= y < self.height