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 =
|
||||
new();
|
||||
private readonly HashSet<string> clientOnlySubscriptions = new();
|
||||
private readonly HashSet<string> serverSubscriptions = new();
|
||||
private readonly InteractorKind kind;
|
||||
|
||||
public Publisher(InteractorKind kind)
|
||||
|
|
@ -24,20 +26,28 @@ public class Publisher
|
|||
.GetTypesSafe();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attrs = type.GetCustomAttributes(typeof(InteractorAttribute), false);
|
||||
if (attrs.Length == 0)
|
||||
var classAttrs = type.GetCustomAttributes(typeof(InteractorAttribute), false);
|
||||
if (classAttrs.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var methods = type.GetMethods();
|
||||
foreach (var method in methods)
|
||||
{
|
||||
var attrs2 = method.GetCustomAttributes(typeof(InteractionAttribute), false);
|
||||
if (attrs2.Length == 0)
|
||||
var methodAttrs = method.GetCustomAttributes(typeof(InteractionAttribute), false);
|
||||
if (methodAttrs.Length == 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
continue;
|
||||
|
|
@ -51,6 +61,7 @@ public class Publisher
|
|||
this.Subscribe(attr.Type, del);
|
||||
}
|
||||
}
|
||||
this.clientOnlySubscriptions.ExceptWith(this.serverSubscriptions);
|
||||
}
|
||||
|
||||
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 mine2d.backend.data;
|
||||
using mine2d.engine;
|
||||
using mine2d.engine.system.annotations;
|
||||
using mine2d.state;
|
||||
using Newtonsoft.Json;
|
||||
|
|
@ -7,7 +8,7 @@ using WatsonTcp;
|
|||
|
||||
namespace mine2d.backend;
|
||||
|
||||
class RemoteBackend : IBackend
|
||||
public class RemoteBackend : IBackend
|
||||
{
|
||||
private WatsonTcpClient client;
|
||||
private Publisher publisher;
|
||||
|
|
@ -27,6 +28,10 @@ class RemoteBackend : IBackend
|
|||
public void ProcessPacket(ValueType packet)
|
||||
{
|
||||
this.publisher.Publish(packet);
|
||||
if (this.publisher.IsClientOnlyPacket(PacketUtils.GetType(packet)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var json = JsonConvert.SerializeObject(packet);
|
||||
var bytes = Encoding.UTF8.GetBytes(json);
|
||||
this.client.Send(bytes);
|
||||
|
|
@ -53,4 +58,4 @@ class RemoteBackend : IBackend
|
|||
};
|
||||
this.client.Connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ public static class TypeExtensions
|
|||
{
|
||||
var missingTypes = e.Types
|
||||
.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
|
||||
{
|
||||
Lowest = 0,
|
||||
Low = 1,
|
||||
Normal = 2,
|
||||
High = 3,
|
||||
Highest = 4,
|
||||
Important = 5,
|
||||
Lowest = -2,
|
||||
Low = -1,
|
||||
Normal = 0,
|
||||
High = 1,
|
||||
Highest = 2,
|
||||
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.core;
|
||||
using mine2d.frontend.renderer;
|
||||
using Mine2d.frontend;
|
||||
|
||||
namespace mine2d.frontend;
|
||||
|
||||
|
|
@ -23,122 +24,7 @@ public class Frontend : IFrontend
|
|||
public void Process()
|
||||
{
|
||||
var ctx = Context.Get();
|
||||
while (SDL_PollEvent(out var e) != 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
EventService.PollEvents();
|
||||
|
||||
ctx.Renderer.Clear();
|
||||
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