BlockGameMenu.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Numerics;
  5. using System.Text;
  6. using Content.Client.Arcade.UI;
  7. using Content.Client.Resources;
  8. using Content.Shared.Arcade;
  9. using Content.Shared.Input;
  10. using Robust.Client.Graphics;
  11. using Robust.Client.ResourceManagement;
  12. using Robust.Client.UserInterface;
  13. using Robust.Client.UserInterface.Controls;
  14. using Robust.Client.UserInterface.CustomControls;
  15. using Robust.Shared.Graphics;
  16. using Robust.Shared.IoC;
  17. using Robust.Shared.Localization;
  18. using Robust.Shared.Maths;
  19. using Robust.Shared.Utility;
  20. using static Robust.Client.UserInterface.Controls.BoxContainer;
  21. namespace Content.Client.Arcade
  22. {
  23. public sealed class BlockGameMenu : DefaultWindow
  24. {
  25. private static readonly Color OverlayBackgroundColor = new(74, 74, 81, 180);
  26. private static readonly Color OverlayShadowColor = new(0, 0, 0, 83);
  27. private static readonly Vector2 BlockSize = new(15, 15);
  28. private readonly PanelContainer _mainPanel;
  29. private readonly BoxContainer _gameRootContainer;
  30. private GridContainer _gameGrid = default!;
  31. private GridContainer _nextBlockGrid = default!;
  32. private GridContainer _holdBlockGrid = default!;
  33. private readonly Label _pointsLabel;
  34. private readonly Label _levelLabel;
  35. private readonly Button _pauseButton;
  36. private readonly PanelContainer _menuRootContainer;
  37. private readonly Button _unpauseButton;
  38. private readonly Control _unpauseButtonMargin;
  39. private readonly Button _newGameButton;
  40. private readonly Button _scoreBoardButton;
  41. private readonly PanelContainer _gameOverRootContainer;
  42. private readonly Label _finalScoreLabel;
  43. private readonly Button _finalNewGameButton;
  44. private readonly PanelContainer _highscoresRootContainer;
  45. private readonly Label _localHighscoresLabel;
  46. private readonly Label _globalHighscoresLabel;
  47. private readonly Button _highscoreBackButton;
  48. private bool _isPlayer = false;
  49. private bool _gameOver = false;
  50. public event Action<BlockGamePlayerAction>? OnAction;
  51. public BlockGameMenu()
  52. {
  53. Title = Loc.GetString("blockgame-menu-title");
  54. MinSize = SetSize = new Vector2(410, 490);
  55. var resourceCache = IoCManager.Resolve<IResourceCache>();
  56. var backgroundTexture = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
  57. _mainPanel = new PanelContainer();
  58. #region Game Menu
  59. // building the game container
  60. _gameRootContainer = new BoxContainer
  61. {
  62. Orientation = LayoutOrientation.Vertical
  63. };
  64. _levelLabel = new Label
  65. {
  66. Align = Label.AlignMode.Center,
  67. HorizontalExpand = true
  68. };
  69. _gameRootContainer.AddChild(_levelLabel);
  70. _gameRootContainer.AddChild(new Control
  71. {
  72. MinSize = new Vector2(1, 5)
  73. });
  74. _pointsLabel = new Label
  75. {
  76. Align = Label.AlignMode.Center,
  77. HorizontalExpand = true
  78. };
  79. _gameRootContainer.AddChild(_pointsLabel);
  80. _gameRootContainer.AddChild(new Control
  81. {
  82. MinSize = new Vector2(1, 10)
  83. });
  84. var gameBox = new BoxContainer
  85. {
  86. Orientation = LayoutOrientation.Horizontal
  87. };
  88. gameBox.AddChild(SetupHoldBox(backgroundTexture));
  89. gameBox.AddChild(new Control
  90. {
  91. MinSize = new Vector2(10, 1)
  92. });
  93. gameBox.AddChild(SetupGameGrid(backgroundTexture));
  94. gameBox.AddChild(new Control
  95. {
  96. MinSize = new Vector2(10, 1)
  97. });
  98. gameBox.AddChild(SetupNextBox(backgroundTexture));
  99. _gameRootContainer.AddChild(gameBox);
  100. _gameRootContainer.AddChild(new Control
  101. {
  102. MinSize = new Vector2(1, 10)
  103. });
  104. _pauseButton = new Button
  105. {
  106. Text = Loc.GetString("blockgame-menu-button-pause"),
  107. TextAlign = Label.AlignMode.Center
  108. };
  109. _pauseButton.OnPressed += (e) => TryPause();
  110. _gameRootContainer.AddChild(_pauseButton);
  111. #endregion
  112. _mainPanel.AddChild(_gameRootContainer);
  113. #region Pause Menu
  114. var pauseRootBack = new StyleBoxTexture
  115. {
  116. Texture = backgroundTexture,
  117. Modulate = OverlayShadowColor
  118. };
  119. pauseRootBack.SetPatchMargin(StyleBox.Margin.All, 10);
  120. _menuRootContainer = new PanelContainer
  121. {
  122. PanelOverride = pauseRootBack,
  123. VerticalAlignment = VAlignment.Center,
  124. HorizontalAlignment = HAlignment.Center
  125. };
  126. var pauseInnerBack = new StyleBoxTexture
  127. {
  128. Texture = backgroundTexture,
  129. Modulate = OverlayBackgroundColor
  130. };
  131. pauseInnerBack.SetPatchMargin(StyleBox.Margin.All, 10);
  132. var pauseMenuInnerPanel = new PanelContainer
  133. {
  134. PanelOverride = pauseInnerBack,
  135. VerticalAlignment = VAlignment.Center,
  136. HorizontalAlignment = HAlignment.Center
  137. };
  138. _menuRootContainer.AddChild(pauseMenuInnerPanel);
  139. var pauseMenuContainer = new BoxContainer
  140. {
  141. Orientation = LayoutOrientation.Vertical,
  142. HorizontalAlignment = HAlignment.Center,
  143. VerticalAlignment = VAlignment.Center
  144. };
  145. _newGameButton = new Button
  146. {
  147. Text = Loc.GetString("blockgame-menu-button-new-game"),
  148. TextAlign = Label.AlignMode.Center
  149. };
  150. _newGameButton.OnPressed += (e) =>
  151. {
  152. OnAction?.Invoke(BlockGamePlayerAction.NewGame);
  153. };
  154. pauseMenuContainer.AddChild(_newGameButton);
  155. pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
  156. _scoreBoardButton = new Button
  157. {
  158. Text = Loc.GetString("blockgame-menu-button-scoreboard"),
  159. TextAlign = Label.AlignMode.Center
  160. };
  161. _scoreBoardButton.OnPressed += (e) =>
  162. {
  163. OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores);
  164. };
  165. pauseMenuContainer.AddChild(_scoreBoardButton);
  166. _unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false };
  167. pauseMenuContainer.AddChild(_unpauseButtonMargin);
  168. _unpauseButton = new Button
  169. {
  170. Text = Loc.GetString("blockgame-menu-button-unpause"),
  171. TextAlign = Label.AlignMode.Center,
  172. Visible = false
  173. };
  174. _unpauseButton.OnPressed += (e) =>
  175. {
  176. OnAction?.Invoke(BlockGamePlayerAction.Unpause);
  177. };
  178. pauseMenuContainer.AddChild(_unpauseButton);
  179. pauseMenuInnerPanel.AddChild(pauseMenuContainer);
  180. #endregion
  181. #region Gameover Screen
  182. var gameOverRootBack = new StyleBoxTexture
  183. {
  184. Texture = backgroundTexture,
  185. Modulate = OverlayShadowColor
  186. };
  187. gameOverRootBack.SetPatchMargin(StyleBox.Margin.All, 10);
  188. _gameOverRootContainer = new PanelContainer
  189. {
  190. PanelOverride = gameOverRootBack,
  191. VerticalAlignment = VAlignment.Center,
  192. HorizontalAlignment = HAlignment.Center
  193. };
  194. var gameOverInnerBack = new StyleBoxTexture
  195. {
  196. Texture = backgroundTexture,
  197. Modulate = OverlayBackgroundColor
  198. };
  199. gameOverInnerBack.SetPatchMargin(StyleBox.Margin.All, 10);
  200. var gameOverMenuInnerPanel = new PanelContainer
  201. {
  202. PanelOverride = gameOverInnerBack,
  203. VerticalAlignment = VAlignment.Center,
  204. HorizontalAlignment = HAlignment.Center
  205. };
  206. _gameOverRootContainer.AddChild(gameOverMenuInnerPanel);
  207. var gameOverMenuContainer = new BoxContainer
  208. {
  209. Orientation = LayoutOrientation.Vertical,
  210. HorizontalAlignment = HAlignment.Center,
  211. VerticalAlignment = VAlignment.Center
  212. };
  213. gameOverMenuContainer.AddChild(new Label { Text = Loc.GetString("blockgame-menu-msg-game-over"), Align = Label.AlignMode.Center });
  214. gameOverMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
  215. _finalScoreLabel = new Label { Align = Label.AlignMode.Center };
  216. gameOverMenuContainer.AddChild(_finalScoreLabel);
  217. gameOverMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
  218. _finalNewGameButton = new Button
  219. {
  220. Text = Loc.GetString("blockgame-menu-button-new-game"),
  221. TextAlign = Label.AlignMode.Center
  222. };
  223. _finalNewGameButton.OnPressed += (e) =>
  224. {
  225. OnAction?.Invoke(BlockGamePlayerAction.NewGame);
  226. };
  227. gameOverMenuContainer.AddChild(_finalNewGameButton);
  228. gameOverMenuInnerPanel.AddChild(gameOverMenuContainer);
  229. #endregion
  230. #region High Score Screen
  231. var rootBack = new StyleBoxTexture
  232. {
  233. Texture = backgroundTexture,
  234. Modulate = OverlayShadowColor
  235. };
  236. rootBack.SetPatchMargin(StyleBox.Margin.All, 10);
  237. _highscoresRootContainer = new PanelContainer
  238. {
  239. PanelOverride = rootBack,
  240. VerticalAlignment = VAlignment.Center,
  241. HorizontalAlignment = HAlignment.Center
  242. };
  243. var c = new Color(OverlayBackgroundColor.R, OverlayBackgroundColor.G, OverlayBackgroundColor.B, 220);
  244. var innerBack = new StyleBoxTexture
  245. {
  246. Texture = backgroundTexture,
  247. Modulate = c
  248. };
  249. innerBack.SetPatchMargin(StyleBox.Margin.All, 10);
  250. var menuInnerPanel = new PanelContainer
  251. {
  252. PanelOverride = innerBack,
  253. VerticalAlignment = VAlignment.Center,
  254. HorizontalAlignment = HAlignment.Center
  255. };
  256. _highscoresRootContainer.AddChild(menuInnerPanel);
  257. var menuContainer = new BoxContainer
  258. {
  259. Orientation = LayoutOrientation.Vertical,
  260. HorizontalAlignment = HAlignment.Center,
  261. VerticalAlignment = VAlignment.Center
  262. };
  263. menuContainer.AddChild(new Label { Text = Loc.GetString("blockgame-menu-label-highscores") });
  264. menuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
  265. var highScoreBox = new BoxContainer
  266. {
  267. Orientation = LayoutOrientation.Horizontal
  268. };
  269. _localHighscoresLabel = new Label
  270. {
  271. Align = Label.AlignMode.Center
  272. };
  273. highScoreBox.AddChild(_localHighscoresLabel);
  274. highScoreBox.AddChild(new Control { MinSize = new Vector2(40, 1) });
  275. _globalHighscoresLabel = new Label
  276. {
  277. Align = Label.AlignMode.Center
  278. };
  279. highScoreBox.AddChild(_globalHighscoresLabel);
  280. menuContainer.AddChild(highScoreBox);
  281. menuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
  282. _highscoreBackButton = new Button
  283. {
  284. Text = Loc.GetString("blockgame-menu-button-back"),
  285. TextAlign = Label.AlignMode.Center
  286. };
  287. _highscoreBackButton.OnPressed += (e) =>
  288. {
  289. OnAction?.Invoke(BlockGamePlayerAction.Pause);
  290. };
  291. menuContainer.AddChild(_highscoreBackButton);
  292. menuInnerPanel.AddChild(menuContainer);
  293. #endregion
  294. Contents.AddChild(_mainPanel);
  295. CanKeyboardFocus = true;
  296. }
  297. public void SetUsability(bool isPlayer)
  298. {
  299. _isPlayer = isPlayer;
  300. UpdateUsability();
  301. }
  302. private void UpdateUsability()
  303. {
  304. _pauseButton.Disabled = !_isPlayer;
  305. _newGameButton.Disabled = !_isPlayer;
  306. _scoreBoardButton.Disabled = !_isPlayer;
  307. _unpauseButton.Disabled = !_isPlayer;
  308. _finalNewGameButton.Disabled = !_isPlayer;
  309. _highscoreBackButton.Disabled = !_isPlayer;
  310. }
  311. private Control SetupGameGrid(Texture panelTex)
  312. {
  313. _gameGrid = new GridContainer
  314. {
  315. Columns = 10,
  316. HSeparationOverride = 1,
  317. VSeparationOverride = 1
  318. };
  319. UpdateBlocks(Array.Empty<BlockGameBlock>());
  320. var back = new StyleBoxTexture
  321. {
  322. Texture = panelTex,
  323. Modulate = Color.FromHex("#4a4a51"),
  324. };
  325. back.SetPatchMargin(StyleBox.Margin.All, 10);
  326. var gamePanel = new PanelContainer
  327. {
  328. PanelOverride = back,
  329. HorizontalExpand = true,
  330. SizeFlagsStretchRatio = 34.25f
  331. };
  332. var backgroundPanel = new PanelContainer
  333. {
  334. PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#86868d") }
  335. };
  336. backgroundPanel.AddChild(_gameGrid);
  337. gamePanel.AddChild(backgroundPanel);
  338. return gamePanel;
  339. }
  340. private Control SetupNextBox(Texture panelTex)
  341. {
  342. var previewBack = new StyleBoxTexture
  343. {
  344. Texture = panelTex,
  345. Modulate = Color.FromHex("#4a4a51")
  346. };
  347. previewBack.SetPatchMargin(StyleBox.Margin.All, 10);
  348. var grid = new GridContainer
  349. {
  350. Columns = 1,
  351. HorizontalExpand = true,
  352. SizeFlagsStretchRatio = 20
  353. };
  354. var nextBlockPanel = new PanelContainer
  355. {
  356. PanelOverride = previewBack,
  357. MinSize = BlockSize * 6.5f,
  358. HorizontalAlignment = HAlignment.Left,
  359. VerticalAlignment = VAlignment.Top
  360. };
  361. var nextCenterContainer = new CenterContainer();
  362. _nextBlockGrid = new GridContainer
  363. {
  364. HSeparationOverride = 1,
  365. VSeparationOverride = 1
  366. };
  367. nextCenterContainer.AddChild(_nextBlockGrid);
  368. nextBlockPanel.AddChild(nextCenterContainer);
  369. grid.AddChild(nextBlockPanel);
  370. grid.AddChild(new Label { Text = Loc.GetString("blockgame-menu-label-next"), Align = Label.AlignMode.Center });
  371. return grid;
  372. }
  373. private Control SetupHoldBox(Texture panelTex)
  374. {
  375. var previewBack = new StyleBoxTexture
  376. {
  377. Texture = panelTex,
  378. Modulate = Color.FromHex("#4a4a51")
  379. };
  380. previewBack.SetPatchMargin(StyleBox.Margin.All, 10);
  381. var grid = new GridContainer
  382. {
  383. Columns = 1,
  384. HorizontalExpand = true,
  385. SizeFlagsStretchRatio = 20
  386. };
  387. var holdBlockPanel = new PanelContainer
  388. {
  389. PanelOverride = previewBack,
  390. MinSize = BlockSize * 6.5f,
  391. HorizontalAlignment = HAlignment.Left,
  392. VerticalAlignment = VAlignment.Top
  393. };
  394. var holdCenterContainer = new CenterContainer();
  395. _holdBlockGrid = new GridContainer
  396. {
  397. HSeparationOverride = 1,
  398. VSeparationOverride = 1
  399. };
  400. holdCenterContainer.AddChild(_holdBlockGrid);
  401. holdBlockPanel.AddChild(holdCenterContainer);
  402. grid.AddChild(holdBlockPanel);
  403. grid.AddChild(new Label { Text = Loc.GetString("blockgame-menu-label-hold"), Align = Label.AlignMode.Center });
  404. return grid;
  405. }
  406. protected override void KeyboardFocusExited()
  407. {
  408. if (!IsOpen)
  409. return;
  410. if (_gameOver)
  411. return;
  412. TryPause();
  413. }
  414. private void TryPause()
  415. {
  416. OnAction?.Invoke(BlockGamePlayerAction.Pause);
  417. }
  418. public void SetStarted()
  419. {
  420. _gameOver = false;
  421. _unpauseButton.Visible = true;
  422. _unpauseButtonMargin.Visible = true;
  423. }
  424. public void SetScreen(BlockGameMessages.BlockGameScreen screen)
  425. {
  426. if (_gameOver)
  427. return;
  428. switch (screen)
  429. {
  430. case BlockGameMessages.BlockGameScreen.Game:
  431. GrabKeyboardFocus();
  432. CloseMenus();
  433. _pauseButton.Disabled = !_isPlayer;
  434. break;
  435. case BlockGameMessages.BlockGameScreen.Pause:
  436. //ReleaseKeyboardFocus();
  437. CloseMenus();
  438. _mainPanel.AddChild(_menuRootContainer);
  439. _pauseButton.Disabled = true;
  440. break;
  441. case BlockGameMessages.BlockGameScreen.Gameover:
  442. _gameOver = true;
  443. _pauseButton.Disabled = true;
  444. //ReleaseKeyboardFocus();
  445. CloseMenus();
  446. _mainPanel.AddChild(_gameOverRootContainer);
  447. break;
  448. case BlockGameMessages.BlockGameScreen.Highscores:
  449. //ReleaseKeyboardFocus();
  450. CloseMenus();
  451. _mainPanel.AddChild(_highscoresRootContainer);
  452. break;
  453. }
  454. }
  455. private void CloseMenus()
  456. {
  457. if (_mainPanel.Children.Contains(_menuRootContainer))
  458. _mainPanel.RemoveChild(_menuRootContainer);
  459. if (_mainPanel.Children.Contains(_gameOverRootContainer))
  460. _mainPanel.RemoveChild(_gameOverRootContainer);
  461. if (_mainPanel.Children.Contains(_highscoresRootContainer))
  462. _mainPanel.RemoveChild(_highscoresRootContainer);
  463. }
  464. public void SetGameoverInfo(int amount, int? localPlacement, int? globalPlacement)
  465. {
  466. var globalPlacementText = globalPlacement == null ? "-" : $"#{globalPlacement}";
  467. var localPlacementText = localPlacement == null ? "-" : $"#{localPlacement}";
  468. _finalScoreLabel.Text =
  469. Loc.GetString("blockgame-menu-gameover-info",
  470. ("global", globalPlacementText),
  471. ("local", localPlacementText),
  472. ("points", amount));
  473. }
  474. public void UpdatePoints(int points)
  475. {
  476. _pointsLabel.Text = Loc.GetString("blockgame-menu-label-points", ("points", points));
  477. }
  478. public void UpdateLevel(int level)
  479. {
  480. _levelLabel.Text = Loc.GetString("blockgame-menu-label-level", ("level", level + 1));
  481. }
  482. public void UpdateHighscores(List<BlockGameMessages.HighScoreEntry> localHighscores,
  483. List<BlockGameMessages.HighScoreEntry> globalHighscores)
  484. {
  485. var localHighscoreText = new StringBuilder(Loc.GetString("blockgame-menu-text-station") + "\n");
  486. var globalHighscoreText = new StringBuilder(Loc.GetString("blockgame-menu-text-nanotrasen") + "\n");
  487. for (var i = 0; i < 5; i++)
  488. {
  489. localHighscoreText.AppendLine(localHighscores.Count > i
  490. ? $"#{i + 1}: {localHighscores[i].Name} - {localHighscores[i].Score}"
  491. : $"#{i + 1}: ??? - 0");
  492. globalHighscoreText.AppendLine(globalHighscores.Count > i
  493. ? $"#{i + 1}: {globalHighscores[i].Name} - {globalHighscores[i].Score}"
  494. : $"#{i + 1}: ??? - 0");
  495. }
  496. _localHighscoresLabel.Text = localHighscoreText.ToString();
  497. _globalHighscoresLabel.Text = globalHighscoreText.ToString();
  498. }
  499. protected override void KeyBindDown(GUIBoundKeyEventArgs args)
  500. {
  501. base.KeyBindDown(args);
  502. if (!_isPlayer || args.Handled)
  503. return;
  504. else if (args.Function == ContentKeyFunctions.ArcadeLeft)
  505. OnAction?.Invoke(BlockGamePlayerAction.StartLeft);
  506. else if (args.Function == ContentKeyFunctions.ArcadeRight)
  507. OnAction?.Invoke(BlockGamePlayerAction.StartRight);
  508. else if (args.Function == ContentKeyFunctions.ArcadeUp)
  509. OnAction?.Invoke(BlockGamePlayerAction.Rotate);
  510. else if (args.Function == ContentKeyFunctions.Arcade3)
  511. OnAction?.Invoke(BlockGamePlayerAction.CounterRotate);
  512. else if (args.Function == ContentKeyFunctions.ArcadeDown)
  513. OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart);
  514. else if (args.Function == ContentKeyFunctions.Arcade2)
  515. OnAction?.Invoke(BlockGamePlayerAction.Hold);
  516. else if (args.Function == ContentKeyFunctions.Arcade1)
  517. OnAction?.Invoke(BlockGamePlayerAction.Harddrop);
  518. }
  519. protected override void KeyBindUp(GUIBoundKeyEventArgs args)
  520. {
  521. base.KeyBindUp(args);
  522. if (!_isPlayer || args.Handled)
  523. return;
  524. else if (args.Function == ContentKeyFunctions.ArcadeLeft)
  525. OnAction?.Invoke(BlockGamePlayerAction.EndLeft);
  526. else if (args.Function == ContentKeyFunctions.ArcadeRight)
  527. OnAction?.Invoke(BlockGamePlayerAction.EndRight);
  528. else if (args.Function == ContentKeyFunctions.ArcadeDown)
  529. OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd);
  530. }
  531. public void UpdateNextBlock(BlockGameBlock[] blocks)
  532. {
  533. _nextBlockGrid.RemoveAllChildren();
  534. if (blocks.Length == 0)
  535. return;
  536. var columnCount = blocks.Max(b => b.Position.X) + 1;
  537. var rowCount = blocks.Max(b => b.Position.Y) + 1;
  538. _nextBlockGrid.Columns = columnCount;
  539. for (var y = 0; y < rowCount; y++)
  540. {
  541. for (var x = 0; x < columnCount; x++)
  542. {
  543. var c = GetColorForPosition(blocks, x, y);
  544. _nextBlockGrid.AddChild(new PanelContainer
  545. {
  546. PanelOverride = new StyleBoxFlat { BackgroundColor = c },
  547. MinSize = BlockSize,
  548. RectDrawClipMargin = 0
  549. });
  550. }
  551. }
  552. }
  553. public void UpdateHeldBlock(BlockGameBlock[] blocks)
  554. {
  555. _holdBlockGrid.RemoveAllChildren();
  556. if (blocks.Length == 0)
  557. return;
  558. var columnCount = blocks.Max(b => b.Position.X) + 1;
  559. var rowCount = blocks.Max(b => b.Position.Y) + 1;
  560. _holdBlockGrid.Columns = columnCount;
  561. for (var y = 0; y < rowCount; y++)
  562. {
  563. for (var x = 0; x < columnCount; x++)
  564. {
  565. var c = GetColorForPosition(blocks, x, y);
  566. _holdBlockGrid.AddChild(new PanelContainer
  567. {
  568. PanelOverride = new StyleBoxFlat { BackgroundColor = c },
  569. MinSize = BlockSize,
  570. RectDrawClipMargin = 0
  571. });
  572. }
  573. }
  574. }
  575. public void UpdateBlocks(BlockGameBlock[] blocks)
  576. {
  577. _gameGrid.RemoveAllChildren();
  578. for (var y = 0; y < 20; y++)
  579. {
  580. for (var x = 0; x < 10; x++)
  581. {
  582. var c = GetColorForPosition(blocks, x, y);
  583. _gameGrid.AddChild(new PanelContainer
  584. {
  585. PanelOverride = new StyleBoxFlat { BackgroundColor = c },
  586. MinSize = BlockSize,
  587. RectDrawClipMargin = 0
  588. });
  589. }
  590. }
  591. }
  592. private static Color GetColorForPosition(BlockGameBlock[] blocks, int x, int y)
  593. {
  594. var c = Color.Transparent;
  595. var matchingBlock = blocks.FirstOrNull(b => b.Position.X == x && b.Position.Y == y);
  596. if (matchingBlock.HasValue)
  597. {
  598. c = BlockGameBlock.ToColor(matchingBlock.Value.GameBlockColor);
  599. }
  600. return c;
  601. }
  602. }
  603. }