added frontend event system
This commit is contained in:
parent
95744e9e33
commit
f2c1886cee
|
|
@ -9,6 +9,8 @@ public class Publisher
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, HashSet<Delegate>> subscribers =
|
private readonly Dictionary<string, HashSet<Delegate>> subscribers =
|
||||||
new();
|
new();
|
||||||
|
private readonly HashSet<string> clientOnlySubscriptions = new();
|
||||||
|
private readonly HashSet<string> serverSubscriptions = new();
|
||||||
private readonly InteractorKind kind;
|
private readonly InteractorKind kind;
|
||||||
|
|
||||||
public Publisher(InteractorKind kind)
|
public Publisher(InteractorKind kind)
|
||||||
|
|
@ -24,20 +26,28 @@ public class Publisher
|
||||||
.GetTypesSafe();
|
.GetTypesSafe();
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
{
|
{
|
||||||
var attrs = type.GetCustomAttributes(typeof(InteractorAttribute), false);
|
var classAttrs = type.GetCustomAttributes(typeof(InteractorAttribute), false);
|
||||||
if (attrs.Length == 0)
|
if (classAttrs.Length == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var methods = type.GetMethods();
|
var methods = type.GetMethods();
|
||||||
foreach (var method in methods)
|
foreach (var method in methods)
|
||||||
{
|
{
|
||||||
var attrs2 = method.GetCustomAttributes(typeof(InteractionAttribute), false);
|
var methodAttrs = method.GetCustomAttributes(typeof(InteractionAttribute), false);
|
||||||
if (attrs2.Length == 0)
|
if (methodAttrs.Length == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var attr = (InteractionAttribute)attrs2[0];
|
var attr = (InteractionAttribute)methodAttrs[0];
|
||||||
|
if (attr.Kind is InteractorKind.Server or InteractorKind.Hybrid)
|
||||||
|
{
|
||||||
|
this.serverSubscriptions.Add(attr.Type);
|
||||||
|
}
|
||||||
|
if (attr.Kind is InteractorKind.Client)
|
||||||
|
{
|
||||||
|
this.clientOnlySubscriptions.Add(attr.Type);
|
||||||
|
}
|
||||||
if (attr.Kind != this.kind && this.kind != InteractorKind.Hybrid)
|
if (attr.Kind != this.kind && this.kind != InteractorKind.Hybrid)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -51,6 +61,7 @@ public class Publisher
|
||||||
this.Subscribe(attr.Type, del);
|
this.Subscribe(attr.Type, del);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.clientOnlySubscriptions.ExceptWith(this.serverSubscriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Subscribe(string type, Delegate callback)
|
private void Subscribe(string type, Delegate callback)
|
||||||
|
|
@ -100,4 +111,14 @@ public class Publisher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsClientOnlyPacket(string type)
|
||||||
|
{
|
||||||
|
return this.clientOnlySubscriptions.Contains(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsServerPacket(string type)
|
||||||
|
{
|
||||||
|
return this.serverSubscriptions.Contains(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using mine2d.backend.data;
|
using mine2d.backend.data;
|
||||||
|
using mine2d.engine;
|
||||||
using mine2d.engine.system.annotations;
|
using mine2d.engine.system.annotations;
|
||||||
using mine2d.state;
|
using mine2d.state;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
@ -7,7 +8,7 @@ using WatsonTcp;
|
||||||
|
|
||||||
namespace mine2d.backend;
|
namespace mine2d.backend;
|
||||||
|
|
||||||
class RemoteBackend : IBackend
|
public class RemoteBackend : IBackend
|
||||||
{
|
{
|
||||||
private WatsonTcpClient client;
|
private WatsonTcpClient client;
|
||||||
private Publisher publisher;
|
private Publisher publisher;
|
||||||
|
|
@ -27,6 +28,10 @@ class RemoteBackend : IBackend
|
||||||
public void ProcessPacket(ValueType packet)
|
public void ProcessPacket(ValueType packet)
|
||||||
{
|
{
|
||||||
this.publisher.Publish(packet);
|
this.publisher.Publish(packet);
|
||||||
|
if (this.publisher.IsClientOnlyPacket(PacketUtils.GetType(packet)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
var json = JsonConvert.SerializeObject(packet);
|
var json = JsonConvert.SerializeObject(packet);
|
||||||
var bytes = Encoding.UTF8.GetBytes(json);
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
this.client.Send(bytes);
|
this.client.Send(bytes);
|
||||||
|
|
@ -53,4 +58,4 @@ class RemoteBackend : IBackend
|
||||||
};
|
};
|
||||||
this.client.Connect();
|
this.client.Connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ public static class TypeExtensions
|
||||||
{
|
{
|
||||||
var missingTypes = e.Types
|
var missingTypes = e.Types
|
||||||
.Where(t => typeArguments.Contains(t) && t != null);
|
.Where(t => typeArguments.Contains(t) && t != null);
|
||||||
|
|
||||||
throw new Exception($"Failed to make generic type {type} with arguments {string.Join(", ", missingTypes)}", e);
|
throw new ArgumentException($"Failed to make generic type {type} with arguments {string.Join(", ", missingTypes)}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ namespace mine2d.engine.system;
|
||||||
|
|
||||||
public enum EventPriority
|
public enum EventPriority
|
||||||
{
|
{
|
||||||
Lowest = 0,
|
Lowest = -2,
|
||||||
Low = 1,
|
Low = -1,
|
||||||
Normal = 2,
|
Normal = 0,
|
||||||
High = 3,
|
High = 1,
|
||||||
Highest = 4,
|
Highest = 2,
|
||||||
Important = 5,
|
Important = 3,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Mine2d.engine.system;
|
||||||
|
|
||||||
|
public enum EventType
|
||||||
|
{
|
||||||
|
Quit,
|
||||||
|
MouseMotion,
|
||||||
|
MouseButtonDown,
|
||||||
|
MouseButtonUp,
|
||||||
|
KeyDown,
|
||||||
|
KeyUp,
|
||||||
|
WindowResize,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using mine2d.engine.system;
|
||||||
|
|
||||||
|
namespace Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
|
public class EventListenerAttribute : Attribute
|
||||||
|
{
|
||||||
|
public EventType Type { get; }
|
||||||
|
public EventPriority Priority { get; set; }
|
||||||
|
|
||||||
|
public EventListenerAttribute(EventType type)
|
||||||
|
{
|
||||||
|
this.Type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
using mine2d.core.extensions;
|
||||||
|
using mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend;
|
||||||
|
|
||||||
|
internal struct EventAction
|
||||||
|
{
|
||||||
|
public EventPriority priority;
|
||||||
|
public Delegate del;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EventPublisher
|
||||||
|
{
|
||||||
|
private readonly Dictionary<EventType, List<EventAction>> eventListeners = new();
|
||||||
|
|
||||||
|
public EventPublisher()
|
||||||
|
{
|
||||||
|
this.Scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Scan()
|
||||||
|
{
|
||||||
|
var types = this.GetType().Assembly
|
||||||
|
.GetTypesSafe()
|
||||||
|
.Where(t => t.Namespace != null && t.Namespace.StartsWith("Mine2d.frontend.events", StringComparison.Ordinal));
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
var methods = type.GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttributes(typeof(EventListenerAttribute), false).Length > 0);
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
var attributes = method.GetCustomAttributes(typeof(EventListenerAttribute), false);
|
||||||
|
foreach (var eventType in from EventListenerAttribute attribute in attributes
|
||||||
|
let eventType = attribute.Type
|
||||||
|
select eventType)
|
||||||
|
{
|
||||||
|
if (!this.eventListeners.ContainsKey(eventType))
|
||||||
|
{
|
||||||
|
this.eventListeners.Add(eventType, new List<EventAction>());
|
||||||
|
}
|
||||||
|
|
||||||
|
var del = method.GetParameters().Length == 0 ?
|
||||||
|
Delegate.CreateDelegate(typeof(Action), method) :
|
||||||
|
Delegate.CreateDelegate(
|
||||||
|
typeof(Action<>).MakeGenericTypeSafely(method.GetParameters()[0].ParameterType),
|
||||||
|
method
|
||||||
|
);
|
||||||
|
this.eventListeners[eventType].Add(new EventAction
|
||||||
|
{
|
||||||
|
priority = ((EventListenerAttribute)attributes[0]).Priority,
|
||||||
|
del = del
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var (_, value) in this.eventListeners)
|
||||||
|
{
|
||||||
|
value.Sort((a, b) => a.priority.CompareTo(b.priority));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dump()
|
||||||
|
{
|
||||||
|
foreach (var eventType in this.eventListeners.Keys)
|
||||||
|
{
|
||||||
|
Console.WriteLine(eventType);
|
||||||
|
foreach (var action in this.eventListeners[eventType])
|
||||||
|
{
|
||||||
|
Console.WriteLine(action.del.Method.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Publish(EventType eventType, SDL_Event e)
|
||||||
|
{
|
||||||
|
if (this.eventListeners.ContainsKey(eventType))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var action in this.eventListeners[eventType])
|
||||||
|
{
|
||||||
|
if (action.del.Method.GetParameters().Length == 0)
|
||||||
|
{
|
||||||
|
action.del.DynamicInvoke();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
action.del.DynamicInvoke(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CancelEventException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CancelEventException : Exception
|
||||||
|
{
|
||||||
|
public CancelEventException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
using mine2d;
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend;
|
||||||
|
|
||||||
|
public class EventService
|
||||||
|
{
|
||||||
|
private static readonly EventPublisher eventPublisher = new();
|
||||||
|
|
||||||
|
public static void PollEvents()
|
||||||
|
{
|
||||||
|
while (SDL_PollEvent(out var e) != 0)
|
||||||
|
{
|
||||||
|
if (e.type == SDL_EventType.SDL_QUIT)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.Quit, e);
|
||||||
|
}
|
||||||
|
if (e.type == SDL_EventType.SDL_WINDOWEVENT && e.window.windowEvent == SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.WindowResize, e);
|
||||||
|
}
|
||||||
|
if (e.type == SDL_EventType.SDL_MOUSEMOTION)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.MouseMotion, e);
|
||||||
|
}
|
||||||
|
if (e.type == SDL_EventType.SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.MouseButtonDown, e);
|
||||||
|
}
|
||||||
|
if (e.type == SDL_EventType.SDL_MOUSEBUTTONUP && e.button.button == SDL_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.MouseButtonUp, e);
|
||||||
|
}
|
||||||
|
if (e.type == SDL_EventType.SDL_KEYDOWN)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.KeyDown, e);
|
||||||
|
}
|
||||||
|
if (e.type == SDL_EventType.SDL_KEYUP)
|
||||||
|
{
|
||||||
|
eventPublisher.Publish(EventType.KeyUp, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using mine2d.backend.data;
|
using mine2d.backend.data;
|
||||||
using mine2d.core;
|
using mine2d.core;
|
||||||
using mine2d.frontend.renderer;
|
using mine2d.frontend.renderer;
|
||||||
|
using Mine2d.frontend;
|
||||||
|
|
||||||
namespace mine2d.frontend;
|
namespace mine2d.frontend;
|
||||||
|
|
||||||
|
|
@ -23,122 +24,7 @@ public class Frontend : IFrontend
|
||||||
public void Process()
|
public void Process()
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
while (SDL_PollEvent(out var e) != 0)
|
EventService.PollEvents();
|
||||||
{
|
|
||||||
if (e.type == SDL_EventType.SDL_QUIT)
|
|
||||||
{
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
if (e.type == SDL_EventType.SDL_WINDOWEVENT)
|
|
||||||
{
|
|
||||||
if (e.window.windowEvent == SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
|
|
||||||
{
|
|
||||||
ctx.FrontendGameState.WindowWidth = e.window.data1;
|
|
||||||
ctx.FrontendGameState.WindowHeight = e.window.data2;
|
|
||||||
Console.WriteLine($"Window resized to {e.window.data1}x{e.window.data2}");
|
|
||||||
var player = ctx.GameState.Players.Find(
|
|
||||||
p => p.Id == ctx.FrontendGameState.PlayerGuid
|
|
||||||
);
|
|
||||||
ctx.FrontendGameState.Camera.CenterOn(player.Position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e.type == SDL_EventType.SDL_MOUSEMOTION)
|
|
||||||
{
|
|
||||||
var mousePos = new Vector2(e.motion.x, e.motion.y);
|
|
||||||
ctx.FrontendGameState.MousePosition = mousePos;
|
|
||||||
if (ctx.GameState.Players.Find(player => player.Id == ctx.FrontendGameState.PlayerGuid)?.Mining != Vector2.Zero)
|
|
||||||
{
|
|
||||||
var amp = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + ctx.FrontendGameState.Camera.Position;
|
|
||||||
ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, amp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e.type == SDL_EventType.SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT)
|
|
||||||
{
|
|
||||||
var amp = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + ctx.FrontendGameState.Camera.Position;
|
|
||||||
ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, amp));
|
|
||||||
}
|
|
||||||
if (e.type == SDL_EventType.SDL_MOUSEBUTTONUP && e.button.button == SDL_BUTTON_LEFT)
|
|
||||||
{
|
|
||||||
ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, Vector2.Zero));
|
|
||||||
}
|
|
||||||
if (e.type == SDL_EventType.SDL_KEYDOWN && e.key.repeat == 0)
|
|
||||||
{
|
|
||||||
var movementInput = ctx.FrontendGameState.MovementInput;
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_F11)
|
|
||||||
{
|
|
||||||
_ = SDL_SetWindowFullscreen(
|
|
||||||
ctx.Window.GetRaw(),
|
|
||||||
ctx.FrontendGameState.Settings.Fullscreen ? 0 : (uint)SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP
|
|
||||||
);
|
|
||||||
ctx.FrontendGameState.Settings.Fullscreen = !ctx.FrontendGameState.Settings.Fullscreen;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_A)
|
|
||||||
{
|
|
||||||
movementInput.X -= 1;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_D)
|
|
||||||
{
|
|
||||||
movementInput.X += 1;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_W)
|
|
||||||
{
|
|
||||||
movementInput.Y -= 1;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_S)
|
|
||||||
{
|
|
||||||
movementInput.Y += 1;
|
|
||||||
}
|
|
||||||
ctx.FrontendGameState.MovementInput = movementInput;
|
|
||||||
}
|
|
||||||
if (e.type == SDL_EventType.SDL_KEYUP && e.key.repeat == 0)
|
|
||||||
{
|
|
||||||
var movementInput = ctx.FrontendGameState.MovementInput;
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_A)
|
|
||||||
{
|
|
||||||
movementInput.X += 1;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_D)
|
|
||||||
{
|
|
||||||
movementInput.X -= 1;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_W)
|
|
||||||
{
|
|
||||||
movementInput.Y += 1;
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_S)
|
|
||||||
{
|
|
||||||
movementInput.Y -= 1;
|
|
||||||
}
|
|
||||||
ctx.FrontendGameState.MovementInput = movementInput;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
e.key.keysym.scancode
|
|
||||||
is SDL_Scancode.SDL_SCANCODE_A
|
|
||||||
or SDL_Scancode.SDL_SCANCODE_D
|
|
||||||
or SDL_Scancode.SDL_SCANCODE_W
|
|
||||||
or SDL_Scancode.SDL_SCANCODE_S
|
|
||||||
&& e.key.repeat == 0
|
|
||||||
&& e.type is SDL_EventType.SDL_KEYDOWN or SDL_EventType.SDL_KEYUP
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (e.key.repeat == 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var movement = ctx.FrontendGameState.MovementInput;
|
|
||||||
if (movement.Length() > 0)
|
|
||||||
{
|
|
||||||
movement = Vector2.Normalize(movement);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Backend.ProcessPacket(new MovePacket(ctx.FrontendGameState.PlayerName, movement));
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_ESCAPE)
|
|
||||||
{
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Renderer.Clear();
|
ctx.Renderer.Clear();
|
||||||
var scale = ctx.FrontendGameState.Settings.GameScale;
|
var scale = ctx.FrontendGameState.Settings.GameScale;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend.events;
|
||||||
|
|
||||||
|
public class Exit
|
||||||
|
{
|
||||||
|
[EventListener(EventType.Quit)]
|
||||||
|
public static void onExit()
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[EventListener(EventType.KeyDown)]
|
||||||
|
public static void onKeyDown(SDL_Event e)
|
||||||
|
{
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_ESCAPE)
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
using mine2d;
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend.events;
|
||||||
|
|
||||||
|
public class Fullscreen
|
||||||
|
{
|
||||||
|
[EventListener(EventType.KeyDown)]
|
||||||
|
public static void onToggleFullscreen(SDL_Event e)
|
||||||
|
{
|
||||||
|
if (e.key.keysym.scancode != SDL_Scancode.SDL_SCANCODE_F11)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx = Context.Get();
|
||||||
|
_ = SDL_SetWindowFullscreen(
|
||||||
|
ctx.Window.GetRaw(),
|
||||||
|
ctx.FrontendGameState.Settings.Fullscreen ? 0 : (uint)SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
|
ctx.FrontendGameState.Settings.Fullscreen = !ctx.FrontendGameState.Settings.Fullscreen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
using mine2d;
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend.events;
|
||||||
|
|
||||||
|
public class PlayerBreakInput
|
||||||
|
{
|
||||||
|
[EventListener(EventType.MouseMotion)]
|
||||||
|
public static void onBreak(SDL_Event e)
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
var mousePos = new Vector2(e.motion.x, e.motion.y);
|
||||||
|
ctx.FrontendGameState.MousePosition = mousePos;
|
||||||
|
if (ctx.GameState.Players.Find(player => player.Id == ctx.FrontendGameState.PlayerGuid)?.Mining
|
||||||
|
!= Vector2.Zero)
|
||||||
|
{
|
||||||
|
var amp = ctx.FrontendGameState.MousePosition
|
||||||
|
/ ctx.FrontendGameState.Settings.GameScale
|
||||||
|
+ ctx.FrontendGameState.Camera.Position;
|
||||||
|
ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, amp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[EventListener(EventType.MouseButtonDown)]
|
||||||
|
public static void onMouseDown(SDL_Event e)
|
||||||
|
{
|
||||||
|
if (e.button.button != SDL_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx = Context.Get();
|
||||||
|
var amp = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + ctx.FrontendGameState.Camera.Position;
|
||||||
|
ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, amp));
|
||||||
|
}
|
||||||
|
|
||||||
|
[EventListener(EventType.MouseButtonUp)]
|
||||||
|
public static void onMouseUp(SDL_Event e)
|
||||||
|
{
|
||||||
|
if (e.button.button != SDL_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx = Context.Get();
|
||||||
|
ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, Vector2.Zero));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
using mine2d;
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend.events;
|
||||||
|
|
||||||
|
public class PlayerInput
|
||||||
|
{
|
||||||
|
[EventListener(EventType.KeyDown)]
|
||||||
|
public static void move(SDL_Event e)
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
if (!isMovementKey(e.key.keysym.scancode) || e.key.repeat == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var movementInput = ctx.FrontendGameState.MovementInput;
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_A)
|
||||||
|
{
|
||||||
|
movementInput.X -= 1;
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_D)
|
||||||
|
{
|
||||||
|
movementInput.X += 1;
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_W)
|
||||||
|
{
|
||||||
|
movementInput.Y -= 1;
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_S)
|
||||||
|
{
|
||||||
|
movementInput.Y += 1;
|
||||||
|
}
|
||||||
|
ctx.FrontendGameState.MovementInput = movementInput;
|
||||||
|
sendMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
[EventListener(EventType.KeyUp)]
|
||||||
|
public static void stopMove(SDL_Event e)
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
if (!isMovementKey(e.key.keysym.scancode) || e.key.repeat == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var movementInput = ctx.FrontendGameState.MovementInput;
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_A)
|
||||||
|
{
|
||||||
|
movementInput.X += 1;
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_D)
|
||||||
|
{
|
||||||
|
movementInput.X -= 1;
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_W)
|
||||||
|
{
|
||||||
|
movementInput.Y += 1;
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_S)
|
||||||
|
{
|
||||||
|
movementInput.Y -= 1;
|
||||||
|
}
|
||||||
|
ctx.FrontendGameState.MovementInput = movementInput;
|
||||||
|
sendMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool isMovementKey(SDL_Scancode scancode)
|
||||||
|
{
|
||||||
|
return scancode is SDL_Scancode.SDL_SCANCODE_A
|
||||||
|
or SDL_Scancode.SDL_SCANCODE_D
|
||||||
|
or SDL_Scancode.SDL_SCANCODE_W
|
||||||
|
or SDL_Scancode.SDL_SCANCODE_S;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sendMovement()
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
var movement = ctx.FrontendGameState.MovementInput;
|
||||||
|
if (movement.Length() > 0)
|
||||||
|
{
|
||||||
|
movement = Vector2.Normalize(movement);
|
||||||
|
}
|
||||||
|
ctx.Backend.ProcessPacket(new MovePacket(ctx.FrontendGameState.PlayerName, movement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using mine2d;
|
||||||
|
using Mine2d.engine.system;
|
||||||
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace Mine2d.frontend.events;
|
||||||
|
|
||||||
|
public class Resize
|
||||||
|
{
|
||||||
|
[EventListener(EventType.WindowResize)]
|
||||||
|
public static void onResize(SDL_Event e)
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
ctx.FrontendGameState.WindowWidth = e.window.data1;
|
||||||
|
ctx.FrontendGameState.WindowHeight = e.window.data2;
|
||||||
|
var player = ctx.GameState.Players.Find(
|
||||||
|
p => p.Id == ctx.FrontendGameState.PlayerGuid
|
||||||
|
);
|
||||||
|
ctx.FrontendGameState.Camera.CenterOn(player.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue