Fix stop reset, piece selection visuals, add trajectory preview and menu button
Bugfixes:
- Stop now fully rebuilds piece visuals (fixes destroyed pieces not
reappearing and lingering cargo indicators)
- Piece stock buttons use explicit selected/unselected styling instead
of ambiguous toggle behavior (teal bg + bright border when selected)
- Color dots next to stock buttons match piece colors
Features:
- Clicking a placed piece highlights its start/end cells with piece color
- Back-to-menu button ("← Menu") in top-left returns to level selector
with fade transition
- DetailPanel shows "Pion" name and has styled remove button
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
43a3e97f28
commit
210be72100
3 changed files with 162 additions and 14 deletions
|
|
@ -133,14 +133,35 @@ public partial class Main : Node2D
|
|||
uiRoot.MouseFilter = Control.MouseFilterEnum.Ignore;
|
||||
_uiLayer.AddChild(uiRoot);
|
||||
|
||||
// Level title (top-left)
|
||||
// Level title bar (top-left)
|
||||
var titleBar = new HBoxContainer();
|
||||
titleBar.SetAnchorsPreset(Control.LayoutPreset.TopLeft);
|
||||
titleBar.OffsetLeft = 12;
|
||||
titleBar.OffsetTop = 8;
|
||||
titleBar.AddThemeConstantOverride("separation", 12);
|
||||
|
||||
var backButton = new Button { Text = "← Menu", CustomMinimumSize = new Vector2(70, 28) };
|
||||
backButton.AddThemeFontSizeOverride("font_size", 11);
|
||||
var backStyle = new StyleBoxFlat
|
||||
{
|
||||
BgColor = new Color("#2A2A2E"),
|
||||
BorderColor = new Color("#444448"),
|
||||
BorderWidthBottom = 1, BorderWidthTop = 1, BorderWidthLeft = 1, BorderWidthRight = 1,
|
||||
CornerRadiusTopLeft = 4, CornerRadiusTopRight = 4,
|
||||
CornerRadiusBottomLeft = 4, CornerRadiusBottomRight = 4,
|
||||
ContentMarginLeft = 8, ContentMarginRight = 8,
|
||||
ContentMarginTop = 2, ContentMarginBottom = 2
|
||||
};
|
||||
backButton.AddThemeStyleboxOverride("normal", backStyle);
|
||||
backButton.Pressed += OnBackToMenu;
|
||||
titleBar.AddChild(backButton);
|
||||
|
||||
_levelTitle = new Label { Text = "CHESSISTICS" };
|
||||
_levelTitle.SetAnchorsPreset(Control.LayoutPreset.TopLeft);
|
||||
_levelTitle.OffsetLeft = 16;
|
||||
_levelTitle.OffsetTop = 12;
|
||||
_levelTitle.AddThemeFontSizeOverride("font_size", 20);
|
||||
_levelTitle.MouseFilter = Control.MouseFilterEnum.Ignore;
|
||||
uiRoot.AddChild(_levelTitle);
|
||||
titleBar.AddChild(_levelTitle);
|
||||
|
||||
uiRoot.AddChild(titleBar);
|
||||
|
||||
// --- Side Panel (anchored to right edge) ---
|
||||
_sidePanel = new PanelContainer();
|
||||
|
|
@ -268,13 +289,24 @@ public partial class Main : Node2D
|
|||
var snap = _sim.GetSnapshot();
|
||||
if (snap.Phase != SimPhase.Edit) return;
|
||||
|
||||
_boardView.ClearHighlights();
|
||||
|
||||
var coords = new Coords(col, row);
|
||||
var piece = snap.Pieces.FirstOrDefault(p => p.StartCell == coords || p.EndCell == coords);
|
||||
if (piece != null)
|
||||
{
|
||||
_detailPanel.ShowPiece(piece);
|
||||
|
||||
// Highlight start and end cells to show trajectory
|
||||
var pieceColor = PieceView.GetPieceColor(piece.Kind);
|
||||
var highlightColor = new Color(pieceColor, 0.3f);
|
||||
_boardView.HighlightCells([piece.StartCell, piece.EndCell], highlightColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_detailPanel.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Level Management ---
|
||||
|
||||
|
|
@ -491,13 +523,32 @@ public partial class Main : Node2D
|
|||
_running = false;
|
||||
_simTimer.Stop();
|
||||
_sim.ProcessCommand(new StopSimulationCommand());
|
||||
_eventAnimator.ResetPiecePositions(_sim.GetSnapshot());
|
||||
|
||||
// Full visual rebuild: clear everything and recreate from snapshot
|
||||
_eventAnimator.ClearAll();
|
||||
var snap = _sim.GetSnapshot();
|
||||
foreach (var ps in snap.Pieces)
|
||||
{
|
||||
var pieceView = new PieceView();
|
||||
pieceView.Setup(ps.Id, ps.Kind, ps.StartCell, ps.EndCell, _boardView);
|
||||
_boardView.AddChild(pieceView);
|
||||
|
||||
var color = PieceView.GetPieceColor(ps.Kind);
|
||||
var trajectView = new TrajectView();
|
||||
trajectView.Setup(ps.Id,
|
||||
_boardView.CoordsToPixel(ps.StartCell),
|
||||
_boardView.CoordsToPixel(ps.EndCell),
|
||||
color);
|
||||
_boardView.AddChild(trajectView);
|
||||
|
||||
_eventAnimator.RegisterPiece(ps.Id, pieceView, trajectView);
|
||||
}
|
||||
|
||||
_controlBar.UpdateForPhase(SimPhase.Edit);
|
||||
_controlBar.ResetTurn();
|
||||
_metricsOverlay.Hide();
|
||||
_inputMapper.SetSnapshot(_sim.GetSnapshot());
|
||||
_inputMapper.SetSnapshot(snap);
|
||||
|
||||
// Reset objective panel
|
||||
if (_currentLevel != null)
|
||||
_objectivePanel.Setup(_currentLevel.Demands);
|
||||
}
|
||||
|
|
@ -550,4 +601,18 @@ public partial class Main : Node2D
|
|||
else
|
||||
ShowLevelSelect();
|
||||
}
|
||||
|
||||
private void OnBackToMenu()
|
||||
{
|
||||
SfxManager.Instance?.PlayClick();
|
||||
_running = false;
|
||||
_simTimer.Stop();
|
||||
_eventAnimator.ClearAll();
|
||||
|
||||
FadeOut(0.2f, () =>
|
||||
{
|
||||
ShowLevelSelect();
|
||||
FadeIn(0.3f);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Godot;
|
||||
using Chessistics.Engine.Model;
|
||||
using Chessistics.Scripts.Pieces;
|
||||
|
||||
namespace Chessistics.Scripts.UI;
|
||||
|
||||
|
|
@ -14,17 +15,41 @@ public partial class DetailPanel : PanelContainer
|
|||
|
||||
public override void _Ready()
|
||||
{
|
||||
var style = new StyleBoxFlat
|
||||
{
|
||||
BgColor = new Color(0.14f, 0.14f, 0.16f, 0.95f),
|
||||
BorderColor = new Color("#444448"),
|
||||
BorderWidthTop = 1,
|
||||
CornerRadiusTopLeft = 4, CornerRadiusTopRight = 4,
|
||||
ContentMarginLeft = 12, ContentMarginRight = 12,
|
||||
ContentMarginTop = 8, ContentMarginBottom = 8
|
||||
};
|
||||
AddThemeStyleboxOverride("panel", style);
|
||||
|
||||
var vbox = new VBoxContainer();
|
||||
vbox.AddThemeConstantOverride("separation", 4);
|
||||
|
||||
var title = new Label { Text = "DETAIL" };
|
||||
title.AddThemeFontSizeOverride("font_size", 14);
|
||||
title.AddThemeFontSizeOverride("font_size", 13);
|
||||
title.AddThemeColorOverride("font_color", new Color("#B8942A"));
|
||||
vbox.AddChild(title);
|
||||
|
||||
_infoLabel = new Label { Text = "" };
|
||||
_infoLabel.AddThemeFontSizeOverride("font_size", 11);
|
||||
_infoLabel.AddThemeColorOverride("font_color", new Color("#CCCCCC"));
|
||||
vbox.AddChild(_infoLabel);
|
||||
|
||||
_removeButton = new Button { Text = "Retirer" };
|
||||
_removeButton = new Button { Text = "Retirer", CustomMinimumSize = new Vector2(80, 26) };
|
||||
_removeButton.AddThemeFontSizeOverride("font_size", 11);
|
||||
var btnStyle = new StyleBoxFlat
|
||||
{
|
||||
BgColor = new Color("#5A2A2A"),
|
||||
CornerRadiusTopLeft = 4, CornerRadiusTopRight = 4,
|
||||
CornerRadiusBottomLeft = 4, CornerRadiusBottomRight = 4,
|
||||
ContentMarginLeft = 8, ContentMarginRight = 8,
|
||||
ContentMarginTop = 2, ContentMarginBottom = 2
|
||||
};
|
||||
_removeButton.AddThemeStyleboxOverride("normal", btnStyle);
|
||||
_removeButton.Pressed += () => EmitSignal(SignalName.RemoveRequested, _currentPieceId);
|
||||
vbox.AddChild(_removeButton);
|
||||
|
||||
|
|
@ -37,6 +62,7 @@ public partial class DetailPanel : PanelContainer
|
|||
_currentPieceId = piece.Id;
|
||||
var kindName = piece.Kind switch
|
||||
{
|
||||
PieceKind.Pawn => "Pion",
|
||||
PieceKind.Rook => "Tour II",
|
||||
PieceKind.Bishop => "Fou II",
|
||||
PieceKind.Knight => "Cavalier",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Godot;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Chessistics.Engine.Model;
|
||||
using Chessistics.Scripts.Pieces;
|
||||
|
||||
namespace Chessistics.Scripts.UI;
|
||||
|
||||
|
|
@ -15,6 +16,13 @@ public partial class PieceStockPanel : VBoxContainer
|
|||
|
||||
public PieceKind? SelectedKind => _selectedKind;
|
||||
|
||||
private static readonly Color NormalBg = new("#2A2A2E");
|
||||
private static readonly Color SelectedBg = new("#3D6B8E");
|
||||
private static readonly Color HoverBg = new("#353538");
|
||||
private static readonly Color DisabledBg = new("#1E1E20");
|
||||
private static readonly Color BorderNormal = new("#444448");
|
||||
private static readonly Color BorderSelected = new("#5A9ECC");
|
||||
|
||||
public void Setup(IReadOnlyList<PieceStock> stock)
|
||||
{
|
||||
foreach (var child in GetChildren())
|
||||
|
|
@ -24,7 +32,7 @@ public partial class PieceStockPanel : VBoxContainer
|
|||
|
||||
var title = new Label { Text = "PIECES" };
|
||||
title.AddThemeFontSizeOverride("font_size", 16);
|
||||
title.AddThemeColorOverride("font_color", new Color("#FFD700"));
|
||||
title.AddThemeColorOverride("font_color", new Color("#B8942A"));
|
||||
AddChild(title);
|
||||
|
||||
AddChild(new HSeparator());
|
||||
|
|
@ -32,16 +40,31 @@ public partial class PieceStockPanel : VBoxContainer
|
|||
foreach (var entry in stock)
|
||||
{
|
||||
var hbox = new HBoxContainer();
|
||||
hbox.AddThemeConstantOverride("separation", 8);
|
||||
|
||||
// Color dot matching piece color
|
||||
var dot = new ColorRect
|
||||
{
|
||||
CustomMinimumSize = new Vector2(10, 10),
|
||||
Size = new Vector2(10, 10),
|
||||
Color = PieceView.GetPieceColor(entry.Kind),
|
||||
MouseFilter = Control.MouseFilterEnum.Ignore
|
||||
};
|
||||
var dotCenter = new CenterContainer { CustomMinimumSize = new Vector2(14, 32) };
|
||||
dotCenter.AddChild(dot);
|
||||
hbox.AddChild(dotCenter);
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
Text = GetPieceName(entry.Kind),
|
||||
CustomMinimumSize = new Vector2(120, 32),
|
||||
ToggleMode = true
|
||||
ToggleMode = false // We manage selection state ourselves
|
||||
};
|
||||
ApplyButtonStyle(button, false);
|
||||
|
||||
var countLabel = new Label { Text = $"x{entry.Count}" };
|
||||
countLabel.AddThemeFontSizeOverride("font_size", 14);
|
||||
countLabel.AddThemeFontSizeOverride("font_size", 13);
|
||||
countLabel.AddThemeColorOverride("font_color", new Color("#999999"));
|
||||
|
||||
var kind = entry.Kind;
|
||||
button.Pressed += () => OnPieceButtonPressed(kind);
|
||||
|
|
@ -72,11 +95,45 @@ public partial class PieceStockPanel : VBoxContainer
|
|||
{
|
||||
foreach (var (k, (button, _, remaining)) in _entries)
|
||||
{
|
||||
button.ButtonPressed = k == _selectedKind;
|
||||
bool selected = k == _selectedKind;
|
||||
button.Disabled = remaining <= 0;
|
||||
ApplyButtonStyle(button, selected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyButtonStyle(Button button, bool selected)
|
||||
{
|
||||
var bg = selected ? SelectedBg : NormalBg;
|
||||
var border = selected ? BorderSelected : BorderNormal;
|
||||
|
||||
var normal = MakeStyle(bg, border);
|
||||
var hover = MakeStyle(selected ? SelectedBg.Lightened(0.1f) : HoverBg, border);
|
||||
var disabled = MakeStyle(DisabledBg, new Color("#2A2A2E"));
|
||||
|
||||
button.AddThemeStyleboxOverride("normal", normal);
|
||||
button.AddThemeStyleboxOverride("hover", hover);
|
||||
button.AddThemeStyleboxOverride("pressed", MakeStyle(bg.Darkened(0.15f), border));
|
||||
button.AddThemeStyleboxOverride("disabled", disabled);
|
||||
button.AddThemeFontSizeOverride("font_size", 12);
|
||||
button.AddThemeColorOverride("font_color", selected ? Colors.White : new Color("#CCCCCC"));
|
||||
button.AddThemeColorOverride("font_disabled_color", new Color("#555555"));
|
||||
}
|
||||
|
||||
private static StyleBoxFlat MakeStyle(Color bg, Color border)
|
||||
{
|
||||
return new StyleBoxFlat
|
||||
{
|
||||
BgColor = bg,
|
||||
BorderColor = border,
|
||||
BorderWidthBottom = 1, BorderWidthTop = 1,
|
||||
BorderWidthLeft = 1, BorderWidthRight = 1,
|
||||
CornerRadiusTopLeft = 4, CornerRadiusTopRight = 4,
|
||||
CornerRadiusBottomLeft = 4, CornerRadiusBottomRight = 4,
|
||||
ContentMarginLeft = 8, ContentMarginRight = 8,
|
||||
ContentMarginTop = 4, ContentMarginBottom = 4
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateCount(PieceKind kind, int remaining)
|
||||
{
|
||||
if (!_entries.TryGetValue(kind, out var entry)) return;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue