add z indexing
This commit is contained in:
parent
fca6d11504
commit
802ba51875
@ -28,6 +28,7 @@ class Doodle(ABC):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
self._color = parent._color if parent else Color.BLACK
|
self._color = parent._color if parent else Color.BLACK
|
||||||
|
self._z_index = 0
|
||||||
# Is storing this vector in a tuple the right thing to do?
|
# Is storing this vector in a tuple the right thing to do?
|
||||||
# It might make more sense to store _x and _y, or use
|
# It might make more sense to store _x and _y, or use
|
||||||
# a library's optimized 2D vector implementation.
|
# a library's optimized 2D vector implementation.
|
||||||
@ -38,6 +39,7 @@ class Doodle(ABC):
|
|||||||
if parent:
|
if parent:
|
||||||
# register with parent for updates
|
# register with parent for updates
|
||||||
self._parent.add(self)
|
self._parent.add(self)
|
||||||
|
world.add(self)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def draw(self, screen) -> None:
|
def draw(self, screen) -> None:
|
||||||
@ -63,7 +65,9 @@ class Doodle(ABC):
|
|||||||
cases, it will be possible for child classes to override
|
cases, it will be possible for child classes to override
|
||||||
this to opt for a deepcopy or other logic.
|
this to opt for a deepcopy or other logic.
|
||||||
"""
|
"""
|
||||||
return copy.copy(self)
|
new = copy.copy(self)
|
||||||
|
world.add(new)
|
||||||
|
return new
|
||||||
|
|
||||||
def color(self, r: int, g: int, b: int) -> "Doodle":
|
def color(self, r: int, g: int, b: int) -> "Doodle":
|
||||||
"""
|
"""
|
||||||
@ -84,6 +88,13 @@ class Doodle(ABC):
|
|||||||
self._pos_vec = (x, y)
|
self._pos_vec = (x, y)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def z_index(self, z: float) -> "Doodle":
|
||||||
|
"""
|
||||||
|
Setter for z_index
|
||||||
|
"""
|
||||||
|
self._z_index = z
|
||||||
|
return self
|
||||||
|
|
||||||
def move(self, dx: float, dy: float) -> "Doodle":
|
def move(self, dx: float, dy: float) -> "Doodle":
|
||||||
"""
|
"""
|
||||||
This shifts the vector by a set amount.
|
This shifts the vector by a set amount.
|
||||||
@ -137,6 +148,10 @@ class Doodle(ABC):
|
|||||||
return self._parent.y + self._pos_vec[1]
|
return self._parent.y + self._pos_vec[1]
|
||||||
return self._pos_vec[1]
|
return self._pos_vec[1]
|
||||||
|
|
||||||
|
# @property
|
||||||
|
# def z_index(self) -> float:
|
||||||
|
# return self._z_index
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pos_vec(self) -> (float, float):
|
def pos_vec(self) -> (float, float):
|
||||||
"""
|
"""
|
||||||
@ -259,12 +274,10 @@ class Group(Doodle):
|
|||||||
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.
|
||||||
|
|
||||||
The draw logic is to just call the draw method of all children.
|
This is done by default, since all drawables will be
|
||||||
This works because we know that all doodles are guaranteed
|
registered with the scene upon creation.
|
||||||
to have such a method.
|
|
||||||
"""
|
"""
|
||||||
for d in self._doodles:
|
pass
|
||||||
d.draw(screen)
|
|
||||||
|
|
||||||
def copy(self) -> "Group":
|
def copy(self) -> "Group":
|
||||||
"""
|
"""
|
||||||
@ -272,7 +285,9 @@ class Group(Doodle):
|
|||||||
|
|
||||||
We are storing a list, so deep copies are necessary.
|
We are storing a list, so deep copies are necessary.
|
||||||
"""
|
"""
|
||||||
return copy.deepcopy(self)
|
new = copy.deepcopy(self)
|
||||||
|
world.add(new)
|
||||||
|
return new
|
||||||
|
|
||||||
def color(self, r: int, g: int, b: int) -> "Doodle":
|
def color(self, r: int, g: int, b: int) -> "Doodle":
|
||||||
"""
|
"""
|
||||||
@ -311,3 +326,37 @@ class Group(Doodle):
|
|||||||
# if we understand the implications of tightly
|
# if we understand the implications of tightly
|
||||||
# binding the implementations of these two classes.
|
# binding the implementations of these two classes.
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class Circle(Doodle):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
"""
|
||||||
|
This is a less interesting class than Line, but very similar.
|
||||||
|
"""
|
||||||
|
super().__init__(parent)
|
||||||
|
# circle is a position & radius
|
||||||
|
self._radius = 0
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Circle(pos={self.pos_vec}, radius={self._radius}, {self._color})"
|
||||||
|
|
||||||
|
def draw(self, screen):
|
||||||
|
pygame.draw.circle(screen, self._color, self.pos_vec, self._radius)
|
||||||
|
|
||||||
|
def radius(self, r: float) -> "Doodle":
|
||||||
|
"""
|
||||||
|
A setter for the circle's radius.
|
||||||
|
"""
|
||||||
|
self._radius = r
|
||||||
|
return self
|
||||||
|
|
||||||
|
def grow(self, by: float):
|
||||||
|
"""
|
||||||
|
Modify radius by an amount. (Negative to shrink.)
|
||||||
|
"""
|
||||||
|
return self.radius(self._radius + by)
|
||||||
|
|
||||||
|
def random(self) -> "Doodle":
|
||||||
|
super().random()
|
||||||
|
# constrain to 10-100
|
||||||
|
return self.radius(random.random*90 + 10)
|
||||||
|
10
src/doodles/examples/circles.py
Normal file
10
src/doodles/examples/circles.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from doodles.doodles import Group, Circle, Color
|
||||||
|
from doodles.world import world
|
||||||
|
|
||||||
|
c = Circle()
|
||||||
|
|
||||||
|
g = Group().pos(400, 300)
|
||||||
|
for r in range(20, 50, 5):
|
||||||
|
Circle(g).radius(r).color(*Color.random()).z_index(-r)
|
||||||
|
for r in range(60, 150, 10):
|
||||||
|
Circle(g).radius(r).color(*Color.random()).z_index(-r)
|
@ -1,4 +1,3 @@
|
|||||||
from .world import world
|
|
||||||
|
|
||||||
|
|
||||||
def make_grid(iterable, cols, rows, width, height, *, x_offset=0, y_offset=0):
|
def make_grid(iterable, cols, rows, width, height, *, x_offset=0, y_offset=0):
|
||||||
@ -10,7 +9,6 @@ def make_grid(iterable, cols, rows, width, height, *, x_offset=0, y_offset=0):
|
|||||||
for c in range(cols):
|
for c in range(cols):
|
||||||
for r in range(rows):
|
for r in range(rows):
|
||||||
doodle.pos(width * c + x_offset, height * r + y_offset)
|
doodle.pos(width * c + x_offset, height * r + y_offset)
|
||||||
world.add(doodle)
|
|
||||||
doodle = next(iterable)
|
doodle = next(iterable)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
pass
|
pass
|
||||||
|
@ -29,6 +29,7 @@ def main(modname: str):
|
|||||||
pygame.quit()
|
pygame.quit()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
world.render()
|
world.render()
|
||||||
|
# print(f"world contains {world._drawables}")
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class World:
|
|||||||
Draw world to screen
|
Draw world to screen
|
||||||
"""
|
"""
|
||||||
self.screen.fill(self.background_color)
|
self.screen.fill(self.background_color)
|
||||||
for d in self._drawables:
|
for d in sorted(self._drawables, key=lambda d: d._z_index):
|
||||||
d.draw(self.screen)
|
d.draw(self.screen)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user