Renderování textu, jumpscary, win a lose screen

This commit is contained in:
Perry 2026-03-09 20:05:21 +01:00
parent 9bfe63a166
commit e6128dc9f5
21 changed files with 360 additions and 84 deletions

View file

@ -5,8 +5,10 @@ using System.Runtime.CompilerServices;
using FNAF_Clone.Map;
using GlobalClassLib;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MonoGameLibrary;
using MonoGameLibrary.Graphics;
using MonoGameLibrary.Input;
namespace FNAF_Clone.GUI;
@ -15,45 +17,57 @@ public class UIManager {
public static class ScreenTypes {
public const string OFFICE = "office";
public const string CAMERAS = "monitor";
public const string OVERLAY = "overlay";
public const string WIN = "win";
public const string LOSE = "lose";
}
private static Screen officeScreen = new(ScreenTypes.OFFICE);
private static Screen monitorScreen = new(ScreenTypes.CAMERAS);
private static Screen overlayScreen = new(ScreenTypes.OVERLAY);
private static Screen winScreen = new(ScreenTypes.WIN);
private static Screen loseScreen = new(ScreenTypes.LOSE);
private static TextureAtlas testAtlas;
private static TextureAtlas officeAtlas;
private static TextureAtlas monitorAtlas;
public static TextureAtlas enemyAtlas;
public static TextureAtlas OfficeAtlas{ get; private set; }
public static TextureAtlas MonitorAtlas{ get; private set; }
public static TextureAtlas EnemyAtlas{ get; private set; }
public static SpriteFont PixelMonoFont{ get; private set; }
public static int GlobalPixelMultiplier{ get; private set; }
private Dictionary<(int, int), UIElement> doorElements = new();
// private Dictionary<(int, int), UIElement> doorElements = new();
private static Dictionary<int, UIElement> enemyElements = new();
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");
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");
testAtlas = TextureAtlas.FromFile(Core.content, "images/testBlocks-definition.xml"); // TODO: move this to its own method
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");
Screen.AddScreens([officeScreen, monitorScreen]);
Screen.AddScreens([officeScreen, monitorScreen, overlayScreen, winScreen, loseScreen]);
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)));
officeScreen.AddElement("office_right", new UIElement([officeAtlas[5], officeAtlas[2]], new Point(440, 0)));
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)));
officeScreen.AddElement("office_right", new UIElement([OfficeAtlas[5], OfficeAtlas[2]], new Point(440, 0)));
// officeScreen.AddElement("test",
// new UIElement(testAtlas[0], Point.Zero)
// {Pressable = true, OnMousePress = () => Console.WriteLine("Pressed!")}
// );
monitorScreen.AddElement("screen", new UIElement(monitorAtlas[0], Point.Zero));
monitorScreen.AddElement("view-frame", new UIElement(monitorAtlas[1], new Point(62, 55)));
monitorScreen.AddElement("map-frame", new UIElement(monitorAtlas[2], new Point(334, 135)));
monitorScreen.AddElement("map", new UIElement(monitorAtlas[3], new Point(334, 135)));
monitorScreen.AddElement("screen", new UIElement(MonitorAtlas[0], Point.Zero));
monitorScreen.AddElement("view-frame", new UIElement(MonitorAtlas[1], new Point(62, 55)));
monitorScreen.AddElement("map-frame", new UIElement(MonitorAtlas[2], new Point(334, 135)));
monitorScreen.AddElement("map", new UIElement(MonitorAtlas[3], new Point(334, 135)));
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++){
@ -70,9 +84,16 @@ 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));
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]);
}
@ -86,21 +107,26 @@ public class UIManager {
int targetId = door.Tiles.tile1.GridPosition.y > door.Tiles.tile2.GridPosition.y ? door.Tiles.tile1.Id : door.Tiles.tile2.Id;
UIElement tile = monitorScreen["room"+targetId];
monitorScreen.AddElement("door"+Math.Max(door.Tiles.tile1.Id, door.Tiles.tile2.Id)+"-"+Math.Min(door.Tiles.tile1.Id, door.Tiles.tile2.Id), new UIElement([monitorAtlas[5], monitorAtlas[6]], tile.Bounds.Item1));
monitorScreen.AddElement("door"+Math.Max(door.Tiles.tile1.Id, door.Tiles.tile2.Id)+"-"+Math.Min(door.Tiles.tile1.Id, door.Tiles.tile2.Id), new UIElement([MonitorAtlas[5], MonitorAtlas[6]], tile.Bounds.Item1));
}
}
monitorScreen.AddElement("p1-office-door-left", new UIElement([monitorAtlas[7], monitorAtlas[8]], new Point(400, 272)));
monitorScreen.AddElement("p1-office-door-centre", new UIElement([monitorAtlas[9], monitorAtlas[10]], new Point(400, 272)));
monitorScreen.AddElement("p1-office-door-right", new UIElement([monitorAtlas[11], monitorAtlas[12]], new Point(400, 272)));
monitorScreen.AddElement("p2-office-door-right", new UIElement([monitorAtlas[13], monitorAtlas[14]], new Point(400, 144)));
monitorScreen.AddElement("p2-office-door-centre", new UIElement([monitorAtlas[15], monitorAtlas[16]], new Point(400, 144)));
monitorScreen.AddElement("p2-office-door-left", new UIElement([monitorAtlas[17], monitorAtlas[18]], new Point(400, 144)));
monitorScreen.AddElement("p1-office-door-left", new UIElement([MonitorAtlas[7], MonitorAtlas[8]], new Point(400, 272)));
monitorScreen.AddElement("p1-office-door-centre", new UIElement([MonitorAtlas[9], MonitorAtlas[10]], new Point(400, 272)));
monitorScreen.AddElement("p1-office-door-right", new UIElement([MonitorAtlas[11], MonitorAtlas[12]], new Point(400, 272)));
monitorScreen.AddElement("p2-office-door-right", new UIElement([MonitorAtlas[13], MonitorAtlas[14]], new Point(400, 144)));
monitorScreen.AddElement("p2-office-door-centre", new UIElement([MonitorAtlas[15], MonitorAtlas[16]], new Point(400, 144)));
monitorScreen.AddElement("p2-office-door-left", new UIElement([MonitorAtlas[17], MonitorAtlas[18]], new Point(400, 144)));
}
public static void AddEnemySprite(int id, UIElement sprite) {
public static void AddEnemySprite(int id, UIElement sprite, UIElement jumpscareSprite = null) {
monitorScreen.AddElement($"enemy{id}", sprite);
if (jumpscareSprite != null){
officeScreen.AddElement($"enemy{id}-jumpscare", jumpscareSprite);
jumpscareSprite.Active = false;
jumpscareSprite.Visible = false;
}
enemyElements.Add(id, sprite);
sprite.Visible = false;
}
@ -174,6 +200,30 @@ public class UIManager {
monitorScreen["eye-opponent"].SetPosition(monitorScreen["room"+id].Bounds.Item1);
}
public static void Jumpscare(ClientEnemy enemy) {
Screen.SetScreen(ScreenTypes.OFFICE);
enemy.JumpscareSprite.Play();
timerElement.Stop();
// UIElement jumpscareElement = enemy.Sprite.Clone();
// jumpscareElement.ScaleMultiplier = 2;
// jumpscareElement.SetPosition(new Point(0, 0));
// officeScreen.AddElement("jumpscare", jumpscareElement);
}
public static void ShowVictoryScreen() {
Screen.SetScreen(ScreenTypes.WIN);
Screen.DisableOverlay();
CommandManager.AllowInput(false);
}
public static void ShowDeathScreen() {
Screen.SetScreen(ScreenTypes.LOSE);
Screen.DisableOverlay();
CommandManager.AllowInput(false);
}
// private static Point GetRoomUIPos((int x, int y) pos) {
// return new Point(336 + (32 * pos.x), 144 + (32 * pos.y));
// }