import random from random import randint import pygame import configparser from pygame import Color from domain.entities.cat import Cat from domain.entities.entity import Entity from domain.world import World config = configparser.ConfigParser() config.read("config.ini") class Renderer: def __init__( self, width=800, height=800, tiles_x=10, tiles_y=10, ): self.width = width self.height = height self.tiles_x = tiles_x self.tiles_y = tiles_y self.tile_width = self.width / self.tiles_x self.tile_height = self.height / self.tiles_y pygame.init() pygame.display.set_caption("AI Vacuum Cleaner") self.screen = pygame.display.set_mode((self.width, self.height)) self.font = pygame.font.SysFont("Arial", 26, bold=True) self.sprites = { "VACUUM": pygame.transform.scale( pygame.image.load("media/sprites/vacuum.png"), (self.tile_width, self.tile_height), ), "DOC_STATION": pygame.transform.scale( pygame.image.load("media/sprites/docking_station.png"), (self.tile_width, self.tile_height), ), "WALL": pygame.transform.scale( pygame.image.load("media/sprites/wall.png"), (self.tile_width, self.tile_height), ), "TILE": pygame.transform.scale( pygame.image.load("media/sprites/tile_cropped.jpeg"), (self.tile_width, self.tile_height), ), "PEEL": pygame.transform.scale( pygame.image.load("media/sprites/peel.webp"), (self.tile_width, self.tile_height), ), "CAT_FRONT": pygame.transform.scale( pygame.image.load("media/sprites/cat/standing_front.png"), (self.tile_width, self.tile_height), ), "CAT_BACK": pygame.transform.scale( pygame.image.load("media/sprites/cat/standing_back.png"), (self.tile_width, self.tile_height), ), "CAT_LEFT": pygame.transform.scale( pygame.image.load("media/sprites/cat/standing_left.png"), (self.tile_width, self.tile_height), ), "CAT_RIGHT": pygame.transform.scale( pygame.image.load("media/sprites/cat/standing_right.png"), (self.tile_width, self.tile_height), ), "PLANT1": pygame.transform.scale( pygame.image.load("media/sprites/plants/plant1.png"), ( self.tile_width + self.tile_width / 4, self.tile_height + self.tile_height / 4, ), ), "PLANT2": pygame.transform.scale( pygame.image.load("media/sprites/plants/plant2.png"), ( self.tile_width + self.tile_width / 4, self.tile_height + self.tile_height / 4, ), ), "PLANT3": pygame.transform.scale( pygame.image.load("media/sprites/plants/plant3.png"), ( self.tile_width + self.tile_width / 4, self.tile_height + self.tile_height / 4, ), ), } self.cat_direction_sprite = { 0: self.sprites["CAT_BACK"], 1: self.sprites["CAT_RIGHT"], 2: self.sprites["CAT_FRONT"], 3: self.sprites["CAT_LEFT"], } def render(self, world: World): self.render_floor() self.render_board() for x in range(world.width): for y in range(world.height): for entity in world.dust[x][y]: self.draw_entity(entity) for x in range(world.width): for y in range(world.height): for entity in world.obstacles[x][y]: self.draw_entity(entity) self.draw_entity(world.vacuum) self.draw_entity(world.doc_station) if config.getboolean("APP", "cat"): self.draw_entity(world.cat) pygame.display.update() def line(self, x_1, y_1, x_2, y_2, color=None): pygame.draw.line(self.screen, color, (x_1, y_1), (x_2, y_2)) def render_board(self, color=Color("black")): for i in range(1, self.tiles_x): self.line( self.tile_width * i, 0, self.tile_width * i, self.height, color=color ) for i in range(1, self.tiles_y): self.line( 0, self.tile_height * i, self.width, self.tile_height * i, color=color ) def draw_entity(self, entity: Entity): sprite = self.sprites.get(entity.type, None) draw_pos = (entity.x * self.tile_width, entity.y * self.tile_height) if "PEEL" in entity.type: draw_pos = ( (entity.x - 0.1) * self.tile_width, (entity.y - 0.25) * self.tile_height, ) if "PLANT" in entity.type: draw_pos = ( (entity.x - 0.1) * self.tile_width, (entity.y - 0.25) * self.tile_height, ) if "CAT" in entity.type and isinstance(entity, Cat): sprite = self.cat_direction_sprite[entity.direction] if "VACUUM" in entity.type: # Add text displaying container filling level text_surface = self.font.render( f"Filling: {entity.container_filling}%", True, Color("black") ) text_pos = ( draw_pos[0] + self.tile_width / 2 - text_surface.get_width() / 2, draw_pos[1] + self.tile_height, ) self.screen.blit(text_surface, text_pos) sprite = self.create_vacuum_sprite(entity) if "DOC_STATION" in entity.type: draw_pos = ( (entity.x - 0.1) * self.tile_width, (entity.y - 0.25) * self.tile_height, ) self.screen.blit(sprite, draw_pos) def create_vacuum_sprite(self, vacuum): angles = { (1, 0): 0, (-1, 0): 180, (0, 1): 270, (0, -1): 90, } init_sprite = self.sprites.get(vacuum.type, None) return pygame.transform.rotate(init_sprite, angles[vacuum.direction]) def draw_sprite(self, x: int, y: int, sprite_name: str): self.screen.blit( self.sprites[sprite_name], (x * self.tile_width, y * self.tile_height) ) def fill_grid_with_sprite(self, sprite): for tile_x in range(self.tiles_x): for tile_y in range(self.tiles_y): self.draw_sprite(tile_x, tile_y, sprite) def render_floor(self): self.fill_grid_with_sprite("TILE")