From 6efae3e29e88d8119ff9851b98218a10a9a6c413 Mon Sep 17 00:00:00 2001 From: James Turk Date: Mon, 22 Apr 2024 02:35:23 -0500 Subject: [PATCH] support update functions --- src/doodles/doodles.py | 15 ++++++++++++--- src/doodles/examples/clock.py | 9 +++++++++ src/doodles/lines.py | 11 ++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/doodles/examples/clock.py diff --git a/src/doodles/doodles.py b/src/doodles/doodles.py index 6779c0e..e0ddf71 100644 --- a/src/doodles/doodles.py +++ b/src/doodles/doodles.py @@ -27,6 +27,7 @@ class Doodle(ABC): self._parent = parent self._color = parent._color if parent else Color.BLACK self._z_index = 0 + self._updates = [] # Is storing this vector in a tuple the right thing to do? # It might make more sense to store _x and _y, or use # a library's optimized 2D vector implementation. @@ -55,12 +56,20 @@ class Doodle(ABC): """ pass + def register_update(self, method, *args): + self._updates.append((method, args)) + def update(self) -> None: """ - An optional method, if implemented will be called every frame, - allowing for animation of properties. + Default implementation is to support + update function behavior. + + Can be overriden (see examples.balls) + to provide per-object update behavior. """ - pass + for method, args in self._updates: + evaled_args = [arg() for arg in args] + method(*evaled_args) def copy(self) -> "Doodle": """ diff --git a/src/doodles/examples/clock.py b/src/doodles/examples/clock.py new file mode 100644 index 0000000..03e6bb9 --- /dev/null +++ b/src/doodles/examples/clock.py @@ -0,0 +1,9 @@ +import time +from doodles import Circle, Color, Line, Group + +def create(): + g = Group().pos(400, 300) + Circle(g).radius(300).color(Color.BLACK).z_index(1) + Circle(g).radius(290).color(Color.BROWN).z_index(10) + Circle(g).radius(20).color(Color.BLACK).z_index(50) + Line(g).vec(lambda: time.time() % 60 / 60 * 360, 200).z_index(100) diff --git a/src/doodles/lines.py b/src/doodles/lines.py index d22d802..2865692 100644 --- a/src/doodles/lines.py +++ b/src/doodles/lines.py @@ -1,8 +1,10 @@ import math import random import pygame +from typing import Callable from .doodles import Doodle + class Line(Doodle): def __init__(self, parent=None): """ @@ -58,6 +60,14 @@ class Line(Doodle): """ Alternate constructor, to create offset vector from angle & length. """ + if isinstance(degrees, Callable): + self.register_update( + self.to, + lambda: magnitude * math.cos(math.radians(degrees())), + lambda: magnitude * math.sin(math.radians(degrees())), + ) + return self + return self.to( magnitude * math.cos(math.radians(degrees)), magnitude * math.sin(math.radians(degrees)), @@ -89,4 +99,3 @@ class Line(Doodle): self.x + self._offset_vec[0], self.y + self._offset_vec[1], ) -