Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/core/rendering/pygame_surface_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ def draw_line(
def draw_rect(
self, color: tuple[int, int, int], rect: pygame.Rect, width: int = 0
) -> None: ...
def draw_circle(
self,
color: tuple[int, int, int],
center: tuple[int, int],
radius: int,
width: int = 0,
) -> None: ...


class _RendererView(RenderEnqueue):
Expand Down Expand Up @@ -136,6 +143,15 @@ def draw_rect(
) -> None:
self._impl.draw_rect(color, rect, width)

def draw_circle(
self,
color: tuple[int, int, int],
center: tuple[int, int],
radius: int,
width: int = 0,
) -> None:
self._impl.draw_circle(color, center, radius, width)


class PygameSurfaceRenderer:
"""Command queue wrapper for pygame surface rendering.
Expand Down Expand Up @@ -280,6 +296,29 @@ def draw_rect(
)
)

def draw_circle(
self,
color: tuple[int, int, int],
center: tuple[int, int],
radius: int,
width: int = 0,
) -> None:
"""Queue a circle drawing operation.

Args:
color: RGB color tuple
center: Center position (x, y)
radius: Circle radius in pixels
width: Line width (0 for filled circle)
"""
self._command_queue.append(
DrawCommand(
operation=pygame.draw.circle,
args=(self._surface, color, center, radius, width),
kwargs={},
)
)

# Frame control methods (only for main/core, not exposed in view)

def begin_frame(
Expand Down
94 changes: 90 additions & 4 deletions src/ecs/systems/entity_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,96 @@ def draw_entity(
# Get color tuple
color = renderable.get_color_tuple()

# Render all shapes as rectangles for now
# (RenderEnqueue only has draw_rect and draw_line)
rect = pygame.Rect(pixel_x, pixel_y, cell_size, cell_size)
self._renderer.draw_rect(color, rect, 0)
# Render based on shape
if renderable.shape == "circle":
# For apples, draw realistic apple with stem and leaf
self._draw_realistic_apple(pixel_x, pixel_y, cell_size, color)
elif renderable.shape in ["square", "rectangle"]:
# Draw as rectangle (existing behavior)
rect = pygame.Rect(pixel_x, pixel_y, cell_size, cell_size)
self._renderer.draw_rect(color, rect, 0)
else:
# Default fallback to rectangle for unknown shapes
rect = pygame.Rect(pixel_x, pixel_y, cell_size, cell_size)
self._renderer.draw_rect(color, rect, 0)

def _draw_realistic_apple(
self, pixel_x: int, pixel_y: int, cell_size: int, color: tuple[int, int, int]
) -> None:
"""Draw a realistic apple with elliptical body, stem and leaf.

Args:
pixel_x: X position in pixels
pixel_y: Y position in pixels
cell_size: Size of the cell
color: RGB color of the apple
"""
# Apple body - slightly flattened ellipse
body_width = int(cell_size * 0.8)
body_height = int(cell_size * 0.7)
body_x = pixel_x + (cell_size - body_width) // 2
body_y = pixel_y + int(cell_size * 0.15)

# Draw apple body as ellipse using multiple circles for smooth appearance
center_x = body_x + body_width // 2

# Main body - draw filled ellipse approximation
radius_x = body_width // 2
radius_y = body_height // 2

# Draw ellipse as multiple horizontal lines
for y in range(body_height):
dy = y - radius_y
if radius_y != 0:
# Ellipse equation: (x/rx)² + (y/ry)² = 1
# Solve for x: x = rx * sqrt(1 - (y/ry)²)
normalized_y = dy / radius_y
if abs(normalized_y) <= 1:
half_width = int(
radius_x * (1 - normalized_y * normalized_y) ** 0.5
)
line_y = body_y + y
line_start = center_x - half_width
line_end = center_x + half_width
if half_width > 0:
self._renderer.draw_line(
color, (line_start, line_y), (line_end, line_y), 1
)

# Apple stem (caule) - small brown rectangle
stem_color = (101, 67, 33) # Brown color
stem_width = max(2, cell_size // 10)
stem_height = max(3, cell_size // 6)
stem_x = center_x - stem_width // 2
stem_y = pixel_y + 2
stem_rect = pygame.Rect(stem_x, stem_y, stem_width, stem_height)
self._renderer.draw_rect(stem_color, stem_rect, 0)

# Apple leaf (folha) - small green triangle-like shape
leaf_color = (34, 139, 34) # Forest green
leaf_size = max(3, cell_size // 8)

# Draw leaf as small lines forming a leaf shape
leaf_x = stem_x + stem_width + 1
leaf_y = stem_y + 1

# Leaf outline - draw a small oval-like shape
for i in range(leaf_size):
y_offset = i
if i < leaf_size // 2:
# Upper half - expanding
width = (i * 2) // 3 + 1
else:
# Lower half - contracting
width = ((leaf_size - i) * 2) // 3 + 1

for w in range(width):
point_x = leaf_x + w
point_y = leaf_y + y_offset
# Draw individual pixels for leaf
self._renderer.draw_line(
leaf_color, (point_x, point_y), (point_x, point_y), 1
)

def update(self, world: World) -> None:
"""Update method required by BaseSystem.
Expand Down
182 changes: 0 additions & 182 deletions src/game/scenes/menu.py

This file was deleted.