Hlavní menu, synchronizace jmen hráčů. Client hru spustí až ve chvíli kdy dostane správný packet. Oprava bugu v se scalováním UIElementu

This commit is contained in:
Perry 2026-03-11 22:35:30 +01:00
parent e6128dc9f5
commit 7656707177
19 changed files with 315 additions and 53 deletions

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using FNAF_Clone.Map;
using GlobalClassLib;
using Microsoft.Xna.Framework;
@ -20,6 +21,8 @@ public class UIManager {
public const string OVERLAY = "overlay";
public const string WIN = "win";
public const string LOSE = "lose";
public const string MENU = "menu";
public const string LOADING = "loading";
}
private static Screen officeScreen = new(ScreenTypes.OFFICE);
@ -27,6 +30,8 @@ public class UIManager {
private static Screen overlayScreen = new(ScreenTypes.OVERLAY);
private static Screen winScreen = new(ScreenTypes.WIN);
private static Screen loseScreen = new(ScreenTypes.LOSE);
private static Screen menuScreen = new(ScreenTypes.MENU);
private static Screen loadingScreen = new(ScreenTypes.LOADING);
private static TextureAtlas testAtlas;
public static TextureAtlas OfficeAtlas{ get; private set; }
@ -41,19 +46,21 @@ public class UIManager {
private static TimerUIElement timerElement;
private static InputListenerHook monitorSwitchHook;
public static void InitUI() {
GlobalPixelMultiplier = Core.graphicsDevice.Viewport.Height / 360;
testAtlas = TextureAtlas.FromFile(Core.content, "images/testBlocks-definition.xml"); // TODO: move this to its own method
public static void LoadAssets() {
testAtlas = TextureAtlas.FromFile(Core.content, "images/testBlocks-definition.xml");
OfficeAtlas = TextureAtlas.FromFile(Core.content, "images/office-definition.xml");
MonitorAtlas = TextureAtlas.FromFile(Core.content, "images/monitor-definition.xml");
EnemyAtlas = TextureAtlas.FromFile(Core.content, "images/enemies-definition.xml");
PixelMonoFont = Core.content.Load<SpriteFont>("ponderosa");
}
public static void InitUI() {
GlobalPixelMultiplier = Core.graphicsDevice.Viewport.Height / 360;
Screen.AddScreens([officeScreen, monitorScreen, overlayScreen, winScreen, loseScreen]);
Screen.SetScreen(ScreenTypes.OFFICE);
Screen.SetOverlayScreen(ScreenTypes.OVERLAY);
Screen.AddScreens([officeScreen, monitorScreen, overlayScreen, winScreen, loseScreen, menuScreen, loadingScreen]);
// Screen.SetScreen(ScreenTypes.OFFICE);
// Screen.SetOverlayScreen(ScreenTypes.OVERLAY);
officeScreen.AddElement("office_left", new UIElement([OfficeAtlas[3], OfficeAtlas[0]], Point.Zero));
officeScreen.AddElement("office_centre", new UIElement([OfficeAtlas[4], OfficeAtlas[1]], new Point(200, 0)));
@ -69,6 +76,74 @@ public class UIManager {
monitorScreen.AddElement("map-frame", new UIElement(MonitorAtlas[2], new Point(334, 135)));
monitorScreen.AddElement("map", new UIElement(MonitorAtlas[3], new Point(334, 135)));
timerElement = new(new(0, 0), PixelMonoFont);
overlayScreen.AddElement("timer", timerElement);
winScreen.AddElement("win-text", new TextUIElement(new(320, 180), PixelMonoFont, TextUIElement.Alignment.CENTER){Text = "YOU WIN", Color = Color.Green});
loseScreen.AddElement("lose-text", new TextUIElement(new(320, 180), PixelMonoFont, TextUIElement.Alignment.CENTER){Text = "YOU LOSE", Color = Color.Red});
// overlayScreen.AddElement("test", new TextBoxUIElement(PixelMonoFont, Point.Zero, new(200, 100)));
// Main menu
// TextUIElement serverIpLabel = (TextUIElement) menuScreen.AddElement("server-ip-label", new TextUIElement(new (20, 20), PixelMonoFont){Text = "ENTER SERVER IP: ", Color = Color.Gray});
// TextBoxUIElement serverIpTextBox = (TextBoxUIElement)menuScreen.AddElement("server-ip-textbox",
// new TextBoxUIElement(PixelMonoFont,
// new(serverIpLabel.Bounds.Item1.X + (int)serverIpLabel.Measure().X, serverIpLabel.Bounds.Item1.Y),
// new(640, serverIpLabel.Bounds.Item2.Y + (int)serverIpLabel.Measure().Y)));
// serverIpTextBox.OnFocused = () => {
// serverIpTextBox.Color = Color.LightGreen;
// serverIpLabel.Color = Color.DarkGreen;
// };
// serverIpTextBox.OnUnfocused = () => {
// serverIpTextBox.Color = Color.White;
// serverIpLabel.Color = Color.Gray;
// };
MenuInputField usernameField = (MenuInputField)menuScreen.AddElement("username-field", new MenuInputField(PixelMonoFont, new(20, 20), "USERNAME: "));
MenuInputField field = (MenuInputField)menuScreen.AddElement("server-ip-field", new MenuInputField(PixelMonoFont, new(usernameField.Bounds.Item1.X, usernameField.Bounds.Item2.Y + 20), "SERVER IP: ", "127.0.0.1"));
UIElement connectButton = menuScreen.AddElement("server-ip-submit", new TextUIElement(new Point(field.Bounds.Item1.X, field.Bounds.Item2.Y), PixelMonoFont)
{
Text = "CONNECT",
Pressable = true,
OnMousePress = () => {
// string[] input = serverIpTextBox.Text.Split(":");
// if(input.Length != 2 || !int.TryParse(input[0], out var port)) return;
// Client.Connect(input[0], port);
Client.Player.username = usernameField.Text;
Client.Connect(field.Text, 9012);
Screen.SetScreen(ScreenTypes.LOADING);
}
});
menuScreen.AddElement("host-button",
new TextUIElement(new(connectButton.Bounds.Item1.X, connectButton.Bounds.Item2.Y + 30), PixelMonoFont) {Text = "HOST"});
loadingScreen.AddElement("loading-text", new LoadingUIElement(new(320, 180), PixelMonoFont, field.Text));
}
public static void DisplayMainMenu() {
Screen.SetScreen(ScreenTypes.MENU);
CommandManager.AllowGameControls(false);
}
public static void DisplayGameUI() {
Screen.SetScreen(ScreenTypes.OFFICE);
Screen.SetOverlayScreen(ScreenTypes.OVERLAY);
CommandManager.AllowGameControls(true);
UpdateCameras([Client.Player.state.camera]); // in case there is an enemy on the default camera
}
public static void StartTimer() {
timerElement.Start();
}
public static void SpawnMapElements(TileConnectorProjection[] doors) {
for (int i = 0; i < 5; i++){ // NOTE: this loop does y in reverse, y labels are inverted to match server
for (int j = 0; j < 5; j++){
int i1 = i;
@ -87,17 +162,6 @@ public class UIManager {
monitorScreen.AddElement("eye-player", new UIElement(MonitorAtlas[24], monitorScreen["room"+Client.Player.state.camera].Bounds.Item1));
monitorScreen.AddElement("eye-opponent", new UIElement([MonitorAtlas[23], MonitorAtlas[22]], monitorScreen["room"+Client.Opponent.state.camera].Bounds.Item1));
timerElement = new(new(0, 0), PixelMonoFont);
overlayScreen.AddElement("timer", timerElement);
timerElement.Start();
winScreen.AddElement("win-text", new TextUIElement(new(320, 180), PixelMonoFont, TextUIElement.Alignment.CENTER){Text = "YOU WIN", Color = Color.Green});
loseScreen.AddElement("lose-text", new TextUIElement(new(320, 180), PixelMonoFont, TextUIElement.Alignment.CENTER){Text = "YOU LOSE", Color = Color.Red});
UpdateCameras([Client.Player.state.camera]);
}
public static void SpawnDoors(TileConnectorProjection[] doors) {
foreach (var door in doors){
if(door.Type != ConnectorType.DOOR_REMOTE) continue;
@ -198,7 +262,7 @@ public class UIManager {
public static void ChangeCameraOpponent(int id) {
monitorScreen["eye-opponent"].SetPosition(monitorScreen["room"+id].Bounds.Item1);
}
public static void Jumpscare(ClientEnemy enemy) {
@ -214,13 +278,13 @@ public class UIManager {
public static void ShowVictoryScreen() {
Screen.SetScreen(ScreenTypes.WIN);
Screen.DisableOverlay();
CommandManager.AllowInput(false);
CommandManager.AllowGameControls(false);
}
public static void ShowDeathScreen() {
Screen.SetScreen(ScreenTypes.LOSE);
Screen.DisableOverlay();
CommandManager.AllowInput(false);
CommandManager.AllowGameControls(false);
}