import json import os from typing import Any # Bibliothèque d'images de fond CraftPix — RÉSERVÉE au rôle admin (voir # core/sprite_gate.py, routes/game/scenes/scene_object_add.py), même règle que # la bibliothèque de sprites animaux (game_engine/labels/animal_sprite_library.py) : # licence CraftPix, interdiction de rendre ces images utilisables par un # compte "user". Générée une fois par # scripts/game/generate_background_manifest.py depuis assets/background// # (pack source, non versionné) vers static/game/backgrounds// # .png, avec un manifest JSON portant les dimensions RÉELLES # (largeur/hauteur) de chaque image — utilisées comme taille par défaut de # l'objet de scène "fond" posé (voir game_engine/scenes/add_scene_object.py), # modifiable ensuite comme n'importe quel objet (panneau "Position & taille"). _MANIFEST_PATH = os.path.join( os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "static", "game", "backgrounds", "manifest.json", ) def _load_manifest() -> dict[str, Any]: try: with open(_MANIFEST_PATH, encoding="utf-8") as f: return dict(json.load(f)) except FileNotFoundError: # Poste de dev sans les images de fond copiées (script pas encore # lancé), ou paquet exporté pour un jeu qui n'utilise aucun fond # CraftPix (voir publish/build_scorm_package.py, à étendre pour # copier sélectivement static/game/backgrounds/ le jour où un export # utilise ce widget) : aucun fond disponible, pas une erreur. return {} def _build_library() -> dict[str, dict[str, Any]]: manifest = _load_manifest() library: dict[str, dict[str, Any]] = {} for pack_slug, pack in manifest.items(): pack_label = pack["label"] for image_name, dims in pack["images"].items(): slug = f"{pack_slug}-{image_name}" library[slug] = { "label": f"{pack_label} — {image_name.replace('_', ' ')}", "url": f"/static/game/backgrounds/{pack_slug}/{image_name}.png", "width": dims["width"], "height": dims["height"], "pack": pack_slug, "pack_label": pack_label, } return library BACKGROUND_LIBRARY = _build_library()