Machine_learning_2023/view/renderer.py

199 lines
7.0 KiB
Python

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,
),
),
"EARRING": pygame.transform.scale(
pygame.image.load("media/sprites/earrings.webp"),
(
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")