Source code for simvx.core.nodes_2d.ysort
"""YSortContainer -- Sorts children by Y for top-down games."""
from __future__ import annotations
from .node2d import Node2D
[docs]
class YSortContainer(Node2D):
"""Sorts children by Y position each frame for top-down perspective.
Children are drawn in Y-ascending order (lower Y = drawn first = behind),
which creates a natural depth effect for top-down 2D games. The sort
only affects draw order; the children list itself is not mutated.
Uses dirty-flag optimization: O(n) comparison instead of O(n log n) sort
when no child Y values have changed.
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._last_y_values: list[float] = []
self._sorted_cache: list = []
def _draw_recursive(self, renderer):
"""Override draw traversal to sort children by Y before drawing."""
if not self.visible:
return
self.draw(renderer)
# Collect current Y values
children = list(self.children.safe_iter())
y_values = [c.position.y if isinstance(c, Node2D) and hasattr(c.position, 'y') else 0.0 for c in children]
# Only re-sort if Y values changed or child count changed
if y_values != self._last_y_values or len(children) != len(self._sorted_cache):
self._sorted_cache = sorted(
children,
key=lambda c: c.position.y if isinstance(c, Node2D) and hasattr(c.position, 'y') else 0,
)
self._last_y_values = y_values
for child in self._sorted_cache:
child._draw_recursive(renderer)