Éditeur de collision (jeu 2D) : règles trigger -> action par objet
Build and deploy / test-python (push) Successful in 6m31s
Build and deploy / test-js (push) Successful in 50s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Nouvel onglet "🧩 Collision" dans l'éditeur de scène 2D : chaque objet
(hors joueur et fond) peut porter des règles "à la collision" ou "dans
un périmètre (px)" déclenchant une action (quête, attaque, événement,
ou interagir - qui affiche "Appuie sur [touche]" puis exécute une
sous-action à l'appui, un seul niveau d'imbrication). Backend
(sanitisation, route de persistance, exposition dans
full_game_payload) + assistant modal en cartes empilées côté client.

Ajoute le moteur d'exécution runtime (collision-rules-controller.js) :
détecte l'entrée en collision/périmètre avec le joueur à chaque tick,
déclenche l'action une seule fois par entrée, pur JS client sans appel
serveur (fonctionne à l'identique en ligne et en export SCORM).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-02 17:11:42 +02:00
co-authored by Claude Sonnet 5
parent dfaf85fac1
commit ee270d0286
15 changed files with 989 additions and 0 deletions
+26
View File
@@ -43,6 +43,29 @@ def render_scene_edit(slug, screen_id, game):
o["id"]: screens.resolve_personnage_animations(o) for o in objects if o["kind"] == "personnage"
}
# "🧩 Collision" (voir templates/scene_edit.html) : une carte par objet
# ÉLIGIBLE (jamais un "fond", jamais le personnage "joueur" — ce sont
# TOUJOURS les AUTRES objets qui réagissent à SA présence, voir
# screens/rendering/collision_rules.py) — construit ici plutôt que
# réutiliser `objects` tel quel, pour ne poser resolve_personnage_role
# qu'une fois par objet personnage (déjà lu ci-dessus pour l'objet
# SÉLECTIONNÉ, mais nécessaire ici pour TOUS les personnages).
collision_rule_objects = []
for o in objects:
if o["kind"] == "fond":
continue
role = screens.resolve_personnage_role(o) if o["kind"] == "personnage" else None
if role == "joueur":
continue
collision_rule_objects.append({
"id": o["id"],
"name": o.get("name") or _DEFAULT_OBJECT_LABELS.get(o["kind"], "Décor"),
"kind": o["kind"],
"role": role,
"thumbnail_html": o["rendered_html"],
"rules": screens.resolve_collision_rules(o),
})
flow_blocks = screens.list_flow_blocks(slug, screen_id)
flow_nodes = screens.list_flow_nodes(slug, screen_id)
flow_edges = screens.list_flow_edges(slug, screen_id)
@@ -102,4 +125,7 @@ def render_scene_edit(slug, screen_id, game):
definitions=db.list_definitions(slug),
definitions_json=json.dumps({str(d["id"]): screens.data_definition_options(slug, d["id"]) for d in db.list_definitions(slug)}),
definitions_names_json=json.dumps({d["id"]: d["name"] for d in db.list_definitions(slug)}),
collision_rule_objects_json=json.dumps(collision_rule_objects),
collision_action_types=screens.ACTION_TYPES, collision_trigger_types=screens.TRIGGER_TYPES,
collision_default_perimetre_px=screens.DEFAULT_PERIMETRE_PX,
)