import html as html_lib from ..rendering.personnage_data import resolve_personnage_idle_frame def render_scene_object(obj): """HTML d'un objet de scène — positionnement en PIXELS ABSOLUS (pas de % fluide, voir ensure_scene_schema.py), mirror volontairement plus simple que render_element_html.py (pas d'arbre de nesting, pas de palette de widgets à gérer) : juste kind="personnage" (réutilise resolve_personnage_idle_frame, même _personnage_data que le widget "personnage" de l'éditeur document) ou kind="decor" (image fixe, attributes.src). data-object-id/data-personnage jouent le même rôle que data-element-id/data-personnage côté DOM (voir static/js/screen_edit/personnage-preview.js, static/js/play/actions.js).""" style = ( f"position:absolute; left:{obj['x']}px; top:{obj['y']}px; " f"width:{obj['width']}px; height:{obj['height']}px; z-index:{obj['z_index']};" ) # data-element-id (en plus de data-object-id) : réutilise TELS QUELS # tous les sélecteurs [data-element-id=...] déjà écrits pour l'éditeur # document (collision, animation de sprites, "Modifier un élément") — # voir static/js/play/actions.js/conditions.js. Sans risque de # collision d'id : un jeu est ENTIÈREMENT "document" (_screen_elements) # OU "jeu_2d" (_scene_objects), jamais les deux à la fois. # data-anim-target (Timeline d'animation, Bug corrigé) : applyAnimationClip() # (static/js/play/screens.js) et son équivalent d'aperçu éditeur # (animation-timeline.js) sélectionnent TOUJOURS leur cible via # [data-anim-target=...] (jamais data-element-id/data-object-id, posé # sur .canvasElement/.playElement pour le DOM, voir visible_attrs.py) — # un objet de scène n'ayant pas de wrapper équivalent, cet attribut est # posé directement sur son : SANS lui, aucun clip de Timeline (ni # même une action de flow "Jouer une animation") ne trouvait jamais sa # cible pour un objet de scène, quel que soit son type d'animation. # class="sceneObjectSprite" (object-fit:contain, voir static/style.css) : # les frames CraftPix (screens/labels/animal_sprite_library.py) sont de # GRANDS canevas très paddés (~788×504 px, très différent des sprites # Kenney déjà bien recadrés, ~96×128 px) — sans object-fit, l'image # remplirait quand même son cadre (width/height:100%, voir la règle # `.canvasElementInner > img` dans scene_edit.html) mais DÉFORMÉE, # rendant le personnage minuscule/écrasé dans sa boîte de sélection. if obj["kind"] == "personnage": src = resolve_personnage_idle_frame(obj) src_attr = f' src="{html_lib.escape(src)}"' if src else "" return (f'') src = (obj.get("attributes") or {}).get("src", "") src_attr = f' src="{html_lib.escape(src)}"' if src else "" return (f'')