149 lines
3.3 KiB
Python
149 lines
3.3 KiB
Python
from abc import ABC, abstractmethod
|
|
import sys
|
|
import copy
|
|
import random
|
|
import math
|
|
import pygame
|
|
|
|
WHITE = (255, 255, 255)
|
|
BLACK = (0, 0, 0)
|
|
WIDTH = 800
|
|
HEIGHT = 600
|
|
|
|
|
|
class Doodle(ABC):
|
|
def __init__(self):
|
|
self._pos_vec = (0, 0)
|
|
self._color = BLACK
|
|
|
|
@abstractmethod
|
|
def draw(self, screen) -> None:
|
|
pass
|
|
|
|
def copy(self):
|
|
return copy.copy(self)
|
|
|
|
def color(self, r, g, b):
|
|
self._color = (r, g, b)
|
|
return self
|
|
|
|
def pos(self, x, y):
|
|
self._pos_vec = (x, y)
|
|
return self
|
|
|
|
def move(self, dx, dy):
|
|
return self.pos(self.x + dx, self.y + dy)
|
|
|
|
def random(self):
|
|
x = random.random() * WIDTH
|
|
y = random.random() * HEIGHT
|
|
r = random.random() * 255
|
|
g = random.random() * 255
|
|
b = random.random() * 255
|
|
return self.pos(x, y).color(r, g, b)
|
|
|
|
@property
|
|
def pos_vec(self):
|
|
return self._pos_vec
|
|
|
|
@property
|
|
def x(self):
|
|
return self._pos_vec[0]
|
|
|
|
@property
|
|
def y(self):
|
|
return self._pos_vec[1]
|
|
|
|
|
|
class Line(Doodle):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._offset_vec = (10, 0)
|
|
|
|
def __repr__(self):
|
|
return f"Line(pos={self.pos_vec}, end={self.end_vec}, {self._color})"
|
|
|
|
def draw(self, screen):
|
|
pygame.draw.line(screen, self._color, self.pos_vec, self.end_vec)
|
|
|
|
def to(self, x, y):
|
|
self._offset_vec = (x, y)
|
|
return self
|
|
|
|
def random(self):
|
|
super().random()
|
|
magnitude = random.random() * 100
|
|
degrees = random.random() * 360
|
|
return self.vec(degrees, magnitude)
|
|
|
|
def vec(self, degrees, magnitude):
|
|
return self.to(magnitude * math.cos(math.radians(degrees)),
|
|
magnitude * math.sin(math.radians(degrees)))
|
|
|
|
@property
|
|
def end_vec(self):
|
|
return (self.pos_vec[0] + self._offset_vec[0],
|
|
self.pos_vec[1] + self._offset_vec[1],
|
|
)
|
|
|
|
class Group(Doodle):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._doodles = []
|
|
|
|
def draw(self, screen):
|
|
for d in self._doodles:
|
|
d.draw(screen)
|
|
|
|
def color(self, r, g, b):
|
|
for d in self._doodles:
|
|
d.color(r, g, b)
|
|
|
|
def copy(self):
|
|
return copy.deepcopy(self)
|
|
|
|
def add(self, doodle):
|
|
self._doodles.append(doodle)
|
|
return self
|
|
|
|
def move(self, dx, dy):
|
|
for d in self._doodles:
|
|
d.move(dx, dy)
|
|
return self
|
|
|
|
def render_scene(screen, background, *drawables):
|
|
screen.fill(background)
|
|
for d in drawables:
|
|
d.draw(screen)
|
|
|
|
def main():
|
|
pygame.init()
|
|
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
|
pygame.display.set_caption("Doodles")
|
|
|
|
g = Group()
|
|
for d in range(100, 200, 10):
|
|
g.add(
|
|
Line().pos(300, 300).vec(d, 100)
|
|
)
|
|
|
|
g2 = g.copy()
|
|
g2.move(20, 20)
|
|
g3 = g.copy()
|
|
g3.move(100, 100).color(0, 100, 100)
|
|
g3.add(Line().random().pos(g3.x, g3.y))
|
|
g3.add(Line().random().pos(g3.x, g3.y))
|
|
|
|
while True:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
pygame.quit()
|
|
sys.exit()
|
|
|
|
render_scene(screen, WHITE, g, g2, g3)
|
|
|
|
pygame.display.flip()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|