214 lines
8.3 KiB
Python
214 lines
8.3 KiB
Python
import pygame
|
|
from src.desk import Desk
|
|
from src.settings import DESK_WIDTH, DESK_HEIGHT
|
|
|
|
# Fenstergröße und Tile Größe (Felder)
|
|
tile_size = 30
|
|
screen_w = 1900
|
|
screen_h = 900
|
|
|
|
# Farben für die einzelnen Tiles
|
|
color_wall = (30, 20, 40) # black like
|
|
color_room = (75, 40, 55) # dark red-violet
|
|
color_hall = (35, 65, 45) # dark green
|
|
color_door = (40, 90, 110) # dark blue
|
|
color_void = (10, 10, 15) # a little more black
|
|
color_text = (220, 180, 210) # rose
|
|
color_border = (55, 35, 70)
|
|
color_start = (255, 0, 0)# dark violet
|
|
|
|
|
|
class Map:
|
|
def __init__(self):
|
|
|
|
# Map wird mit "Tiles" (30x30 Feldern aufgebaut
|
|
# W=Wall, R=Room, S=Start, H=Hall, D=Door
|
|
self.map = [
|
|
"WWWWWWWWWWWWWWWWWWWHHSSHHWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
|
|
"WWWWWWWWWWWWWWWWWWWHHHHHHWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWRRRRRRRRRRRRRRRWWHHHHHHWWRRRRRRRRRRRRRRRWWRRRRRRRRRRRRRRRWW",
|
|
"WWWWWWWWWWWWWWWDDWWHHHHHHWWWWWWWWWWWWWWDDWWWWDDWWWWWWWWWWWWWW",
|
|
"WWWWWWWWWWWWWWWDDWWHHHHHHWWWWWWWWWWWWWWDDWWWWDDWWWWWWWWWWWWWW",
|
|
"WWHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHWW",
|
|
"WWHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHWW",
|
|
"WWHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHDD",
|
|
"WWHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHDD",
|
|
"WWHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHWW",
|
|
"WWHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHWW",
|
|
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
|
|
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
|
|
]
|
|
|
|
# Raumbeschreibung in (Spalte, Zeile, Beschreibung)
|
|
# gibt an wo der Raumname auf dem Bildschirm angezeigt wird
|
|
self.room_decription = [
|
|
(7, 13, "Room 102"),
|
|
(32, 13, "Room 103"),
|
|
(49, 13, "Room 105")
|
|
]
|
|
|
|
# die Räume als Pixel-Rechtecke, Spalte und Zeile aus der Map * tile_size
|
|
# die Reihenfolge ist: x - y - breite - höhe | in Pixel
|
|
self.rooms: dict[str, pygame.Rect] = {
|
|
"Room 102": pygame.Rect(2 * tile_size, 2 * tile_size, 15 * tile_size, 10 * tile_size),
|
|
"Room 103": pygame.Rect(27 * tile_size, 2 * tile_size, 15 * tile_size, 10 * tile_size),
|
|
"Room 105": pygame.Rect(44 * tile_size, 2 * tile_size, 15 * tile_size, 10 * tile_size),
|
|
}
|
|
|
|
# soll automatisch einen Tisch ind er MItte des Raumes erstellen
|
|
self.desks: dict[str, list[Desk]] = {}
|
|
for room_name, room_rect in self.rooms.items():
|
|
# berechnet die Mitte des Raumes, zieht die Tischgröße ab, damit er wirklich zentriert ist
|
|
center_x = room_rect.centerx - DESK_WIDTH // 2
|
|
center_y = room_rect.centery - DESK_HEIGHT // 2
|
|
|
|
# erstell einen Tisch pro Raum und speichert ihn
|
|
self.desks[room_name] = [Desk(center_x, center_y)]
|
|
|
|
|
|
|
|
def get_tile(self, column: int, row: int):
|
|
# ein check, ob die Position innerhalb der Map liegt
|
|
if 0 <= row < len(self.map) and 0 <= column < len(self.map[row]):
|
|
# gibt den Buchstaben der Position zurück
|
|
return self.map[row][column]
|
|
# falls Außerhalb der Map, ein return als Wand
|
|
return "W"
|
|
|
|
def is_accessible(self, column: int, row: int) -> bool:
|
|
# gibt True zurück, wenn der Spieler das Tile betreten darf
|
|
return self.get_tile(column, row) in ("R", "D", "H", "S")
|
|
|
|
|
|
# Funktion, um die Map zu erstellen
|
|
def draw_map(self, surface: pygame.Surface, font: pygame.font.Font, cam_x: int = 0, cam_y: int = 0) -> None:
|
|
|
|
# Dict, dass jedem Buchstaben eine Farbe zuordnet
|
|
color_for = {
|
|
"W": color_wall,
|
|
"R": color_room,
|
|
"H": color_hall,
|
|
"D": color_door,
|
|
"S": color_start,
|
|
}
|
|
|
|
# äußere Schleife Zeile für Zeile
|
|
for row_nr in range(len(self.map)):
|
|
# innerer Loop für jedes Zeichen in der Zeile
|
|
for column_nr in range(len(self.map[row_nr])):
|
|
# holt sich den Buchstaben und speichert ihn in der Variable mark
|
|
mark = self.map[row_nr][column_nr]
|
|
# sucht die Farbe für den Buchstaben - falls unbekannt -> color_void
|
|
color = color_for.get(mark, color_void)
|
|
|
|
# errechnet die Position des Tiles auf dem Bildschirm mit "column_nr * tile_size", "- cam_x" verschiebt alles mit der Kamera
|
|
rect = pygame.Rect(
|
|
column_nr * tile_size - cam_x,
|
|
row_nr * tile_size - cam_y,
|
|
# Tile-Breite
|
|
tile_size,
|
|
# Tile-Höhe
|
|
tile_size,
|
|
)
|
|
|
|
# das Rechteck ind er Farbe zeichnen
|
|
pygame.draw.rect(surface, color, rect)
|
|
|
|
# die Wände sollen einen zusätzlichen Rand haben mit 1 = Wandbreite in Pixel
|
|
if mark == "W":
|
|
pygame.draw.rect(surface, color_border, rect, 1)
|
|
|
|
# geht die Beschriftungen durch
|
|
for i in range(len(self.room_decription)):
|
|
# entpackt das Tupel in 3 Variablen: column, row, text
|
|
column, row, text = self.room_decription[i]
|
|
|
|
# die Tile-Koordinaten in Pixel umrechnen und addieren von 2, damit der Text nicht ganz am Rand klebt
|
|
px = column * tile_size - cam_x + 2
|
|
py = row * tile_size - cam_y + 2
|
|
|
|
# Text-Bild mit fon.render()
|
|
# True gibt eine glattere Schrift
|
|
# blit() fixiert den Text auf dem Bildschirm
|
|
surface.blit(font.render(text, True, color_text), (px, py))
|
|
|
|
# Desks werden gezeichnet
|
|
for desk_list in self.desks.values():
|
|
for desk in desk_list:
|
|
desk.draw(surface, cam_x, cam_y)
|
|
|
|
|
|
|
|
# Gibt ein Raum Rechteck zurück - zum Prüfen, ob eine gegebene Position im Raum ist
|
|
def get_room_rect(self, column: int, row: int):
|
|
# rechnet Tile Koordinaten in Pixel um
|
|
pixel_x = column * tile_size
|
|
pixel_y = row * tile_size
|
|
|
|
for room_rect in self.rooms.values():
|
|
|
|
# collidepoint prüft ob der Pixel-Punkt im Rechteck ist
|
|
if room_rect.collidepoint(pixel_x, pixel_y):
|
|
return room_rect
|
|
|
|
# return None, wenn Punkt in keinem Raum liegt (z.B. im Gang)
|
|
return None
|
|
|
|
# Gibt alle Tische im Raum zurück, damit keine Item-Spawns auf Tischen stattfinden
|
|
def get_desks_for_room(self, room_rect: pygame.Rect) -> list[Desk]:
|
|
|
|
for room_name, rect in self.rooms.items():
|
|
if rect == room_rect:
|
|
return self.desks[room_name]
|
|
|
|
# kein passender Raum gefunden
|
|
return []
|
|
|
|
# Gibt das Raum-Rechteck zurück, in dem sich der Spieler gerade befindet
|
|
# Gilt um zu wissen, ob der Spieler im Raum ist wegen den Item spawns
|
|
def get_current_room(self, player_rect: pygame.Rect) -> pygame.Rect:
|
|
|
|
for room_rect in self.rooms.values():
|
|
if room_rect.colliderect(player_rect):
|
|
return room_rect
|
|
|
|
# Spieler ist im Gang
|
|
return None
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
pygame.init()
|
|
screen = pygame.display.set_mode((screen_w, screen_h))
|
|
font = pygame.font.SysFont("monospace", 26, bold=True)
|
|
clock = pygame.time.Clock()
|
|
|
|
my_map = Map()
|
|
|
|
while True:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
pygame.quit()
|
|
exit()
|
|
|
|
screen.fill(color_void)
|
|
my_map.draw_map(screen, font)
|
|
pygame.display.flip()
|
|
clock.tick(60)
|
|
|
|
|
|
|
|
|
|
|
|
|