Enrichit les declencheurs/actions de scene (clic/survol/affichage, surbrillance/video/son/visibilite/indication/attendre) et fiabilise la pose d'un fond/decor importe
- Ajoute clic/survol/affichage-ecran comme declencheurs, et surbrillance, video, son, visibilite, indication, attendre comme actions, utilisables aussi bien par l'editeur manuel (menu lateral Objets/Ecran) que par Ruby (IA), avec blocs deplacables/supprimables dans une chaine. - Corrige plusieurs variantes du bug "impossible de poser un objet hors du champ de la camera" (troncature du chainage d'actions a 4 maillons, fond importe pose a 128x128 au lieu de sa taille reelle, decalage du fond au vrai glisser-depose, redimensionnement manuel jamais propage au monde). - Ajoute un vrai glisser-depose depuis la galerie vers la scene, la gestion complete de "Mes assets" (sous-sections Fonds/Decors/Sons/ Videos, suppression, reclassement fond<->decor sans re-upload). - Ajoute l'upload de son (limite 3 min) et de video (MP4 uniquement, limite 5 min), avec validation de la duree reelle du fichier, et une replique audio optionnelle dans une bulle de dialogue. - Fixe la taille de pose d'un objet/decor importe a 200x200 avec une boite de collision de 150x150. - Filtre le selecteur de fichier des actions son/video par type reel. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b07b231a61
commit
559331f9cf
@@ -13,9 +13,18 @@ _KINDS = {"personnage", "decor", "fond", "dialogue_box", "quiz_box", "score_widg
|
||||
_DIALOGUE_BOX_DEFAULT_SIZE = (320, 150)
|
||||
_QUIZ_BOX_DEFAULT_SIZE = (340, 240)
|
||||
_SCORE_WIDGET_DEFAULT_SIZE = (140, 50)
|
||||
# "decor" (demande explicite) : taille fixe à la pose, JAMAIS la taille
|
||||
# réelle de l'image importée (contrairement à "fond", voir plus bas) —
|
||||
# une photo/illustration "Mes assets" est souvent bien plus grande qu'un
|
||||
# petit objet de décor, 200×200 reste un point de départ raisonnable à
|
||||
# ajuster ensuite à la poignée. La boîte de collision, elle, est posée
|
||||
# plus PETITE que l'objet (150×150, centrée — voir collision_settings.py)
|
||||
# pour rester proche de la silhouette réelle plutôt que du cadre entier.
|
||||
_DECOR_DEFAULT_SIZE = (200, 200)
|
||||
_DECOR_COLLISION_SIZE = (150, 150)
|
||||
|
||||
|
||||
def add_scene_object(slug, scene_id, kind="personnage", forge_character=None, background_slug=None, image_url=None):
|
||||
def add_scene_object(slug, scene_id, kind="personnage", forge_character=None, background_slug=None, image_url=None, image_width=None, image_height=None, x=None, y=None):
|
||||
"""Pose un nouvel objet sur une scène (voir ensure_scene_schema.py).
|
||||
kind="personnage" : attributes._personnage_data, MÊME structure/mêmes
|
||||
fonctions resolve_personnage_* que le widget "personnage" de l'éditeur
|
||||
@@ -33,9 +42,20 @@ def add_scene_object(slug, scene_id, kind="personnage", forge_character=None, ba
|
||||
image_url (kind "fond"/"decor" uniquement) : une image ARBITRAIRE
|
||||
(voir "Mes assets", auth/user_assets/) plutôt qu'une clé de
|
||||
BACKGROUND_LIBRARY — prioritaire sur background_slug si les deux sont
|
||||
fournis. Pas de largeur/hauteur connues d'avance ici (contrairement à
|
||||
BACKGROUND_LIBRARY qui les documente) : retombe sur les colonnes par
|
||||
défaut de _scene_objects, exactement comme un "decor" ordinaire."""
|
||||
fournis. image_width/image_height (kind "fond" uniquement, voir
|
||||
routes/scenes/scene_object_add.py::auth.image_dimensions) : taille
|
||||
RÉELLE de l'image quand connue, pour que le "monde" puisse s'agrandir
|
||||
à sa vraie taille. Un "decor" les ignore volontairement (demande
|
||||
explicite) : toujours posé à _DECOR_DEFAULT_SIZE (200×200), quelle que
|
||||
soit la taille réelle de l'image importée.
|
||||
|
||||
x/y (optionnels) : position EXACTE demandée par le créateur (voir
|
||||
"vrai glisser-déposer" depuis la galerie, static/js/scenes/
|
||||
scene-editor.js::onGalleryDragStart/onCanvasDrop) — remplace le
|
||||
défaut habituel (100,100 posé par le schéma, voir
|
||||
ensure_scene_schema.py) pour TOUT type d'objet, y compris "fond"
|
||||
(qui, SANS position explicite, continue de démarrer au coin
|
||||
haut-gauche du monde comme avant)."""
|
||||
ensure_scene_schema(slug)
|
||||
kind = kind if kind in _KINDS else "personnage"
|
||||
attributes = {}
|
||||
@@ -59,8 +79,16 @@ def add_scene_object(slug, scene_id, kind="personnage", forge_character=None, ba
|
||||
# et disparaîtrait à tort de "🧩 Collision" (voir scene_edit_view.py,
|
||||
# qui exclut toujours le joueur).
|
||||
attributes["_personnage_role"] = "pnj"
|
||||
elif kind in ("fond", "decor") and image_url:
|
||||
elif kind == "fond" and image_url:
|
||||
attributes["src"] = image_url
|
||||
if image_width is not None and image_height is not None:
|
||||
width, height = image_width, image_height
|
||||
elif kind == "decor" and image_url:
|
||||
attributes["src"] = image_url
|
||||
width, height = _DECOR_DEFAULT_SIZE
|
||||
attributes["_collision"] = json.dumps({
|
||||
"width": _DECOR_COLLISION_SIZE[0], "height": _DECOR_COLLISION_SIZE[1],
|
||||
})
|
||||
elif kind == "fond" and background_slug:
|
||||
from ..labels.background_library import BACKGROUND_LIBRARY
|
||||
background = BACKGROUND_LIBRARY.get(background_slug)
|
||||
@@ -83,11 +111,17 @@ def add_scene_object(slug, scene_id, kind="personnage", forge_character=None, ba
|
||||
cols = ["scene_id", "kind", "attributes", "z_index"]
|
||||
values = [scene_id, kind, json.dumps(attributes), z_index]
|
||||
if width is not None:
|
||||
# x=0/y=0 (jamais le défaut 100/100, voir ensure_scene_schema.py) :
|
||||
# un fond commence au coin haut-gauche de la scène/du monde, pas
|
||||
# décalé arbitrairement comme un objet ordinaire.
|
||||
cols += ["width", "height", "x", "y"]
|
||||
values += [width, height, 0, 0]
|
||||
cols += ["width", "height"]
|
||||
values += [width, height]
|
||||
if x is None and y is None and kind == "fond":
|
||||
# Comportement inchangé pour un fond posé SANS position explicite
|
||||
# (galerie Forge/Mes assets par simple clic) : jamais le défaut
|
||||
# 100/100 (voir ensure_scene_schema.py), toujours le coin
|
||||
# haut-gauche de la scène/du monde.
|
||||
x, y = 0, 0
|
||||
if x is not None and y is not None:
|
||||
cols += ["x", "y"]
|
||||
values += [x, y]
|
||||
placeholders = ", ".join(["?"] * len(values))
|
||||
conn.execute(f"INSERT INTO _scene_objects ({', '.join(cols)}) VALUES ({placeholders})", values)
|
||||
object_id = conn.execute("SELECT last_insert_rowid() AS id").fetchone()["id"]
|
||||
|
||||
Reference in New Issue
Block a user