commit c48222991bcd1f4d0d8ee210f06d22138f33b44a Author: Megamichi Date: Wed Feb 28 17:44:06 2024 +0100 init diff --git a/button.py b/button.py new file mode 100644 index 0000000..cb368cd --- /dev/null +++ b/button.py @@ -0,0 +1,39 @@ +import pygame + +class Button(): + def __init__(self, screen, color, pos, width, height, text) -> None: + self.pos = pos + self.größe = width,height + self.color = color + self.screen = screen + self.text = text + def draw(self): + pygame.draw.rect(self.screen, + self.color, + (self.pos[0]-self.größe[0]//2, + self.pos[1]-self.größe[1]//2, + self.größe[0], + self.größe[1]) + ) + pygame.draw.rect(self.screen, + (0,150,0), + (self.pos[0]-self.größe[0]//2, + self.pos[1]-self.größe[1]//2, + self.größe[0], + self.größe[1]), + 2 + ) + + font = pygame.font.Font(None, 30) + text_surface = font.render(self.text, True, (0,0,0)) + text_rect = text_surface.get_rect() + text_rect.center = (self.pos[0], + self.pos[1]) + self.screen.blit(text_surface, text_rect) + def check_hovered(self, mouse): + if (self.pos[0] - self.größe[0]//2 <= mouse[0] <= self.pos[0] + self.größe[0]//2 and + self.pos[1] - self.größe[1]//2 <= mouse[1] <= self.pos[1] + self.größe[1]//2): + return True + else: + return False + diff --git a/main.py b/main.py new file mode 100644 index 0000000..06dd1b3 --- /dev/null +++ b/main.py @@ -0,0 +1,225 @@ +#!/usr/bin/python3 +import pygame +from button import * +import copy +import random + +pygame.init() + + +## funktionen +def get_debug_text(): + def text(text, line_counter): + debug_text = default_font.render(str(text), True, (255, 255, 255)) + screen.blit(debug_text, (0, line_counter * default_font.get_height())) + + line_counter = 1 + globalvars = globals() + for a in globalvars: + text(f"{str(a)} = {str(globalvars[a])}", line_counter) + line_counter += 1 + + +def centered_text(text=str, pos=tuple, color=tuple): + text = default_font.render(str(text), True, color, (255, 255, 255)) + screen.blit(text, (pos[0] - text.get_width() / 2, pos[1])) + + +def draw_feld(feld, block_size): + for a in range(len(feld[0])): + for b in range(len(feld)): + if feld[b][a]: + pygame.draw.rect( + screen, + (255,255,255), + (a * block_size, b * block_size, block_size, block_size), + ) + + +def finde_nachbarn(x, y): + feldx, feldy = len(feld[0]), len(feld) + ov = (y - 1) % feldy , x % feldx + ovr = (y - 1) % feldy , (x + 1) % feldx + ovl = (y - 1) % feldy , (x - 1) % feldx + + r = y , (x + 1) % feldx + l = y , (x - 1) % feldx + + be = (y + 1) % feldy , x % feldx + ber = (y + 1) % feldy , (x + 1) % feldx + bel = (y + 1) % feldy , (x - 1) % feldx + return [ovl,ov, ovr, r, l, bel, be, ber] + +def verarbeite_feld(feld): + feldx, feldy = len(feld[0]), len(feld) # bekomme feld größe + feld2 = copy.deepcopy(feld) # mache neue kopie + for y in range(feldy): # spalte + for x in range(feldx): # zeile + lives = 0 + for pos in finde_nachbarn(x ,y): + if feld[pos[0]][pos[1]]: + lives += 1 + if feld[y][x]: + if lives <= 1:new = False + elif lives >= 4:new = False + else: new = True + else: + if lives == 3:new = True + else: new = False + feld2[y][x] = new + return feld2 # gib kopie zurück + +## Funktion zum Verarbeiten des Feldes + +def make_feld(size,rand): + x = screensize[0] // size + y = screensize[1] // size + if rand: + feld = [[random.choice([False, True]) for _ in range(x)] for _ in range(y)] + else: feld = [[False for _ in range(x)] for _ in range(y)] + return feld, x, y + +def resize_feld(feld, new_size, fill_with=False): + sx = screensize[0] // new_size + sy = screensize[1] // new_size + old_feld_size = len(feld[0]),len(feld) + new_feld = [[" " for _ in range(sx)] for _ in range(sy)] + + for y in range(len(new_feld)): + for x in range(len(new_feld[0])): + if x < old_feld_size[0] and y < old_feld_size[1]: + new_feld[y][x] = feld[y][x] + else: + new_feld[y][x] = fill_with + return new_feld ,sx,sy + +def setbutton_pos(): + global buttons + for i, button in enumerate(buttons): + i += 1 + button.pos = (screensize[0] - 70, button_abstandy * i) +## klassen + + +## variablen +screen = pygame.display.set_mode((800, 500), pygame.RESIZABLE) +pygame.display.set_caption("GoL") +screensize = pygame.display.get_window_size() +clock = pygame.time.Clock() +default_font = pygame.font.SysFont("sans", 14) + +feld, feldx, feldy = make_feld(20,True) + +pause = False +pixelsize = 20 # größe eines pixels +button_abstandy = 30 # abstand von buttons + +buttons = [ + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 25, 25, "\/"), + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Debug"), + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Reset"), + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Zoom"), + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Pause"), + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Randomize"), + Button(screen, (200, 200, 200), (screensize[0] - 70, 50), 100, 25, "Clear"), +] +buttona = {"dropdown": 0, "debug": 1, "reset": 2, "zoom": 3, "pause": 4, "random": 5, "clear": 6} +setbutton_pos() +buttonhovered = [False, False, False, False, False, False, False] +buttons_to_render = 6 # button begrenzung +dropdown = True +before_buttonhovered = [False,False,False] +key_counter = 0 +pressed_keys = pygame.key.get_pressed() +show_debug = False +running = True +if __name__ == "__main__": + while running: + ## key managment + key_counter += 1 + if key_counter == 5: + key_counter = 0 + pressed_keys = pygame.key.get_pressed() + if True in pressed_keys: + if pressed_keys[pygame.K_ESCAPE]: + exit() + if pressed_keys[pygame.K_PLUS] and not before_pressed_keys[pygame.K_PLUS]: + pixelsize += 2 + feld, feldx, feldy = resize_feld(feld,pixelsize) + if pressed_keys[pygame.K_MINUS] and not before_pressed_keys[pygame.K_MINUS]: + pixelsize -= 2 + feld, feldx, feldy = resize_feld(feld,pixelsize) + if pressed_keys[pygame.K_d] and not before_pressed_keys[pygame.K_d]: + show_debug = not show_debug + if pressed_keys[pygame.K_SPACE] and not before_pressed_keys[pygame.K_SPACE]: + pause = not pause + if pressed_keys[pygame.K_r] and not before_pressed_keys[pygame.K_r]: + feld, feldx, feldy = make_feld(pixelsize,False) + + ## event managment + for event in pygame.event.get(): + if event.type == pygame.QUIT: + exit() + if event.type == pygame.WINDOWRESIZED: + screensize = pygame.display.get_window_size() + feld, feldx, feldy = resize_feld(feld,pixelsize) + setbutton_pos() + draw_feld(feld, pixelsize) # male feld mit color_key + + mx, my = pygame.mouse.get_pos() + mousepressed = pygame.mouse.get_pressed() + + for button in buttons[:buttons_to_render]: # male jeden button + button.draw() + + if True in mousepressed: + for i, button in enumerate(buttons[:buttons_to_render]): + # checke alle button ob die maus auf einen ist und schreibe es in die liste buttonhovered + if button.check_hovered((mx, my)): + buttonhovered[i] = True + else: + buttonhovered[i] = False + if not True in buttonhovered : # wenn nicht maus über button + if mousepressed[0] == True: + feld[my // pixelsize][mx // pixelsize] = True + else: + feld[my // pixelsize][mx // pixelsize] = False + + if mousepressed[0] and not before_mousepressed[0]: # einmalklick von maus erfassen + if buttonhovered[buttona["dropdown"]]: # falls button "dropdown" mit index von buttona = True + dropdown = not dropdown + if dropdown: + buttons_to_render = len(buttons) # dropdown menü begrenzen indem man nicht alle buttons verarbeitet + buttons[buttona["dropdown"]].text = "\/" + else: + buttons_to_render = 1 + buttons[buttona["dropdown"]].text = "/\\" + if buttonhovered[buttona["debug"]]: + show_debug = not show_debug + if buttonhovered[buttona["reset"]]: + feld, feldx, feldy = make_feld(pixelsize,False) + if buttonhovered[buttona["zoom"]]: + pixelsize += 2 + feld, feldx, feldy = resize_feld(feld,pixelsize,False)#make_feld(pixelsize,False) + if buttonhovered[buttona["clear"]]: + feld, feldx, feldy = make_feld(pixelsize,False) + if buttonhovered[buttona["random"]]: + feld, feldx, feldy = make_feld(pixelsize,True) + if buttonhovered[buttona["pause"]]: + pause = not pause + if mousepressed[2] and not before_mousepressed[2]: + if buttonhovered[buttona["zoom"]]: + pixelsize -= 2 + feld, feldx, feldy = resize_feld(feld,pixelsize,False)#make_feld(pixelsize,False) + + before_buttonhovered = buttonhovered # bevorige maus und button hover daten erfassen + before_mousepressed = mousepressed + before_pressed_keys = pressed_keys + if not pause: + feld = verarbeite_feld(feld) # feld neu machen + if show_debug: # debug text zeichnen + get_debug_text() + ## bildschirm aktuallisierung + pygame.display.flip() + clock.tick(60) + screen.fill((0, 0, 0))