diff --git a/FNAF_Clone/Client.cs b/FNAF_Clone/Client.cs index c759a7d..2620ec0 100644 --- a/FNAF_Clone/Client.cs +++ b/FNAF_Clone/Client.cs @@ -1,6 +1,7 @@ using System; using System.Net; using System.Net.Sockets; +using FNAF_Clone.GUI; using LiteNetLib; using LiteNetLib.Utils; using PacketLib; @@ -90,10 +91,12 @@ public class Client { break; case 3: // toggle cam Player.state.monitorUp = e.Args[1] == 1; + UIManager.ChangeMonitorState(e.Args[1] == 1); Console.WriteLine($"E: Player {e.Args[0]} toggled monitor {(e.Args[1] == 0 ? "off" : "on")}"); break; case 4: // toggle door Player.state.doorStates[e.Args[1]] = e.Args[2] == 1; + UIManager.ChangeDoorState(e.Args[1], e.Args[2] == 1); Console.WriteLine($"E: Player {e.Args[0]} {(e.Args[2] == 1 ? "closed" : "opened")} door {e.Args[1]}"); break; case -1: // movement diff --git a/FNAF_Clone/CommandManager.cs b/FNAF_Clone/CommandManager.cs index ee41efb..2f77446 100644 --- a/FNAF_Clone/CommandManager.cs +++ b/FNAF_Clone/CommandManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using FNAF_Clone.GUI; using Microsoft.Xna.Framework.Input; using MonoGameLibrary.Input; using PacketLib; @@ -8,10 +9,10 @@ namespace FNAF_Clone; public class CommandManager { private static (string label, Keys key, Action action)[] keybinds = [ - ("Toggle Camera", Keys.S, ToggleCamera), - ("Toggle left door", Keys.D1, ToggleDoorLeft), - ("Toggle centre door", Keys.D2, ToggleDoorCentre), - ("Toggle right door", Keys.D3, ToggleDoorRight) + ("Toggle Camera", Keys.Space, SendToggleCamera), + ("Toggle left door", Keys.A, ToggleDoorLeft), + ("Toggle centre door", Keys.W, ToggleDoorCentre), + ("Toggle right door", Keys.D, ToggleDoorRight) ]; @@ -21,15 +22,19 @@ public class CommandManager { Array.ForEach(keybinds, tuple => InputManager.AddListener(tuple.label, tuple.key, () => tuple.action(), InputTiming.PRESS, toggleCamHook)); } - private static void ToggleCamera() { + private static void SendToggleCamera() { Client.SendCommands([PlayerCommand.TOGGLE_MONITOR()]); } - private static void ToggleDoorLeft() => ToggleDoor(0); - private static void ToggleDoorCentre() => ToggleDoor(1); - private static void ToggleDoorRight() => ToggleDoor(2); + private static void ToggleDoorLeft() => SendToggleDoor(0); + private static void ToggleDoorCentre() => SendToggleDoor(1); + private static void ToggleDoorRight() => SendToggleDoor(2); - private static void ToggleDoor(int id) { + private static void SendToggleDoor(int id) { + if (Screen.CurrentScreen.Label == UIManager.ScreenTypes.CAMERAS){ + //TODO: camera doors + return; + } Client.SendCommands([PlayerCommand.TOGGLE_DOOR_OFFICE(id)]); } } \ No newline at end of file diff --git a/FNAF_Clone/Content/Content.mgcb b/FNAF_Clone/Content/Content.mgcb index 9060f47..261666d 100644 --- a/FNAF_Clone/Content/Content.mgcb +++ b/FNAF_Clone/Content/Content.mgcb @@ -13,6 +13,36 @@ #---------------------------------- Content ---------------------------------# +#begin images/monitor-definition.xml +/copy:images/monitor-definition.xml + +#begin images/office-definition.xml +/copy:images/office-definition.xml + +#begin images/SpriteSheet_monitor.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:images/SpriteSheet_monitor.png + +#begin images/SpriteSheet_office.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:images/SpriteSheet_office.png + #begin images/SpriteSheet_testBlocks.png /importer:TextureImporter /processor:TextureProcessor diff --git a/FNAF_Clone/Content/images/SpriteSheet_monitor.png b/FNAF_Clone/Content/images/SpriteSheet_monitor.png new file mode 100644 index 0000000..b673913 Binary files /dev/null and b/FNAF_Clone/Content/images/SpriteSheet_monitor.png differ diff --git a/FNAF_Clone/Content/images/SpriteSheet_office.png b/FNAF_Clone/Content/images/SpriteSheet_office.png new file mode 100644 index 0000000..057c2db Binary files /dev/null and b/FNAF_Clone/Content/images/SpriteSheet_office.png differ diff --git a/FNAF_Clone/Content/images/monitor-definition.xml b/FNAF_Clone/Content/images/monitor-definition.xml new file mode 100644 index 0000000..1604fef --- /dev/null +++ b/FNAF_Clone/Content/images/monitor-definition.xml @@ -0,0 +1,12 @@ + + + images/SpriteSheet_monitor + + + + + + + + + diff --git a/FNAF_Clone/Content/images/office-definition.xml b/FNAF_Clone/Content/images/office-definition.xml new file mode 100755 index 0000000..09f8b3f --- /dev/null +++ b/FNAF_Clone/Content/images/office-definition.xml @@ -0,0 +1,13 @@ + + + images/SpriteSheet_office + + + + + + + + + + diff --git a/FNAF_Clone/FNAF_Clone.csproj b/FNAF_Clone/FNAF_Clone.csproj index 7c07fc9..83748ba 100644 --- a/FNAF_Clone/FNAF_Clone.csproj +++ b/FNAF_Clone/FNAF_Clone.csproj @@ -5,6 +5,7 @@ Major false false + 14 app.manifest diff --git a/FNAF_Clone/GUI/PointExtensions.cs b/FNAF_Clone/GUI/PointExtensions.cs new file mode 100644 index 0000000..529bd48 --- /dev/null +++ b/FNAF_Clone/GUI/PointExtensions.cs @@ -0,0 +1,7 @@ +using Microsoft.Xna.Framework; + +namespace FNAF_Clone.GUI; + +public static class PointExtensions { + public static Point MultiplyByScalar(this Point point, int scalar) => new(point.X * scalar, point.Y * scalar); +} \ No newline at end of file diff --git a/FNAF_Clone/GUI/Screen.cs b/FNAF_Clone/GUI/Screen.cs index 962a742..09172d7 100644 --- a/FNAF_Clone/GUI/Screen.cs +++ b/FNAF_Clone/GUI/Screen.cs @@ -11,9 +11,9 @@ public class Screen { public static Dictionary Screens = new(); public static Screen CurrentScreen{ get; private set; } - public static void AddScreens((string id, Screen screen)[] screens) { - foreach (var tuple in screens){ - Screens.Add(tuple.id, tuple.screen); + public static void AddScreens(Screen[] screens) { + foreach (var screen in screens){ + Screens.Add(screen.Label, screen); } } public static void AddScreen(string id, Screen screen, bool activate = false) { @@ -29,28 +29,24 @@ public class Screen { public static void RemoveScreen(string id) { Screens.Remove(id); } - - public enum ScreenType { - MAIN_MENU, - OFFICE, - CAMERAS - } - - - public ScreenType Type{ get; private set; } + + + public string Label; private Dictionary elements = new(); public bool Active { get; private set; } = false; private InputListenerHook mouseInputHook = new(true); - public Screen(ScreenType type) { - Type = type; + public Screen(string label) { + Label = label; InputManager.AddListener(InputManager.MouseButton.LEFT, () => ProcessMouseInput(InputManager.MouseState), InputTiming.PRESS, mouseInputHook); } - public Screen(ScreenType type, Dictionary elements) { + public Screen(string label, Dictionary elements) { this.elements = elements; - Type = type; + Label = label; } + + public UIElement this[string id] => elements[id]; public void AddElement(string id, UIElement element) { elements.Add(id, element); diff --git a/FNAF_Clone/GUI/UIElement.cs b/FNAF_Clone/GUI/UIElement.cs index bef026e..1160e38 100644 --- a/FNAF_Clone/GUI/UIElement.cs +++ b/FNAF_Clone/GUI/UIElement.cs @@ -1,21 +1,56 @@ using System; +using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MonoGameLibrary; using MonoGameLibrary.Graphics; using MonoGameLibrary.Input; namespace FNAF_Clone.GUI; public class UIElement { + public bool Active { get; set; } = false; public bool Pressable { get; set; } = false; private (Point, Point) bounds; // TODO: Change this to support non-rectangular hitboxes - private TextureRegion texture; + private List textures = new(); + private int currentTextureId = 0; + private float _scaleMultiplier = 1; + public float ScaleMultiplier{ + get{ + return _scaleMultiplier; + } + set{ + _scaleMultiplier = value; + LoadPixelScaleMultiplier(); + } + } + private float pixelScaleMultiplier = 1; + private void LoadPixelScaleMultiplier() { + pixelScaleMultiplier = UIManager.GlobalPixelMultiplier * _scaleMultiplier; + } + public UIElement(TextureRegion texture, Point position) { - this.texture = texture; + textures.Add(texture); bounds = (position, position + new Point(texture.Width, texture.Height)); + LoadPixelScaleMultiplier(); + } + public UIElement(TextureRegion[] textures, Point position) { + this.textures.AddRange(textures); + bounds = (position, position + new Point(textures[0].Width, textures[0].Height)); + LoadPixelScaleMultiplier(); + } + + + public void SetTexture(int textureId) { + if (textureId >= textures.Count){ + Console.WriteLine($"WARNING: TEXTURE {textureId} OUT OF BOUNDS"); + return; + } + + currentTextureId = textureId; } public void Update() { @@ -35,6 +70,7 @@ public class UIElement { public virtual void OnMouseHold() { } public void Draw(SpriteBatch spriteBatch) { - texture.Draw(spriteBatch, bounds.Item1.ToVector2(), Color.White); + textures[currentTextureId].Draw(spriteBatch, bounds.Item1.ToVector2(), Color.White, 0, Vector2.Zero, pixelScaleMultiplier, SpriteEffects.None, 0); + // texture.Draw(spriteBatch, bounds.Item1.ToVector2(), Color.White); } } \ No newline at end of file diff --git a/FNAF_Clone/GUI/UIManager.cs b/FNAF_Clone/GUI/UIManager.cs new file mode 100644 index 0000000..eeede6a --- /dev/null +++ b/FNAF_Clone/GUI/UIManager.cs @@ -0,0 +1,64 @@ +using Microsoft.Xna.Framework; +using MonoGameLibrary; +using MonoGameLibrary.Graphics; + +namespace FNAF_Clone.GUI; + +public class UIManager { + + public static class ScreenTypes { + public const string OFFICE = "office"; + public const string CAMERAS = "monitor"; + } + + private static Screen officeScreen = new(ScreenTypes.OFFICE); + private static Screen monitorScreen = new(ScreenTypes.CAMERAS); + + private static TextureAtlas testAtlas; + private static TextureAtlas officeAtlas; + private static TextureAtlas monitorAtlas; + public static int GlobalPixelMultiplier{ get; private set; } + + 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"); + + Screen.AddScreens([officeScreen, monitorScreen]); + Screen.SetScreen(ScreenTypes.OFFICE); + + // officeScreen.AddElement("test", + // new UIElement(testAtlas[0], Point.Zero) + // {Pressable = true, OnMousePress = () => Console.WriteLine("Pressed!")} + // ); + + 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).MultiplyByScalar(GlobalPixelMultiplier))); + officeScreen.AddElement("office_right", new UIElement([officeAtlas[5], officeAtlas[2]], new Point(440, 0).MultiplyByScalar(GlobalPixelMultiplier))); + + monitorScreen.AddElement("screen", new UIElement(monitorAtlas[0], Point.Zero)); + monitorScreen.AddElement("view-frame", new UIElement(monitorAtlas[1], new Point(62, 55).MultiplyByScalar(GlobalPixelMultiplier))); + monitorScreen.AddElement("map-frame", new UIElement(monitorAtlas[2], new Point(334, 135).MultiplyByScalar(GlobalPixelMultiplier))); + monitorScreen.AddElement("map", new UIElement(monitorAtlas[3], new Point(334, 135).MultiplyByScalar(GlobalPixelMultiplier))); + } + + public static void ChangeDoorState(int id, bool state) { + switch (id){ + case 0: + officeScreen["office_left"].SetTexture(state ? 1 : 0); + break; + case 1: + officeScreen["office_centre"].SetTexture(state ? 1 : 0); + break; + case 2: + officeScreen["office_right"].SetTexture(state ? 1 : 0); + break; + } + } + + public static void ChangeMonitorState(bool state) { + Screen.SetScreen(state ? ScreenTypes.CAMERAS : ScreenTypes.OFFICE); + } +} \ No newline at end of file diff --git a/FNAF_Clone/GameMain.cs b/FNAF_Clone/GameMain.cs index b6076c9..e643bb8 100644 --- a/FNAF_Clone/GameMain.cs +++ b/FNAF_Clone/GameMain.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using FNAF_Clone.GUI; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -9,13 +10,11 @@ using MonoGameLibrary.Input; namespace FNAF_Clone; -public class GameMain() : Core("fnafkooo", 640, 360, false) { +public class GameMain() : Core("fnafkooo", 1920, 1080, false) { // private GraphicsDeviceManager _graphics; // private SpriteBatch _spriteBatch; - private Screen officeScreen = new(Screen.ScreenType.OFFICE); - private TextureAtlas testAtlas; protected override void Initialize() { Client.Connect("127.0.0.1", 9012); @@ -23,19 +22,14 @@ public class GameMain() : Core("fnafkooo", 640, 360, false) { InputManager.AddListener(InputManager.MouseButton.LEFT, (() => Console.WriteLine("LMB pressed at: " + InputManager.MouseState.Position)), InputTiming.PRESS, new InputListenerHook(true)); - base.Initialize(); + + UIManager.InitUI(); } protected override void LoadContent() { // spriteBatch = new SpriteBatch(GraphicsDevice); - testAtlas = TextureAtlas.FromFile(content, "images/testBlocks-definition.xml"); - - Screen.AddScreen("office", officeScreen, true); - officeScreen.AddElement("test", - new UIElement(testAtlas[0], Point.Zero) - {Pressable = true, OnMousePress = () => Console.WriteLine("Pressed!")} - ); + } protected override void Update(GameTime gameTime) { @@ -52,8 +46,8 @@ public class GameMain() : Core("fnafkooo", 640, 360, false) { } protected override void Draw(GameTime gameTime) { - GraphicsDevice.Clear(Color.CornflowerBlue); - spriteBatch.Begin(); + GraphicsDevice.Clear(Color.Black); + spriteBatch.Begin(samplerState:SamplerState.PointClamp); Screen.CurrentScreen.Draw(spriteBatch);