Sync schema.py from GitHub project
Browse files
schema.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from enum import Enum
|
| 4 |
+
from typing import Annotated
|
| 5 |
+
|
| 6 |
+
from pydantic import BaseModel, Field
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class Shape(str, Enum):
|
| 10 |
+
CIRCLE = "circle"
|
| 11 |
+
RECTANGLE = "rectangle"
|
| 12 |
+
TRIANGLE = "triangle"
|
| 13 |
+
STAR = "star"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class MovementPattern(str, Enum):
|
| 17 |
+
STATIC = "static"
|
| 18 |
+
KEYBOARD_HORIZONTAL = "keyboard_horizontal"
|
| 19 |
+
KEYBOARD_ALL = "keyboard_all"
|
| 20 |
+
RAIN_DOWN = "rain_down"
|
| 21 |
+
BOUNCE = "bounce"
|
| 22 |
+
CHASE_PLAYER = "chase_player"
|
| 23 |
+
ZIGZAG = "zigzag"
|
| 24 |
+
CIRCULAR = "circular"
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
class CollisionAction(str, Enum):
|
| 28 |
+
GAME_OVER = "game_over"
|
| 29 |
+
SCORE_PLUS = "score_plus"
|
| 30 |
+
SCORE_MINUS = "score_minus"
|
| 31 |
+
DESTROY_TARGET = "destroy_target"
|
| 32 |
+
BOUNCE_BACK = "bounce_back"
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class InputKey(str, Enum):
|
| 36 |
+
ARROW_LEFT = "arrow_left"
|
| 37 |
+
ARROW_RIGHT = "arrow_right"
|
| 38 |
+
ARROW_UP = "arrow_up"
|
| 39 |
+
ARROW_DOWN = "arrow_down"
|
| 40 |
+
SPACE = "space"
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
class InputAction(str, Enum):
|
| 44 |
+
MOVE_LEFT = "move_left"
|
| 45 |
+
MOVE_RIGHT = "move_right"
|
| 46 |
+
MOVE_UP = "move_up"
|
| 47 |
+
MOVE_DOWN = "move_down"
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class ScorePosition(str, Enum):
|
| 51 |
+
TOP_LEFT = "top_left"
|
| 52 |
+
TOP_RIGHT = "top_right"
|
| 53 |
+
TOP_CENTER = "top_center"
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class SpriteComponent(BaseModel):
|
| 57 |
+
id: str = Field(description="Unique sprite type identifier (e.g. 'player', 'enemy', 'coin')")
|
| 58 |
+
shape: Shape
|
| 59 |
+
color: str = Field(default="#ffffff", description="CSS hex color, e.g. '#00ffcc'")
|
| 60 |
+
x: float = Field(default=300, ge=-300, le=1100, description="Initial X position; can be negative for off-screen spawning")
|
| 61 |
+
y: float = Field(default=400, ge=-700, le=1350, description="Initial Y position; can be negative for off-screen spawning")
|
| 62 |
+
width: float = Field(default=30, ge=5, le=150)
|
| 63 |
+
height: float = Field(default=30, ge=5, le=150)
|
| 64 |
+
movement_pattern: MovementPattern = MovementPattern.STATIC
|
| 65 |
+
speed: float = Field(default=3.0, ge=0.5, le=15.0)
|
| 66 |
+
is_player: bool = Field(default=False, description="True for the player-controlled sprite")
|
| 67 |
+
count: int = Field(default=1, ge=1, le=20, description="Number of instances to spawn (for enemies/collectibles)")
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
class CollisionRule(BaseModel):
|
| 71 |
+
between: Annotated[list[str], Field(min_length=2, max_length=2, description="Exactly two sprite IDs")]
|
| 72 |
+
action: CollisionAction
|
| 73 |
+
value: int = Field(default=1, ge=1, description="Points added/removed for score actions")
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
class InputBinding(BaseModel):
|
| 77 |
+
key: InputKey
|
| 78 |
+
action: InputAction
|
| 79 |
+
target: str = Field(description="ID of the sprite to control")
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
class ScoreDisplay(BaseModel):
|
| 83 |
+
position: ScorePosition = ScorePosition.TOP_RIGHT
|
| 84 |
+
font_size: int = Field(default=22, ge=12, le=40)
|
| 85 |
+
color: str = Field(default="#00ffcc")
|
| 86 |
+
label: str = Field(default="SCORE")
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
class CanvasGame(BaseModel):
|
| 90 |
+
title: str = Field(description="Short evocative game title (2-4 words)")
|
| 91 |
+
width: int = Field(default=600, ge=300, le=800)
|
| 92 |
+
height: int = Field(default=500, ge=300, le=650)
|
| 93 |
+
background_color: str = Field(default="#0a0a0a")
|
| 94 |
+
sprites: list[SpriteComponent] = Field(default_factory=list)
|
| 95 |
+
collision_rules: list[CollisionRule] = Field(default_factory=list)
|
| 96 |
+
input_bindings: list[InputBinding] = Field(default_factory=list)
|
| 97 |
+
score_display: ScoreDisplay | None = Field(default=None)
|
| 98 |
+
lives: int = Field(default=3, ge=1, le=10)
|