Initial commit: Theriapolis baseline at port/godot branch point
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Myra;
|
||||
using Myra.Graphics2D.UI;
|
||||
|
||||
namespace Theriapolis.Game.Screens;
|
||||
|
||||
/// <summary>
|
||||
/// Title screen: game logo text, "New World" button, optional seed input field.
|
||||
/// Uses Myra for all UI widgets.
|
||||
/// </summary>
|
||||
public sealed class TitleScreen : IScreen
|
||||
{
|
||||
private Game1 _game = null!;
|
||||
private Desktop _desktop = null!;
|
||||
private TextBox? _seedInput;
|
||||
|
||||
public void Initialize(Game1 game)
|
||||
{
|
||||
_game = game;
|
||||
BuildUI();
|
||||
}
|
||||
|
||||
private void BuildUI()
|
||||
{
|
||||
var root = new VerticalStackPanel
|
||||
{
|
||||
Spacing = 12,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
|
||||
// Title label
|
||||
var title = new Label
|
||||
{
|
||||
Text = "THERIAPOLIS",
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
};
|
||||
root.Widgets.Add(title);
|
||||
|
||||
// Sub-title
|
||||
var sub = new Label
|
||||
{
|
||||
Text = "Veldara awaits.",
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
};
|
||||
root.Widgets.Add(sub);
|
||||
|
||||
// Spacer
|
||||
root.Widgets.Add(new Label { Text = " " });
|
||||
|
||||
// Seed row
|
||||
var seedRow = new HorizontalStackPanel { Spacing = 8 };
|
||||
seedRow.Widgets.Add(new Label { Text = "Seed:", VerticalAlignment = VerticalAlignment.Center });
|
||||
_seedInput = new TextBox
|
||||
{
|
||||
Text = "",
|
||||
Width = 160,
|
||||
};
|
||||
seedRow.Widgets.Add(_seedInput);
|
||||
root.Widgets.Add(seedRow);
|
||||
|
||||
// New World button
|
||||
var newWorldBtn = new TextButton
|
||||
{
|
||||
Text = "New World",
|
||||
Width = 180,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
};
|
||||
newWorldBtn.Click += OnNewWorldClicked;
|
||||
root.Widgets.Add(newWorldBtn);
|
||||
|
||||
var loadBtn = new TextButton
|
||||
{
|
||||
Text = "Load Game",
|
||||
Width = 180,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
};
|
||||
loadBtn.Click += (_, _) => _game.Screens.Push(new SaveLoadScreen());
|
||||
root.Widgets.Add(loadBtn);
|
||||
|
||||
_desktop = new Desktop { Root = root };
|
||||
}
|
||||
|
||||
private void OnNewWorldClicked(object? sender, EventArgs e)
|
||||
{
|
||||
ulong seed;
|
||||
string raw = _seedInput?.Text?.Trim() ?? "";
|
||||
if (string.IsNullOrEmpty(raw))
|
||||
{
|
||||
// Random seed from system time
|
||||
seed = (ulong)DateTime.UtcNow.Ticks;
|
||||
}
|
||||
else if (!ulong.TryParse(raw, out seed))
|
||||
{
|
||||
// Hash the string to a seed
|
||||
seed = 0;
|
||||
foreach (char c in raw) seed = seed * 31 + c;
|
||||
}
|
||||
|
||||
_game.Screens.Push(new CodexUI.Screens.CodexCharacterCreationScreen(seed));
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime) { }
|
||||
|
||||
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
|
||||
{
|
||||
_game.GraphicsDevice.Clear(new Color(20, 20, 30));
|
||||
_desktop.Render();
|
||||
}
|
||||
|
||||
public void Deactivate() { }
|
||||
public void Reactivate() { }
|
||||
}
|
||||
Reference in New Issue
Block a user