Chessistics/Scripts/UI/LevelSelectScreen.cs

227 lines
7.7 KiB
C#
Raw Normal View History

using Godot;
using System;
namespace Chessistics.Scripts.UI;
public partial class LevelSelectScreen : Control
{
[Signal]
public delegate void LevelSelectedEventHandler(int levelIndex);
private readonly (string name, string desc)[] _levels =
[
("Premier Convoi", "Acheminez du bois de la scierie au depot."),
("Deux Clients", "Fournissez deux destinations depuis une seule scierie."),
("Le Col", "Franchissez le mur et gerez deux types de cargaison."),
("Le Carrefour", "Deux productions, deux demandes, et un carrefour au centre."),
("Le Labyrinthe", "Un couloir etroit serpente a travers les murs."),
("Trois Royaumes", "Trois productions, trois demandes. Gerez un reseau complet.")
];
public override void _Ready()
{
// Full-screen dark background
var bg = new PanelContainer();
bg.SetAnchorsPreset(LayoutPreset.FullRect);
var bgStyle = new StyleBoxFlat { BgColor = new Color(0.12f, 0.12f, 0.14f) };
bg.AddThemeStyleboxOverride("panel", bgStyle);
bg.MouseFilter = MouseFilterEnum.Ignore;
AddChild(bg);
// Outer margin
var margin = new MarginContainer();
margin.SetAnchorsPreset(LayoutPreset.FullRect);
margin.AddThemeConstantOverride("margin_left", 80);
margin.AddThemeConstantOverride("margin_right", 80);
margin.AddThemeConstantOverride("margin_top", 60);
margin.AddThemeConstantOverride("margin_bottom", 60);
margin.MouseFilter = MouseFilterEnum.Ignore;
var outerVBox = new VBoxContainer();
outerVBox.AddThemeConstantOverride("separation", 0);
outerVBox.MouseFilter = MouseFilterEnum.Ignore;
// --- Header section ---
var headerBox = new VBoxContainer();
headerBox.AddThemeConstantOverride("separation", 4);
headerBox.MouseFilter = MouseFilterEnum.Ignore;
var title = new Label
{
Text = "CHESSISTICS",
HorizontalAlignment = HorizontalAlignment.Center
};
title.AddThemeFontSizeOverride("font_size", 48);
title.AddThemeColorOverride("font_color", new Color("#FFD700"));
headerBox.AddChild(title);
var subtitle = new Label
{
Text = "Selectionnez un niveau",
HorizontalAlignment = HorizontalAlignment.Center
};
subtitle.AddThemeFontSizeOverride("font_size", 15);
subtitle.AddThemeColorOverride("font_color", new Color("#777777"));
headerBox.AddChild(subtitle);
outerVBox.AddChild(headerBox);
// Spacer
outerVBox.AddChild(new Control { CustomMinimumSize = new Vector2(0, 48) });
// --- Level cards in a scrollable grid ---
var scroll = new ScrollContainer
{
SizeFlagsVertical = SizeFlags.ExpandFill,
HorizontalScrollMode = ScrollContainer.ScrollMode.Disabled
};
var grid = new GridContainer
{
Columns = 3,
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
MouseFilter = MouseFilterEnum.Ignore
};
grid.AddThemeConstantOverride("h_separation", 28);
grid.AddThemeConstantOverride("v_separation", 28);
for (int i = 0; i < _levels.Length; i++)
{
var (name, desc) = _levels[i];
grid.AddChild(CreateLevelCard(i, name, desc));
}
scroll.AddChild(grid);
outerVBox.AddChild(scroll);
margin.AddChild(outerVBox);
AddChild(margin);
}
private Control CreateLevelCard(int index, string name, string description)
{
var card = new PanelContainer
{
CustomMinimumSize = new Vector2(300, 240),
SizeFlagsVertical = SizeFlags.ShrinkCenter
};
var cardStyle = new StyleBoxFlat
{
BgColor = new Color(0.17f, 0.17f, 0.19f),
BorderColor = new Color(0.28f, 0.28f, 0.32f),
BorderWidthBottom = 1,
BorderWidthTop = 1,
BorderWidthLeft = 1,
BorderWidthRight = 1,
CornerRadiusTopLeft = 8,
CornerRadiusTopRight = 8,
CornerRadiusBottomLeft = 8,
CornerRadiusBottomRight = 8,
ContentMarginLeft = 24,
ContentMarginRight = 24,
ContentMarginTop = 24,
ContentMarginBottom = 24
};
card.AddThemeStyleboxOverride("panel", cardStyle);
var vbox = new VBoxContainer();
vbox.AddThemeConstantOverride("separation", 10);
// Level number
var numLabel = new Label
{
Text = $"Niveau {index + 1}",
HorizontalAlignment = HorizontalAlignment.Center
};
numLabel.AddThemeFontSizeOverride("font_size", 12);
numLabel.AddThemeColorOverride("font_color", new Color("#666666"));
vbox.AddChild(numLabel);
// Level name
var nameLabel = new Label
{
Text = name,
HorizontalAlignment = HorizontalAlignment.Center
};
nameLabel.AddThemeFontSizeOverride("font_size", 22);
nameLabel.AddThemeColorOverride("font_color", new Color("#EEEEEE"));
vbox.AddChild(nameLabel);
// Thin separator
var sep = new HSeparator { CustomMinimumSize = new Vector2(0, 4) };
vbox.AddChild(sep);
// Description
var descLabel = new Label
{
Text = description,
HorizontalAlignment = HorizontalAlignment.Center,
AutowrapMode = TextServer.AutowrapMode.Word,
CustomMinimumSize = new Vector2(240, 0)
};
descLabel.AddThemeFontSizeOverride("font_size", 13);
descLabel.AddThemeColorOverride("font_color", new Color("#999999"));
vbox.AddChild(descLabel);
// Flexible spacer
vbox.AddChild(new Control { SizeFlagsVertical = SizeFlags.ExpandFill });
// Play button
var playBtn = new Button
{
Text = "Jouer",
CustomMinimumSize = new Vector2(120, 38),
SizeFlagsHorizontal = SizeFlags.ShrinkCenter
};
var btnNormal = new StyleBoxFlat
{
BgColor = new Color("#8B6914"),
CornerRadiusTopLeft = 6,
CornerRadiusTopRight = 6,
CornerRadiusBottomLeft = 6,
CornerRadiusBottomRight = 6,
ContentMarginLeft = 24,
ContentMarginRight = 24,
ContentMarginTop = 8,
ContentMarginBottom = 8
};
var btnHover = new StyleBoxFlat
{
BgColor = new Color("#B8860B"),
CornerRadiusTopLeft = 6,
CornerRadiusTopRight = 6,
CornerRadiusBottomLeft = 6,
CornerRadiusBottomRight = 6,
ContentMarginLeft = 24,
ContentMarginRight = 24,
ContentMarginTop = 8,
ContentMarginBottom = 8
};
var btnPressed = new StyleBoxFlat
{
BgColor = new Color("#6B5010"),
CornerRadiusTopLeft = 6,
CornerRadiusTopRight = 6,
CornerRadiusBottomLeft = 6,
CornerRadiusBottomRight = 6,
ContentMarginLeft = 24,
ContentMarginRight = 24,
ContentMarginTop = 8,
ContentMarginBottom = 8
};
playBtn.AddThemeStyleboxOverride("normal", btnNormal);
playBtn.AddThemeStyleboxOverride("hover", btnHover);
playBtn.AddThemeStyleboxOverride("pressed", btnPressed);
playBtn.AddThemeFontSizeOverride("font_size", 15);
var idx = index;
playBtn.Pressed += () => EmitSignal(SignalName.LevelSelected, idx);
vbox.AddChild(playBtn);
card.AddChild(vbox);
return card;
}
}