using System.Text.Json; using DoomDeathmatch.Component.UI; using DoomDeathmatch.Component.Util; using DoomDeathmatch.Scene.Play; using DoomDeathmatch.Script.Score; using DoomDeathmatch.Script.UI; using Engine.Graphics.Pipeline; using Engine.Scene; using Engine.Scene.Component.BuiltIn; using Engine.Scene.Component.BuiltIn.Renderer; using Engine.Util; using OpenTK.Mathematics; namespace DoomDeathmatch.Scene.Main; public static class MainScene { public static Engine.Scene.Scene Create() { var scene = new Engine.Scene.Scene(); var (cameraObject, camera) = UiUtil.CreateOrthographicCamera(scene); var (uiContainerObject, uiContainer) = UiUtil.CreateBackgroundUi(scene, new UiContainerComponent { Camera = camera }); var (logoObject, logoUi) = UiUtil.CreateLogoUi(scene, uiContainer); logoUi.Offset = new Vector2(0, 3f); scene.AddChild(uiContainerObject, logoObject); var menuController = new MenuControllerComponent(); var menuControllerObject = GameObjectUtil.CreateGameObject(scene, [ menuController ]); var mainMenu = CreateMainMenu(scene, uiContainer, menuController); menuController.AddMenuItem("main", mainMenu); var leadersMenu = CreateLeadersMenu(scene, uiContainer, menuController); leadersMenu.IsEnabled = false; menuController.AddMenuItem("leaders", leadersMenu); var rulesMenu = CreateRulesMenu(scene, uiContainer, menuController); rulesMenu.IsEnabled = false; menuController.AddMenuItem("rules", rulesMenu); scene.AddChild(uiContainerObject, mainMenu); scene.AddChild(uiContainerObject, leadersMenu); scene.AddChild(uiContainerObject, rulesMenu); return scene; } private static GameObject CreateMainMenu(Engine.Scene.Scene parScene, UiContainerComponent parUiContainer, MenuControllerComponent parMenuController) { var parentObject = GameObjectUtil.CreateGameObject(parScene); var (playUiObject, playUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Играть"); var (leadersUiObject, leadersUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Лидеры"); var (rulesUiObject, rulesUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Правила"); var (exitUiObject, exitUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Выход"); var (stackObject, stack) = UiUtil.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { playUi, leadersUi, rulesUi, exitUi } }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); playUi.OnClick += _ => EngineUtil.SceneManager.TransitionTo(PlayScene.Create); leadersUi.OnClick += _ => parMenuController.SelectMenuItem("leaders"); rulesUi.OnClick += _ => parMenuController.SelectMenuItem("rules"); exitUi.OnClick += _ => EngineUtil.Close(); var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { playUi, leadersUi, rulesUi, exitUi } }); parScene.AddChild(parentObject, selectorObject); parScene.AddChild(parentObject, stackObject); parScene.AddChild(stackObject, playUiObject); parScene.AddChild(stackObject, leadersUiObject); parScene.AddChild(stackObject, rulesUiObject); parScene.AddChild(stackObject, exitUiObject); return parentObject; } private static GameObject CreateLeadersMenu(Engine.Scene.Scene parScene, UiContainerComponent parUiContainer, MenuControllerComponent parMenuController) { var parentObject = GameObjectUtil.CreateGameObject(parScene); var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Назад"); backUi.OnClick += _ => parMenuController.SelectMenuItem("main"); var (stackObject, stack) = UiUtil.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1.5f), Container = parUiContainer, Children = { } }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); var leadersTable = CreateLeadersTable(parScene, parUiContainer, EngineUtil.DataFolder); foreach (var (rowObject, rowUi) in leadersTable) { stack.Children.Add(rowUi); parScene.AddChild(stackObject, rowObject); } stack.Children.Add(backUi); var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } }); parScene.AddChild(parentObject, selectorObject); parScene.AddChild(parentObject, stackObject); parScene.AddChild(stackObject, backUiObject); return parentObject; } private static List<(GameObject, UiComponent)> CreateLeadersTable(Engine.Scene.Scene parScene, UiContainerComponent parUiContainer, string parDataFolder) { var leadersTableList = new List<(GameObject, UiComponent)> { CreateLeadersRow(parScene, parUiContainer, "Имя", "Очки") }; var leadersTable = ScoreTable.LoadOrCreate(Path.Combine(parDataFolder, "leaders.json")); var rows = 0; foreach (var row in leadersTable.Rows) { leadersTableList.Add(CreateLeadersRow(parScene, parUiContainer, row.Name, row.Score.ToString())); if (++rows >= 5) break; } return leadersTableList; } private static (GameObject, UiComponent) CreateLeadersRow(Engine.Scene.Scene parScene, UiContainerComponent parUiContainer, string parName, string parScore) { var uiComponent = new UiContainerComponent { Container = parUiContainer }; var rowObject = GameObjectUtil.CreateGameObject(parScene, new Transform { Size = new Vector3(5, 8, 1) }, [ uiComponent ]); var (nameUiObject, nameUi, _) = UiUtil.CreateTextUi(parScene, uiComponent, UiUtil.GetDoomFont(), parName); nameUi.Anchor = Anchor.CenterLeft; nameUi.Center = Anchor.Center; var (scoreUiObject, scoreUi, _) = UiUtil.CreateTextUi(parScene, uiComponent, UiUtil.GetDoomFont(), parScore); scoreUi.Anchor = Anchor.CenterRight; scoreUi.Center = Anchor.Center; parScene.AddChild(rowObject, nameUiObject); parScene.AddChild(rowObject, scoreUiObject); return (rowObject, uiComponent); } private static GameObject CreateRulesMenu(Engine.Scene.Scene parScene, UiContainerComponent parUiContainer, MenuControllerComponent parMenuController) { var parentObject = GameObjectUtil.CreateGameObject(parScene); var (backUiObject, backUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Назад"); backUi.OnClick += _ => parMenuController.SelectMenuItem("main"); var (rulesObject, rulesUi, _) = UiUtil.CreateTextUi(parScene, parUiContainer, UiUtil.GetDoomFont(), "Правила"); var (stackObject, stack) = UiUtil.CreateStackUi(parScene, new StackComponent { Offset = new Vector2(0, -1f), Container = parUiContainer, Children = { rulesUi, backUi } }); stackObject.Transform.Size.Xy = new Vector2(1f, 6f); var (selectorObject, selector) = UiUtil.CreateSelectorUi(parScene, new SelectorComponent { Children = { backUi } }); parScene.AddChild(parentObject, selectorObject); parScene.AddChild(parentObject, stackObject); parScene.AddChild(stackObject, rulesObject); parScene.AddChild(stackObject, backUiObject); return parentObject; } }