using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Myra; using Theriapolis.Game.CodexUI.Core; using Theriapolis.Game.Screens; namespace Theriapolis.Game; /// /// Root MonoGame game class. /// Owns the screen stack, SpriteBatch, and the path to content data files. /// public sealed class Game1 : Microsoft.Xna.Framework.Game { private readonly GraphicsDeviceManager _graphics; private SpriteBatch _spriteBatch = null!; public ScreenManager Screens { get; private set; } = null!; /// /// Path to the Content/Data directory containing JSON data files. /// Defaults to "Data" relative to the executable; Desktop shell overrides this. /// public string ContentDataDirectory { get; set; } = "Data"; /// /// Path to the Content/Gfx directory containing sprite assets. Defaults to /// "Gfx" relative to the executable; Desktop shell overrides this. The /// TacticalAtlas reads Gfx/tactical/surface/*.png and /// Gfx/tactical/deco/*.png from here, falling back to procedural /// placeholders for any tile that has no PNG yet. /// public string ContentGfxDirectory { get; set; } = "Gfx"; /// /// Strongly-typed asset bundle for CodexUI screens. Loaded once during /// so every CodexScreen can reference the /// atlas without re-reading PNGs from disk. /// public CodexAtlas CodexAtlas { get; private set; } = new(); // Dev background colour — distinctive so it's obvious when nothing is drawn private static readonly Color DevClear = new(18, 24, 48); public Game1() { _graphics = new GraphicsDeviceManager(this) { PreferredBackBufferWidth = 1280, PreferredBackBufferHeight = 800, IsFullScreen = false, }; Content.RootDirectory = "Content"; IsMouseVisible = true; Window.Title = "Theriapolis"; Window.AllowUserResizing = true; } protected override void Initialize() { // Initialise Myra before any screen tries to use it MyraEnvironment.Game = this; Screens = new ScreenManager(this); Screens.Push(new TitleScreen()); base.Initialize(); } protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); // CodexUI assets + fonts — must load before any CodexScreen is pushed. // Fonts live under a sibling directory of Gfx; resolve via the parent. CodexAtlas.LoadAll(GraphicsDevice, ContentGfxDirectory); string contentRoot = System.IO.Path.GetDirectoryName(ContentGfxDirectory.TrimEnd('/', '\\')) ?? "."; CodexFonts.LoadAll(GraphicsDevice, contentRoot); } protected override void Update(GameTime gameTime) { // Global ESC from title → exit (ScreenManager handles in-game ESC) if (Screens.Current is TitleScreen && Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); Screens.Update(gameTime); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(DevClear); Screens.Draw(gameTime, _spriteBatch); base.Draw(gameTime); } }