Aperçu de la boîte de collision dans l'éditeur + blocage physique au jeu
Build and deploy / test-python (push) Successful in 6m15s
Build and deploy / test-js (push) Successful in 55s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Deux retours utilisateur sur la boîte de collision (ajoutée précédemment) :

- Visible et réglable directement dans l'éditeur de scène : pour l'objet
  sélectionné, un contour pointillé (rectangle/cercle) se superpose sur
  le canevas — glisser son corps ajuste le décalage, glisser sa poignée
  (coin bas-droit) ajuste la taille, les deux se répercutent dans le
  panneau "🧱 Collision" et inversement (édition des champs -> aperçu à
  jour). static/js/scenes/scene-editor.js::onCollisionBoxMouseDown/
  onCollisionBoxResizeMouseDown, mirror des poignées de position/taille
  déjà existantes pour l'objet lui-même.

- Bloque désormais RÉELLEMENT le déplacement au clavier : avant chaque
  pas, personnage-controller.js teste si la position candidate
  chevaucherait la boîte de collision d'un autre objet solide (jamais un
  "fond", jamais un objet à collision désactivée) et annule ce pas — par
  AXE séparément, pour permettre de glisser le long d'un mur en
  diagonale plutôt qu'un blocage total au moindre contact. Réutilise
  forgeShapesOverlap (conditions.js, factorisé depuis elementsOverlap
  pour ne jamais dupliquer la règle "qu'est-ce qui se touche").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-02 15:48:08 +02:00
co-authored by Claude Sonnet 5
parent bc3feb5080
commit a231bcf2fa
8 changed files with 365 additions and 27 deletions
+62
View File
@@ -0,0 +1,62 @@
"""Aperçu visuel de la boîte de collision dans l'éditeur de scène (voir
"🧱 Collision", templates/scene_edit.html) — demandé par l'utilisateur :
"quand je suis dans l'éditeur je veux voir la boîte de collision et régler
sa taille". Rendu SEULEMENT pour l'objet sélectionné (voir
static/js/scenes/scene-editor.js::onCollisionBoxMouseDown/
onCollisionBoxResizeMouseDown pour le glisser-déplacer/redimensionner)."""
import re
import screens
def _create_jeu2d_game(client, tmp_game_slug_cleanup, name="pytest_overlay"):
resp = client.post("/games/new", data={"name": name}, follow_redirects=False)
slug = tmp_game_slug_cleanup(resp.headers["Location"].rstrip("/").split("/")[-1])
screen_id = screens.create_screen(slug, "Scène 1", kind="jeu_2d")
return slug, screen_id
def _add_decor(client, slug, screen_id):
resp = client.post(f"/game/{slug}/screens/{screen_id}/scene-objects/add", data={"kind": "decor"}, follow_redirects=False)
assert resp.status_code == 302, resp.data
return int(re.search(r"selected=(\d+)", resp.headers["Location"]).group(1))
def test_selected_object_renders_the_collision_overlay_with_drag_handlers(client, tmp_game_slug_cleanup):
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
obj_id = _add_decor(client, slug, screen_id)
html = client.get(f"/game/{slug}/screens/{screen_id}/edit?selected={obj_id}").get_data(as_text=True)
assert 'id="collisionBoxOverlay"' in html
assert f"onCollisionBoxMouseDown(event, {obj_id})" in html
assert f"onCollisionBoxResizeMouseDown(event, {obj_id})" in html
def test_only_the_selected_object_gets_an_overlay(client, tmp_game_slug_cleanup):
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
obj_id = _add_decor(client, slug, screen_id)
_add_decor(client, slug, screen_id) # un second objet, jamais sélectionné ici
html = client.get(f"/game/{slug}/screens/{screen_id}/edit?selected={obj_id}").get_data(as_text=True)
assert html.count('id="collisionBoxOverlay"') == 1
def test_overlay_reflects_a_custom_collision_box_size_and_offset(client, tmp_game_slug_cleanup):
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
obj_id = _add_decor(client, slug, screen_id)
client.post(
f"/game/{slug}/scene-objects/{obj_id}/collision",
data='{"enabled": true, "shape": "cercle", "width": 40, "height": 40, "offset_x": 10, "offset_y": -10}',
content_type="application/json",
)
html = client.get(f"/game/{slug}/screens/{screen_id}/edit?selected={obj_id}").get_data(as_text=True)
assert "is-circle" in html
assert "width:40.0px; height:40.0px" in html
def test_disabled_collision_marks_the_overlay(client, tmp_game_slug_cleanup):
slug, screen_id = _create_jeu2d_game(client, tmp_game_slug_cleanup)
obj_id = _add_decor(client, slug, screen_id)
client.post(f"/game/{slug}/scene-objects/{obj_id}/collision", data='{"enabled": false}', content_type="application/json")
html = client.get(f"/game/{slug}/screens/{screen_id}/edit?selected={obj_id}").get_data(as_text=True)
assert "is-disabled" in html