most things working, not text, draw_engine interface still fluid

This commit is contained in:
James Turk 2024-04-23 21:26:34 -05:00
parent 67c2d5093d
commit 37343739e8
5 changed files with 55 additions and 15 deletions

View File

@ -46,7 +46,7 @@ class Doodle(ABC):
world.add(self) world.add(self)
@abstractmethod @abstractmethod
def draw(self, screen) -> None: def draw(self) -> None:
""" """
All doodles need to be drawable, but there is no All doodles need to be drawable, but there is no
way we can provide an implementation without way we can provide an implementation without
@ -231,7 +231,7 @@ class Group(Doodle):
def __repr__(self): def __repr__(self):
return f"Group(pos={self.world_vec}, doodles={len(self._doodles)})" return f"Group(pos={self.world_vec}, doodles={len(self._doodles)})"
def draw(self, screen): def draw(self):
""" """
Groups, despite being an abstract concept, are drawable. Groups, despite being an abstract concept, are drawable.
To draw a group is to draw everything in it. To draw a group is to draw everything in it.

View File

@ -0,0 +1,17 @@
import abc
class DrawEngine(abc.ABC):
@abc.abstractmethod
def circle_draw(self, screen):
pass
@abc.abstractmethod
def rect_draw(self, screen):
pass
@abc.abstractmethod
def line_draw(self, screen):
pass

View File

@ -3,6 +3,7 @@ import random
import pygame import pygame
from typing import Callable from typing import Callable
from .doodles import Doodle from .doodles import Doodle
from .world import world
class Line(Doodle): class Line(Doodle):
@ -22,7 +23,7 @@ class Line(Doodle):
def __repr__(self): def __repr__(self):
return f"Line(pos={self.world_vec}, end={self.end_vec}, {self._color})" return f"Line(pos={self.world_vec}, end={self.end_vec}, {self._color})"
def draw(self, screen): def draw(self):
""" """
Implementation of the abstract draw function for the line. Implementation of the abstract draw function for the line.
@ -41,7 +42,7 @@ class Line(Doodle):
to the class and gaining flexibility from separating to the class and gaining flexibility from separating
presentation logic from data manipulation. presentation logic from data manipulation.
""" """
pygame.draw.aaline(screen, self._color, self.world_vec, self.end_vec) world.draw_engine.line_draw(self)
def to(self, x: float, y: float) -> "Doodle": def to(self, x: float, y: float) -> "Doodle":
""" """

View File

@ -1,6 +1,7 @@
import random import random
import pygame import pygame
from .doodles import Doodle from .doodles import Doodle
from .world import world
class Circle(Doodle): class Circle(Doodle):
@ -15,8 +16,9 @@ class Circle(Doodle):
def __repr__(self): def __repr__(self):
return f"Circle(pos={self.world_vec}, radius={self._radius}, {self._color}, parent={self._parent}))" return f"Circle(pos={self.world_vec}, radius={self._radius}, {self._color}, parent={self._parent}))"
def draw(self, screen): def draw(self):
pygame.draw.circle(screen, self.rgba, self.world_vec, self._radius) # TODO: do we need to override draw? can we move this to Doodle.draw
world.draw_engine.circle_draw(self)
def radius(self, r: float) -> "Doodle": def radius(self, r: float) -> "Doodle":
""" """
@ -25,6 +27,10 @@ class Circle(Doodle):
self._radius = r self._radius = r
return self return self
@property
def radius_val(self) -> float:
return self._radius
def grow(self, by: float): def grow(self, by: float):
""" """
Modify radius by an amount. (Negative to shrink.) Modify radius by an amount. (Negative to shrink.)
@ -50,14 +56,8 @@ class Rectangle(Doodle):
def __repr__(self): def __repr__(self):
return f"Rect(pos={self.world_vec}, width={self._width}, height={self._height}, parent={self._parent})" return f"Rect(pos={self.world_vec}, width={self._width}, height={self._height}, parent={self._parent})"
def draw(self, screen): def draw(self):
rect = pygame.Rect( world.draw_engine.rect_draw(self)
self.world_x - self._width / 2,
self.world_y - self._height / 2,
self._width,
self._height,
)
pygame.draw.rect(screen, self._color, rect)
def width(self, w: float) -> "Doodle": def width(self, w: float) -> "Doodle":
""" """

View File

@ -1,5 +1,26 @@
from .color import Color from .color import Color
import pygame import pygame
# TODO: fix this with a dynamic load
from .draw_engine import DrawEngine
class PygameDrawEngine(DrawEngine):
def circle_draw(self, c: "Circle"):
pygame.draw.circle(world.buffer, c.rgba, c.world_vec, c.radius_val)
def rect_draw(self, r: "Rectangle"):
# TODO: make accessors
rect = pygame.Rect(
r.world_x - r._width / 2,
r.world_y - r._height / 2,
r._width,
r._height,
)
pygame.draw.rect(world.buffer, r.rgba, rect)
def line_draw(self, ll: "Line"):
print("line_draw", ll)
pygame.draw.aaline(world.buffer, ll.rgba, ll.world_vec, ll.end_vec)
class World: class World:
@ -48,6 +69,7 @@ class World:
self._drawables = [] self._drawables = []
self.background_color = Color.WHITE self.background_color = Color.WHITE
self.screen = None self.screen = None
self.draw_engine = PygameDrawEngine()
def init(self): def init(self):
""" """
@ -85,7 +107,7 @@ class World:
# rendering # rendering
self.buffer.fill((*self.background_color, 255)) self.buffer.fill((*self.background_color, 255))
for d in sorted(self._drawables, key=lambda d: d._z_index): for d in sorted(self._drawables, key=lambda d: d._z_index):
d.draw(self.buffer) d.draw()
self.screen.blit(self.buffer, (0, 0)) self.screen.blit(self.buffer, (0, 0))
pygame.display.flip() pygame.display.flip()