From 1d0999a78eda34b6e93880048921404da1adcc47 Mon Sep 17 00:00:00 2001 From: Samuel Bouchet Date: Fri, 17 Apr 2026 22:30:15 +0200 Subject: [PATCH] Add cinematic on mission transition (cell pop-in, camera pan, title overlay) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OnMissionAdvanced now plays a three-track cinematic when the auto-advance fires between missions: - Every cell in the rebuilt board pops in with a scale+fade tween (0.45s, back ease) so terrain expansion reads as "appearing". - The camera smooth-pans + zooms back to the new board center over 0.7s, undoing any collision zoom that was active. - A full-size "Mission N\nName" overlay fades in, holds for ~1.4s, then fades out and frees itself. The per-cell animation doubles as the expansion cue; a dedicated new-cells-only tween can be layered later if needed. No new engine surface — hooks onto the existing MissionStartedEvent path. --- Scripts/Main.cs | 67 +++++++++++++++++++++++++++++++++++++++++++++++-- docs/PLAN.md | 4 --- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/Scripts/Main.cs b/Scripts/Main.cs index 3a2abbb..a567367 100644 --- a/Scripts/Main.cs +++ b/Scripts/Main.cs @@ -985,7 +985,7 @@ public partial class Main : Node2D private void OnMissionAdvanced() { - // Auto-advance happened during simulation — rebuild board seamlessly + // Auto-advance happened during simulation — rebuild board + cinematic if (_sim == null || _campaignDef == null) return; var snap = _sim.GetSnapshot(); @@ -994,10 +994,73 @@ public partial class Main : Node2D BuildBoardFromSnapshot(snap); SetupUIForMission(snap, mission); - CenterCameraOnBoard(snap.Width, snap.Height); + PlayMissionTransitionCinematic(mission, snap); _inputMapper.SetSnapshot(snap); } + private void PlayMissionTransitionCinematic(MissionDef mission, BoardSnapshot snap) + { + // 1. Board cells "pop in": start small and invisible, scale up + foreach (var cell in _boardView.GetChildren()) + { + if (cell is CellView cv) + { + cv.Modulate = new Color(1, 1, 1, 0); + cv.Scale = new Vector2(0.6f, 0.6f); + var t = cv.CreateTween(); + t.SetParallel(true); + t.TweenProperty(cv, "modulate:a", 1f, 0.45f); + t.TweenProperty(cv, "scale", Vector2.One, 0.45f) + .SetEase(Tween.EaseType.Out).SetTrans(Tween.TransitionType.Back); + } + } + + // 2. Smooth camera pan + zoom to new board center + var targetPos = new Vector2( + snap.Width * BoardView.CellSize / 2f, + -snap.Height * BoardView.CellSize / 2f + BoardView.CellSize); + var camTween = CreateTween(); + camTween.SetParallel(true); + camTween.TweenProperty(_camera, "position", targetPos, 0.7f) + .SetEase(Tween.EaseType.Out).SetTrans(Tween.TransitionType.Sine); + camTween.TweenProperty(_camera, "offset", + new Vector2(SidePanelWidth / 2f, (ControlBarHeight - TitleBarHeight) / 2f), 0.7f); + // Reset zoom in case we were zoomed in from a collision event + camTween.TweenProperty(_camera, "zoom", Vector2.One, 0.7f) + .SetEase(Tween.EaseType.Out).SetTrans(Tween.TransitionType.Sine); + + // 3. Title overlay — "Mission N: Name" big fade-in then slide-out + ShowMissionTitleOverlay(mission, snap); + } + + private void ShowMissionTitleOverlay(MissionDef mission, BoardSnapshot snap) + { + var missionNum = snap.Campaign!.CurrentMissionIndex + 1; + var label = new Label + { + Text = $"Mission {missionNum}\n{mission.Name}", + MouseFilter = Control.MouseFilterEnum.Ignore, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center + }; + label.AddThemeFontSizeOverride("font_size", 38); + label.AddThemeColorOverride("font_color", new Color("#FFE8D0")); + label.AddThemeColorOverride("font_outline_color", new Color(0, 0, 0, 0.9f)); + label.AddThemeConstantOverride("outline_size", 8); + label.SetAnchorsPreset(Control.LayoutPreset.FullRect); + label.OffsetRight = -SidePanelWidth; + label.OffsetBottom = -ControlBarHeight; + label.Modulate = new Color(1, 1, 1, 0); + + _uiLayer.AddChild(label); + + var tween = label.CreateTween(); + tween.TweenProperty(label, "modulate:a", 1f, 0.4f); + tween.TweenInterval(1.4f); + tween.TweenProperty(label, "modulate:a", 0f, 0.6f); + tween.TweenCallback(Callable.From(() => label.QueueFree())); + } + // --- Navigation --- private void OnBackToMenu() diff --git a/docs/PLAN.md b/docs/PLAN.md index a601067..7eebdc2 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -12,10 +12,6 @@ et l'extension de la campagne. Le moteur expose deja les commandes et events requis ; cote Godot il manque les surfaces d'interaction et d'animation. -### 1.4 Touche Suppr pour retirer une piece -Le bouton `[Retirer]` du `DetailPanel` existe. Ajouter en complement : -selection + `Delete` → meme effet que le bouton. - ### 1.5 Cinematique de transition de mission Sur `MissionStartedEvent` (hors mission 0) : - Titre "Nouvelle mission" plein ecran en fade-in.