Files
matrixmania/Funktional/Undo_Doodle.py
T

89 lines
3.0 KiB
Python

import pygame
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Undo Doodle")
self.clock = pygame.time.Clock()
# Der Zustand ist eine Liste von Strichen.
# Jeder Strich ist eine Liste von Punkten (tuples).
initial_state = []
# Die Historie speichert die aufeinanderfolgenden, immutablen Zustände
self.history = [initial_state]
self.drawing = False
self.current_stroke = []
@property
def current_state(self):
"""Liefert den aktuellen Zustand (oberstes Element der Historie)."""
return self.history[-1]
def run(self):
running = True
while running:
running = self.handle_events()
self.update()
self.draw()
self.clock.tick(60)
pygame.quit()
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
elif event.type == pygame.KEYDOWN:
# Mit 'u' oder Strg+Z einen Schritt zurückgehen (Undo)
if event.key == pygame.K_u or (event.key == pygame.K_z and (pygame.key.get_mods() & pygame.KMOD_CTRL)):
if len(self.history) > 1:
self.history.pop()
print("Undo ausgeführt!")
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Linke Maustaste gedrückt
self.drawing = True
self.current_stroke = [event.pos]
elif event.type == pygame.MOUSEMOTION:
if self.drawing:
self.current_stroke.append(event.pos)
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1 and self.drawing:
self.drawing = False
if self.current_stroke:
# IMMUTABLE ANSATZ:
# Erstelle einen völlig neuen Zustand (neue Liste),
# anstatt den alten Zustand direkt zu verändern.
new_strokes = self.current_state + [self.current_stroke]
self.history.append(new_strokes)
self.current_stroke = []
return True
def update(self):
pass
def draw(self):
self.screen.fill((255, 255, 255)) # Hintergrund weiß füllen
# 1. Zeichne alle fertigen Striche aus dem aktuellen Zustand
for stroke in self.current_state:
if len(stroke) > 1:
pygame.draw.lines(self.screen, (0, 0, 0), False, stroke, 3)
# 2. Zeichne den aktuellen Strich während des Ziehens in einer Vorschau-Farbe
if self.drawing and len(self.current_stroke) > 1:
pygame.draw.lines(self.screen, (120, 120, 120), False, self.current_stroke, 3)
pygame.display.flip()
if __name__ == "__main__":
game = Game()
game.run()