import json from typing import Any # Boîte de collision d'un objet de scène (voir game_engine/scenes/ # set_scene_object_collision.py) : posée AUTOMATIQUEMENT sur chaque objet # (rectangle, taille = la boîte de l'objet lui-même, centrée dessus, sans # décalage — comportement inchangé pour une condition de collision # existante, voir elementsOverlap() dans static/game/js/play/conditions.js), # réglable ensuite dans le panneau de propriétés : activée/désactivée, # forme (rectangle/cercle) et taille/décalage propres, pour un sprite très # paddé (ex. les frames CraftPix) dont la silhouette réelle est bien plus # petite que son canevas. DEFAULT_COLLISION_SETTINGS: dict[str, Any] = { "enabled": True, "shape": "rectangle", "width": None, "height": None, "offset_x": 0, "offset_y": 0, } COLLISION_SHAPES = ["rectangle", "cercle"] def resolve_collision_settings(obj: dict[str, Any]) -> dict[str, Any]: """Décode attributes._collision en dict Python, jamais None — un attribut absent/corrompu retombe sur le défaut (boîte de collision = la boîte entière de l'objet, comme si ce réglage n'existait pas).""" raw = (obj.get("attributes") or {}).get("_collision") settings = dict(DEFAULT_COLLISION_SETTINGS) if raw: try: parsed = json.loads(raw) except (TypeError, ValueError): parsed = None if isinstance(parsed, dict): for key in DEFAULT_COLLISION_SETTINGS: if key in parsed: settings[key] = parsed[key] if settings["shape"] not in COLLISION_SHAPES: settings["shape"] = "rectangle" if not settings["width"]: settings["width"] = obj.get("width") if not settings["height"]: settings["height"] = obj.get("height") return settings