// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using System; using System.Collections.Generic; using System.Threading.Tasks; using Stride.Core.Mathematics; using Stride.Engine; using Stride.Graphics; using Stride.Rendering.Sprites; using Stride.UI; using Stride.UI.Controls; using Stride.UI.Panels; namespace GameMenu { /// /// Script controller for the main scene. /// public class MainScript : UISceneBase { /// /// Default player name. /// private const string DefaultName = "John Doe"; private const int MaximumStar = 3; private static readonly List ShipNameList = new List { "red_ship", "green_ship", "blue_ship", "blue_ship", "yellow_ship", "yellow_ship", "cyan_ship" }; private readonly List shipList = new List(); private int money; private int bonus; private int lifeStatus; private int powerStatus; private int controlStatus; private int speedStatus; private int activeShipIndex; // Current SpaceShip of the character private readonly List starSpriteIndices = new List(); private readonly List borderStarSpriteIndices = new List(); #region Visuals private UIPage page; private ModalElement shipSelectPopup; // Root of SpaceShip select popup private ModalElement welcomePopup; // Root of welcome popup // Life gauge private RectangleF gaugeBarRegion; private Grid lifebarGrid; private Sprite lifebarGaugeImage; // Counters private TextBlock bonusCounter; private TextBlock lifeCounter; private TextBlock moneyCounter; // Name of the character private TextBlock nameTextBlock; private ImageElement currentShipImage; // Status stars private ImageElement controlStatusStar; private ImageElement powerStatusStar; private ImageElement speedStatusStar; #endregion // Visuals /// /// Spritesheet containing the sprites of the main scene. /// public SpriteSheet MainSceneImages { get; set; } /// /// UI library containing the modal popups and the ship button template. /// public UILibrary UILibrary { get; set; } private int Bonus { set { bonus = value; bonusCounter.Text = CreateBonusCountText(); } get { return bonus; } } private int ControlStatus { get { return controlStatus; } set { if (value > MaximumStar) return; controlStatus = value; ((SpriteFromSheet)controlStatusStar.Source).CurrentFrame = starSpriteIndices[controlStatus]; shipList[activeShipIndex].Control = controlStatus; } } private int LifeStatus { get { return lifeStatus; } set { lifeStatus = value; lifeCounter.Text = CreateLifeCountText(); } } private int PowerStatus { get { return powerStatus; } set { if (value > MaximumStar) return; powerStatus = value; ((SpriteFromSheet)powerStatusStar.Source).CurrentFrame = starSpriteIndices[powerStatus]; shipList[activeShipIndex].Power = powerStatus; } } private int SpeedStatus { get { return speedStatus; } set { if (value > MaximumStar) return; speedStatus = value; ((SpriteFromSheet)speedStatusStar.Source).CurrentFrame = starSpriteIndices[speedStatus]; shipList[activeShipIndex].Speed = speedStatus; } } private int Money { get { return money; } set { money = value; moneyCounter.Text = CreateMoneyCountText(); } } public override void Start() { base.Start(); ShowWelcomePopup(); } protected override void LoadScene() { // Preload stars starSpriteIndices.Add(MainSceneImages.FindImageIndex("star0")); starSpriteIndices.Add(MainSceneImages.FindImageIndex("star1")); starSpriteIndices.Add(MainSceneImages.FindImageIndex("star2")); starSpriteIndices.Add(MainSceneImages.FindImageIndex("star3")); borderStarSpriteIndices.Add(MainSceneImages.FindImageIndex("bstar0")); borderStarSpriteIndices.Add(MainSceneImages.FindImageIndex("bstar1")); borderStarSpriteIndices.Add(MainSceneImages.FindImageIndex("bstar2")); borderStarSpriteIndices.Add(MainSceneImages.FindImageIndex("bstar3")); // Create space ships var random = new Random(); for (var i = 0; i < ShipNameList.Count; i++) { shipList.Add(new SpaceShip { Name = ShipNameList[i], Power = random.Next(MaximumStar + 1), Control = random.Next(MaximumStar + 1), Speed = random.Next(MaximumStar + 1), IsLocked = (i % 3) == 2, }); } // Initialize UI page = Entity.Get().Page; InitializeMainPage(); InitializeShipSelectionPopup(); InitializeWelcomePopup(); // Add pop-ups to the overlay var overlay = (UniformGrid) page.RootElement; overlay.Children.Add(shipSelectPopup); overlay.Children.Add(welcomePopup); Script.AddTask(FillLifeBar); } private async Task FillLifeBar() { var gaugePercentage = 0.15f; while (gaugePercentage < 1f) { await Script.NextFrame(); gaugePercentage = Math.Min(1f, gaugePercentage + (float)Game.UpdateTime.Elapsed.TotalSeconds * 0.02f); var gaugeCurrentRegion = lifebarGaugeImage.Region; gaugeCurrentRegion.Width = gaugePercentage * gaugeBarRegion.Width; lifebarGaugeImage.Region = gaugeCurrentRegion; lifebarGrid.ColumnDefinitions[1].SizeValue = gaugeCurrentRegion.Width / gaugeBarRegion.Width; lifebarGrid.ColumnDefinitions[2].SizeValue = 1 - lifebarGrid.ColumnDefinitions[1].SizeValue; } } private bool CanPurchase(int requireMoney, int requireBonus) { return Money >= requireMoney && Bonus >= requireBonus; } private void CloseShipSelectPopup() { shipSelectPopup.Visibility = Visibility.Collapsed; } private void CloseWelcomePopup() { welcomePopup.Visibility = Visibility.Collapsed; } private string CreateBonusCountText() { return bonus.ToString("D3"); } private string CreateLifeCountText() { return "x" + lifeStatus; } private string CreateMoneyCountText() { return money.ToString("D3"); } private UIElement CreateShipSelectionItem(SpaceShip spaceShip) { var shipPanel = UILibrary.InstantiateElement("ShipButton"); var shipButton = shipPanel.FindVisualChildOfType("shipButton"); var shipImage = shipButton.FindVisualChildOfType("shipImage"); // Update spaceship spaceShip.PowerImageElement = shipButton.FindVisualChildOfType("powerImage"); spaceShip.ControlImageElement = shipButton.FindVisualChildOfType("controlImage"); spaceShip.SpeedImageElement = shipButton.FindVisualChildOfType("speedImage"); var shipIndex = MainSceneImages.FindImageIndex(spaceShip.Name); ((SpriteFromSheet) shipImage.Source).CurrentFrame = shipIndex; shipButton.Click += delegate { activeShipIndex = shipList.FindIndex(w => w.Name == spaceShip.Name); ((SpriteFromSheet)currentShipImage.Source).CurrentFrame = shipIndex; PowerStatus = spaceShip.Power; ControlStatus = spaceShip.Control; SpeedStatus = spaceShip.Speed; CloseShipSelectPopup(); }; shipButton.IsEnabled = !spaceShip.IsLocked; if (spaceShip.IsLocked) { var lockIconElement = shipPanel.FindVisualChildOfType("lockIcon"); lockIconElement.Visibility = Visibility.Visible; } return shipPanel; } private void InitializeMainPage() { var rootElement = page.RootElement; // counters bonusCounter = rootElement.FindVisualChildOfType("bonusCounter"); lifeCounter = rootElement.FindVisualChildOfType("lifeCounter"); moneyCounter = rootElement.FindVisualChildOfType("moneyCounter"); Bonus = 30; LifeStatus = 3; Money = 30; // lifebar lifebarGaugeImage = MainSceneImages["life_bar"]; lifebarGrid = rootElement.FindVisualChildOfType("lifebarGrid"); gaugeBarRegion = lifebarGaugeImage.Region; // character name nameTextBlock = rootElement.FindVisualChildOfType("nameTextBlock"); // explanation // FIXME: UI asset should support multiline text var explanationText = rootElement.FindVisualChildOfType("explanationText"); explanationText.Text = "Pictogram-based alphabets are easily supported.\n日本語も簡単に入れることが出来ます。"; // status stars var statusPanel = rootElement.FindVisualChildOfType("statusPanel"); powerStatusStar = statusPanel.FindVisualChildOfType("powerStatusStar"); controlStatusStar = statusPanel.FindVisualChildOfType("controlStatusStar"); speedStatusStar = statusPanel.FindVisualChildOfType("speedStatusStar"); PowerStatus = shipList[activeShipIndex].Power; ControlStatus = shipList[activeShipIndex].Control; SpeedStatus = shipList[activeShipIndex].Speed; // ship selection var currentShipButton = rootElement.FindVisualChildOfType