Přidány sprity pro kancelář a monitor. Graficky viditelné zavírání a otevírání dveří, zapínání a vypínání monitoru. Podpora pouze pro specifická rozlišení.

This commit is contained in:
Perry 2026-01-26 09:39:17 +01:00
parent 952aae10de
commit 2cd215cc33
13 changed files with 202 additions and 41 deletions

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using FNAF_Clone.GUI;
using LiteNetLib; using LiteNetLib;
using LiteNetLib.Utils; using LiteNetLib.Utils;
using PacketLib; using PacketLib;
@ -90,10 +91,12 @@ public class Client {
break; break;
case 3: // toggle cam case 3: // toggle cam
Player.state.monitorUp = e.Args[1] == 1; 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")}"); Console.WriteLine($"E: Player {e.Args[0]} toggled monitor {(e.Args[1] == 0 ? "off" : "on")}");
break; break;
case 4: // toggle door case 4: // toggle door
Player.state.doorStates[e.Args[1]] = e.Args[2] == 1; 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]}"); Console.WriteLine($"E: Player {e.Args[0]} {(e.Args[2] == 1 ? "closed" : "opened")} door {e.Args[1]}");
break; break;
case -1: // movement case -1: // movement

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using FNAF_Clone.GUI;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using MonoGameLibrary.Input; using MonoGameLibrary.Input;
using PacketLib; using PacketLib;
@ -8,10 +9,10 @@ namespace FNAF_Clone;
public class CommandManager { public class CommandManager {
private static (string label, Keys key, Action action)[] keybinds = [ private static (string label, Keys key, Action action)[] keybinds = [
("Toggle Camera", Keys.S, ToggleCamera), ("Toggle Camera", Keys.Space, SendToggleCamera),
("Toggle left door", Keys.D1, ToggleDoorLeft), ("Toggle left door", Keys.A, ToggleDoorLeft),
("Toggle centre door", Keys.D2, ToggleDoorCentre), ("Toggle centre door", Keys.W, ToggleDoorCentre),
("Toggle right door", Keys.D3, ToggleDoorRight) ("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)); 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()]); Client.SendCommands([PlayerCommand.TOGGLE_MONITOR()]);
} }
private static void ToggleDoorLeft() => ToggleDoor(0); private static void ToggleDoorLeft() => SendToggleDoor(0);
private static void ToggleDoorCentre() => ToggleDoor(1); private static void ToggleDoorCentre() => SendToggleDoor(1);
private static void ToggleDoorRight() => ToggleDoor(2); 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)]); Client.SendCommands([PlayerCommand.TOGGLE_DOOR_OFFICE(id)]);
} }
} }

View file

@ -13,6 +13,36 @@
#---------------------------------- Content ---------------------------------# #---------------------------------- 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 #begin images/SpriteSheet_testBlocks.png
/importer:TextureImporter /importer:TextureImporter
/processor:TextureProcessor /processor:TextureProcessor

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TextureAtlas count="5">
<Texture>images/SpriteSheet_monitor</Texture>
<Regions>
<Region id = "0" name="screen" x="0" y="0" width="640" height="360"/>
<Region id = "1" name="view-frame" x="0" y="360" width="244" height="251"/>
<Region id = "2" name="map-frame" x="244" y="360" width="164" height="171"/>
<Region id = "3" name="map" x="408" y="360" width="164" height="171"/>
<Region id = "4" name="light-button" x="244" y="531" width="36" height="42"/>
</Regions>
</TextureAtlas>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<TextureAtlas count="6">
<Texture>images/SpriteSheet_office</Texture>
<Regions>
<Region id = "0" name="llc" x="0" y="0" width="200" height="360"/>
<Region id = "1" name="lmc" x="200" y="0" width="240" height="360"/>
<Region id = "2" name="lrc" x="440" y="0" width="200" height="360"/>
<Region id = "3" name="llo" x="0" y="360" width="200" height="360"/>
<Region id = "4" name="lmo" x="200" y="360" width="240" height="360"/>
<Region id = "5" name="lro" x="440" y="360" width="200" height="360"/>
</Regions>
</TextureAtlas>

View file

@ -5,6 +5,7 @@
<RollForward>Major</RollForward> <RollForward>Major</RollForward>
<PublishReadyToRun>false</PublishReadyToRun> <PublishReadyToRun>false</PublishReadyToRun>
<TieredCompilation>false</TieredCompilation> <TieredCompilation>false</TieredCompilation>
<LangVersion>14</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>

View file

@ -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);
}

View file

@ -11,9 +11,9 @@ public class Screen {
public static Dictionary<string, Screen> Screens = new(); public static Dictionary<string, Screen> Screens = new();
public static Screen CurrentScreen{ get; private set; } public static Screen CurrentScreen{ get; private set; }
public static void AddScreens((string id, Screen screen)[] screens) { public static void AddScreens(Screen[] screens) {
foreach (var tuple in screens){ foreach (var screen in screens){
Screens.Add(tuple.id, tuple.screen); Screens.Add(screen.Label, screen);
} }
} }
public static void AddScreen(string id, Screen screen, bool activate = false) { public static void AddScreen(string id, Screen screen, bool activate = false) {
@ -29,28 +29,24 @@ public class Screen {
public static void RemoveScreen(string id) { public static void RemoveScreen(string id) {
Screens.Remove(id); Screens.Remove(id);
} }
public enum ScreenType {
MAIN_MENU, public string Label;
OFFICE,
CAMERAS
}
public ScreenType Type{ get; private set; }
private Dictionary<string, UIElement> elements = new(); private Dictionary<string, UIElement> elements = new();
public bool Active { get; private set; } = false; public bool Active { get; private set; } = false;
private InputListenerHook mouseInputHook = new(true); private InputListenerHook mouseInputHook = new(true);
public Screen(ScreenType type) { public Screen(string label) {
Type = type; Label = label;
InputManager.AddListener(InputManager.MouseButton.LEFT, () => ProcessMouseInput(InputManager.MouseState), InputTiming.PRESS, mouseInputHook); InputManager.AddListener(InputManager.MouseButton.LEFT, () => ProcessMouseInput(InputManager.MouseState), InputTiming.PRESS, mouseInputHook);
} }
public Screen(ScreenType type, Dictionary<string, UIElement> elements) { public Screen(string label, Dictionary<string, UIElement> elements) {
this.elements = elements; this.elements = elements;
Type = type; Label = label;
} }
public UIElement this[string id] => elements[id];
public void AddElement(string id, UIElement element) { public void AddElement(string id, UIElement element) {
elements.Add(id, element); elements.Add(id, element);

View file

@ -1,21 +1,56 @@
using System; using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using MonoGameLibrary;
using MonoGameLibrary.Graphics; using MonoGameLibrary.Graphics;
using MonoGameLibrary.Input; using MonoGameLibrary.Input;
namespace FNAF_Clone.GUI; namespace FNAF_Clone.GUI;
public class UIElement { public class UIElement {
public bool Active { get; set; } = false; public bool Active { get; set; } = false;
public bool Pressable { get; set; } = false; public bool Pressable { get; set; } = false;
private (Point, Point) bounds; // TODO: Change this to support non-rectangular hitboxes private (Point, Point) bounds; // TODO: Change this to support non-rectangular hitboxes
private TextureRegion texture; private List<TextureRegion> 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) { public UIElement(TextureRegion texture, Point position) {
this.texture = texture; textures.Add(texture);
bounds = (position, position + new Point(texture.Width, texture.Height)); 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() { public void Update() {
@ -35,6 +70,7 @@ public class UIElement {
public virtual void OnMouseHold() { } public virtual void OnMouseHold() { }
public void Draw(SpriteBatch spriteBatch) { 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);
} }
} }

View file

@ -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);
}
}

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using FNAF_Clone.GUI; using FNAF_Clone.GUI;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
@ -9,13 +10,11 @@ using MonoGameLibrary.Input;
namespace FNAF_Clone; namespace FNAF_Clone;
public class GameMain() : Core("fnafkooo", 640, 360, false) { public class GameMain() : Core("fnafkooo", 1920, 1080, false) {
// private GraphicsDeviceManager _graphics; // private GraphicsDeviceManager _graphics;
// private SpriteBatch _spriteBatch; // private SpriteBatch _spriteBatch;
private Screen officeScreen = new(Screen.ScreenType.OFFICE);
private TextureAtlas testAtlas;
protected override void Initialize() { protected override void Initialize() {
Client.Connect("127.0.0.1", 9012); 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)); InputManager.AddListener(InputManager.MouseButton.LEFT, (() => Console.WriteLine("LMB pressed at: " + InputManager.MouseState.Position)), InputTiming.PRESS, new InputListenerHook(true));
base.Initialize(); base.Initialize();
UIManager.InitUI();
} }
protected override void LoadContent() { protected override void LoadContent() {
// spriteBatch = new SpriteBatch(GraphicsDevice); // 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) { protected override void Update(GameTime gameTime) {
@ -52,8 +46,8 @@ public class GameMain() : Core("fnafkooo", 640, 360, false) {
} }
protected override void Draw(GameTime gameTime) { protected override void Draw(GameTime gameTime) {
GraphicsDevice.Clear(Color.CornflowerBlue); GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(); spriteBatch.Begin(samplerState:SamplerState.PointClamp);
Screen.CurrentScreen.Draw(spriteBatch); Screen.CurrentScreen.Draw(spriteBatch);