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.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

View file

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

View file

@ -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

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>
<PublishReadyToRun>false</PublishReadyToRun>
<TieredCompilation>false</TieredCompilation>
<LangVersion>14</LangVersion>
</PropertyGroup>
<PropertyGroup>
<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 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) {
@ -30,28 +30,24 @@ public class Screen {
Screens.Remove(id);
}
public enum ScreenType {
MAIN_MENU,
OFFICE,
CAMERAS
}
public ScreenType Type{ get; private set; }
public string Label;
private Dictionary<string, UIElement> 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<string, UIElement> elements) {
public Screen(string label, Dictionary<string, UIElement> 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);
}

View file

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

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.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);