refactoring WIP
This commit is contained in:
parent
2742e0100c
commit
7eea232196
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Rider ignored files
|
||||||
|
/modules.xml
|
||||||
|
/.idea.mine2d.iml
|
||||||
|
/contentModel.xml
|
||||||
|
/projectSettingsUpdater.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="UserContentModel">
|
||||||
|
<attachedFolders />
|
||||||
|
<explicitIncludes />
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=trimmable/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
class Program
|
namespace mine2d;
|
||||||
|
|
||||||
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
@ -10,4 +12,4 @@
|
||||||
// p.Dump();
|
// p.Dump();
|
||||||
// Console.WriteLine("Hello World!");
|
// Console.WriteLine("Hello World!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,20 +5,20 @@
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RootNamespace>mine2d</RootNamespace>
|
<RootNamespace>mine2d</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<PublishTrimmed>true</PublishTrimmed>
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
<TrimmerDefaultAction>link</TrimmerDefaultAction>
|
<TrimmerDefaultAction>link</TrimmerDefaultAction>
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
<PublishReadyToRun>true</PublishReadyToRun>
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
<Nullable>disable</Nullable>
|
<Nullable>disable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.SDL2-CS" Version="1.0.596-alpha" />
|
<PackageReference Include="ppy.SDL2-CS" Version="1.0.596-alpha" />
|
||||||
<PackageReference Include="WatsonTcp" Version="4.8.14.14" />
|
<PackageReference Include="WatsonTcp" Version="4.8.14.14" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="assets/*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="assets/*" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
using mine2d.backend;
|
||||||
|
using mine2d.core.tiles;
|
||||||
|
using mine2d.engine;
|
||||||
|
using mine2d.frontend;
|
||||||
|
using mine2d.state;
|
||||||
|
|
||||||
|
namespace mine2d;
|
||||||
|
|
||||||
class Context
|
class Context
|
||||||
{
|
{
|
||||||
public bool IsHost { get; set; }
|
public bool IsHost { get; set; }
|
||||||
|
|
@ -9,7 +17,7 @@ class Context
|
||||||
public Renderer Renderer { get; set; }
|
public Renderer Renderer { get; set; }
|
||||||
public TileRegistry TileRegistry { get; set; }
|
public TileRegistry TileRegistry { get; set; }
|
||||||
public ResourceLoader ResourceLoader { get; set; }
|
public ResourceLoader ResourceLoader { get; set; }
|
||||||
public static Context instance { get; set; }
|
public static Context Instance { get; set; }
|
||||||
|
|
||||||
public Context(
|
public Context(
|
||||||
bool isHost,
|
bool isHost,
|
||||||
|
|
@ -30,16 +38,16 @@ class Context
|
||||||
this.Window = window;
|
this.Window = window;
|
||||||
this.TileRegistry = new TileRegistry();
|
this.TileRegistry = new TileRegistry();
|
||||||
this.ResourceLoader = new ResourceLoader();
|
this.ResourceLoader = new ResourceLoader();
|
||||||
Context.instance = this;
|
Context.Instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Context Get()
|
public static Context Get()
|
||||||
{
|
{
|
||||||
if (Context.instance == null)
|
if (Context.Instance == null)
|
||||||
{
|
{
|
||||||
throw new Exception("Context not initialized");
|
throw new Exception("Context not initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Context.instance;
|
return Context.Instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
using static SDL2.SDL;
|
namespace mine2d;
|
||||||
|
|
||||||
enum Control
|
enum Control
|
||||||
{
|
{
|
||||||
UP,
|
Up,
|
||||||
DOWN,
|
Down,
|
||||||
LEFT,
|
Left,
|
||||||
RIGHT,
|
Right,
|
||||||
STAY,
|
Stay,
|
||||||
CONFIRM,
|
Confirm,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ControlKeyExtension
|
static class ControlKeyExtension
|
||||||
|
|
@ -16,20 +16,20 @@ static class ControlKeyExtension
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case Control.UP:
|
case Control.Up:
|
||||||
return SDL_Keycode.SDLK_w;
|
return SDL_Keycode.SDLK_w;
|
||||||
case Control.DOWN:
|
case Control.Down:
|
||||||
return SDL_Keycode.SDLK_s;
|
return SDL_Keycode.SDLK_s;
|
||||||
case Control.LEFT:
|
case Control.Left:
|
||||||
return SDL_Keycode.SDLK_a;
|
return SDL_Keycode.SDLK_a;
|
||||||
case Control.RIGHT:
|
case Control.Right:
|
||||||
return SDL_Keycode.SDLK_d;
|
return SDL_Keycode.SDLK_d;
|
||||||
case Control.STAY:
|
case Control.Stay:
|
||||||
return SDL_Keycode.SDLK_LCTRL;
|
return SDL_Keycode.SDLK_LCTRL;
|
||||||
case Control.CONFIRM:
|
case Control.Confirm:
|
||||||
return SDL_Keycode.SDLK_SPACE;
|
return SDL_Keycode.SDLK_SPACE;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Invalid control");
|
throw new ArgumentException("Invalid control");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
using mine2d.backend;
|
||||||
|
using mine2d.core;
|
||||||
|
using mine2d.engine;
|
||||||
|
using mine2d.frontend;
|
||||||
|
using mine2d.state;
|
||||||
|
|
||||||
|
namespace mine2d;
|
||||||
|
|
||||||
class Mine2d : Game
|
class Mine2d : Game
|
||||||
{
|
{
|
||||||
private readonly Context ctx;
|
private readonly Context ctx;
|
||||||
|
|
@ -29,13 +37,13 @@ class Mine2d : Game
|
||||||
this.ctx.Frontend.Init();
|
this.ctx.Frontend.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void draw()
|
protected override void Draw()
|
||||||
{
|
{
|
||||||
this.ctx.Frontend.Process();
|
this.ctx.Frontend.Process();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void update(double dt)
|
protected override void Update(double dt)
|
||||||
{
|
{
|
||||||
this.ctx.Backend.Process(dt);
|
this.ctx.Backend.Process(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using mine2d.engine.system.annotations;
|
||||||
|
using mine2d.network;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using WatsonTcp;
|
using WatsonTcp;
|
||||||
|
|
||||||
|
namespace mine2d.backend;
|
||||||
|
|
||||||
class Backend : IBackend
|
class Backend : IBackend
|
||||||
{
|
{
|
||||||
private WatsonTcpServer server;
|
private WatsonTcpServer server;
|
||||||
private Publisher publisher;
|
private Publisher publisher;
|
||||||
private Queue<ValueType> pendingPackets = new();
|
private Queue<ValueType> pendingPackets = new();
|
||||||
private uint tick = 0;
|
private uint tick;
|
||||||
|
|
||||||
public void Process(double dt)
|
public void Process(double dt)
|
||||||
{
|
{
|
||||||
|
|
@ -17,7 +22,7 @@ class Backend : IBackend
|
||||||
var packet = this.pendingPackets.Dequeue();
|
var packet = this.pendingPackets.Dequeue();
|
||||||
this.publisher.Publish(packet);
|
this.publisher.Publish(packet);
|
||||||
}
|
}
|
||||||
this.sendGameState();
|
this.SendGameState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessPacket(ValueType packet)
|
public void ProcessPacket(ValueType packet)
|
||||||
|
|
@ -34,13 +39,13 @@ class Backend : IBackend
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
this.server = new WatsonTcpServer("127.0.0.1", 42069);
|
this.server = new WatsonTcpServer("127.0.0.1", 42069);
|
||||||
this.server.Events.ClientConnected += this.clientConnected;
|
this.server.Events.ClientConnected += this.ClientConnected;
|
||||||
this.server.Events.ClientDisconnected += this.clientDisconnected;
|
this.server.Events.ClientDisconnected += this.ClientDisconnected;
|
||||||
this.server.Events.MessageReceived += this.messageReceived;
|
this.server.Events.MessageReceived += this.MessageReceived;
|
||||||
this.server.Start();
|
this.server.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clientConnected(object sender, ConnectionEventArgs args)
|
private void ClientConnected(object sender, ConnectionEventArgs args)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Client connected: " + args.IpPort);
|
Console.WriteLine("Client connected: " + args.IpPort);
|
||||||
var gameState = Context.Get().GameState;
|
var gameState = Context.Get().GameState;
|
||||||
|
|
@ -51,12 +56,12 @@ class Backend : IBackend
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clientDisconnected(object sender, DisconnectionEventArgs args)
|
private void ClientDisconnected(object sender, DisconnectionEventArgs args)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Client disconnected: " + args.IpPort);
|
Console.WriteLine("Client disconnected: " + args.IpPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void messageReceived(object sender, MessageReceivedEventArgs args)
|
private void MessageReceived(object sender, MessageReceivedEventArgs args)
|
||||||
{
|
{
|
||||||
var time = DateTime.Now;
|
var time = DateTime.Now;
|
||||||
Console.WriteLine("Message Received: " + args.IpPort);
|
Console.WriteLine("Message Received: " + args.IpPort);
|
||||||
|
|
@ -64,24 +69,24 @@ class Backend : IBackend
|
||||||
Console.WriteLine("Received packet: " + packet);
|
Console.WriteLine("Received packet: " + packet);
|
||||||
if (packet != null)
|
if (packet != null)
|
||||||
{
|
{
|
||||||
pendingPackets.Enqueue(packet);
|
this.pendingPackets.Enqueue(packet);
|
||||||
}
|
}
|
||||||
Console.WriteLine(DateTime.Now - time);
|
Console.WriteLine(DateTime.Now - time);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendGameState()
|
private void SendGameState()
|
||||||
{
|
{
|
||||||
if (server == null)
|
if (this.server == null)
|
||||||
return;
|
return;
|
||||||
var clients = server.ListClients();
|
var clients = this.server.ListClients().ToArray();
|
||||||
if (clients.Count() == 0)
|
if (!clients.Any())
|
||||||
return;
|
return;
|
||||||
var gameState = Context.Get().GameState;
|
var gameState = Context.Get().GameState;
|
||||||
var json = JsonConvert.SerializeObject(gameState);
|
var json = JsonConvert.SerializeObject(gameState);
|
||||||
var bytes = Encoding.UTF8.GetBytes(json);
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
foreach (var client in clients)
|
foreach (var client in clients)
|
||||||
{
|
{
|
||||||
server.Send(client, bytes);
|
this.server.Send(client, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
namespace mine2d.backend;
|
||||||
|
|
||||||
interface IBackend
|
interface IBackend
|
||||||
{
|
{
|
||||||
public void Process(double dt);
|
public void Process(double dt);
|
||||||
public void ProcessPacket(ValueType packet);
|
public void ProcessPacket(ValueType packet);
|
||||||
public void Init();
|
public void Init();
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using mine2d.core.extensions;
|
||||||
|
using mine2d.engine;
|
||||||
|
using mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace mine2d.backend;
|
||||||
|
|
||||||
class Publisher
|
class Publisher
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, HashSet<Delegate>> subscribers =
|
private readonly Dictionary<string, HashSet<Delegate>> subscribers =
|
||||||
|
|
@ -7,13 +14,14 @@ class Publisher
|
||||||
public Publisher(InteractorKind kind)
|
public Publisher(InteractorKind kind)
|
||||||
{
|
{
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.scan();
|
this.Scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scan()
|
private void Scan()
|
||||||
{
|
{
|
||||||
var assembly = this.GetType().Assembly;
|
var types = Assembly
|
||||||
var types = assembly.GetTypes();
|
.GetAssembly(this.GetType())!
|
||||||
|
.GetTypesSafe();
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
{
|
{
|
||||||
var attrs = type.GetCustomAttributes(typeof(Interactor), false);
|
var attrs = type.GetCustomAttributes(typeof(Interactor), false);
|
||||||
|
|
@ -35,15 +43,15 @@ class Publisher
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var del = Delegate.CreateDelegate(
|
var del = Delegate.CreateDelegate(
|
||||||
typeof(Action<>).MakeGenericType(method.GetParameters()[0].ParameterType),
|
typeof(Action<>).MakeGenericTypeSafely(method.GetParameters()[0].ParameterType),
|
||||||
method
|
method
|
||||||
);
|
);
|
||||||
this.subscribe(attr.Type, del);
|
this.Subscribe(attr.Type, del);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void subscribe(string type, Delegate callback)
|
private void Subscribe(string type, Delegate callback)
|
||||||
{
|
{
|
||||||
if (!this.subscribers.ContainsKey(type))
|
if (!this.subscribers.ContainsKey(type))
|
||||||
{
|
{
|
||||||
|
|
@ -83,4 +91,4 @@ class Publisher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,21 +1,25 @@
|
||||||
using WatsonTcp;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using mine2d.engine.system.annotations;
|
||||||
|
using mine2d.state;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using WatsonTcp;
|
||||||
|
|
||||||
|
namespace mine2d.backend;
|
||||||
|
|
||||||
class RemoteBackend : IBackend
|
class RemoteBackend : IBackend
|
||||||
{
|
{
|
||||||
private WatsonTcpClient client;
|
private WatsonTcpClient client;
|
||||||
private Publisher publisher;
|
private Publisher publisher;
|
||||||
private Queue<ValueType> pendingPackets = new Queue<ValueType>();
|
private readonly Queue<ValueType> pendingPackets = new();
|
||||||
private uint tick = 0;
|
private uint tick = 0;
|
||||||
|
|
||||||
public void Process(double dt)
|
public void Process(double dt)
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
this.ProcessPacket(new TickPacket(this.tick++));
|
||||||
this.ProcessPacket(new TickPacket(tick++));
|
while (this.pendingPackets.Count > 0)
|
||||||
while (pendingPackets.Count > 0)
|
|
||||||
{
|
{
|
||||||
var packet = pendingPackets.Dequeue();
|
var packet = this.pendingPackets.Dequeue();
|
||||||
this.ProcessPacket(packet);
|
this.ProcessPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +29,7 @@ class RemoteBackend : IBackend
|
||||||
this.publisher.Publish(packet);
|
this.publisher.Publish(packet);
|
||||||
var json = JsonConvert.SerializeObject(packet);
|
var json = JsonConvert.SerializeObject(packet);
|
||||||
var bytes = Encoding.UTF8.GetBytes(json);
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
client.Send(bytes);
|
this.client.Send(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
|
|
@ -36,8 +40,8 @@ class RemoteBackend : IBackend
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
client = new WatsonTcpClient("127.0.0.1", 42069);
|
this.client = new WatsonTcpClient("127.0.0.1", 42069);
|
||||||
client.Events.MessageReceived += (sender, args) =>
|
this.client.Events.MessageReceived += (_, args) =>
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
var message = Encoding.UTF8.GetString(args.Data);
|
var message = Encoding.UTF8.GetString(args.Data);
|
||||||
|
|
@ -47,6 +51,6 @@ class RemoteBackend : IBackend
|
||||||
ctx.GameState = packet;
|
ctx.GameState = packet;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
client.Connect();
|
this.client.Connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,49 +1,55 @@
|
||||||
using System.Numerics;
|
namespace mine2d.backend.data;
|
||||||
|
|
||||||
readonly struct MovePacket
|
public interface IPacket
|
||||||
{
|
{
|
||||||
readonly public string type = "move";
|
string Type { get; }
|
||||||
readonly public string playerName;
|
}
|
||||||
readonly public Vector2 movement;
|
|
||||||
|
readonly struct MovePacket : IPacket
|
||||||
|
{
|
||||||
|
public string Type => "move";
|
||||||
|
|
||||||
|
readonly public string PlayerName;
|
||||||
|
readonly public Vector2 Movement;
|
||||||
|
|
||||||
public MovePacket(string playerName, Vector2 movement)
|
public MovePacket(string playerName, Vector2 movement)
|
||||||
{
|
{
|
||||||
this.playerName = playerName;
|
this.PlayerName = playerName;
|
||||||
this.movement = movement;
|
this.Movement = movement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly struct ConnectPacket
|
readonly struct ConnectPacket
|
||||||
{
|
{
|
||||||
public readonly string type = "connect";
|
public readonly string Type = "connect";
|
||||||
public readonly string playerName;
|
public readonly string PlayerName;
|
||||||
public readonly Guid playerGuid;
|
public readonly Guid PlayerGuid;
|
||||||
|
|
||||||
public ConnectPacket(string playerName, Guid playerGuid)
|
public ConnectPacket(string playerName, Guid playerGuid)
|
||||||
{
|
{
|
||||||
this.playerName = playerName;
|
this.PlayerName = playerName;
|
||||||
this.playerGuid = playerGuid;
|
this.PlayerGuid = playerGuid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly struct TickPacket
|
readonly struct TickPacket
|
||||||
{
|
{
|
||||||
public readonly string type = "tick";
|
public readonly string Type = "tick";
|
||||||
public readonly uint tick;
|
public readonly uint Tick;
|
||||||
|
|
||||||
public TickPacket(uint tick)
|
public TickPacket(uint tick)
|
||||||
{
|
{
|
||||||
this.tick = tick;
|
this.Tick = tick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly struct SelfMovedPacket
|
readonly struct SelfMovedPacket
|
||||||
{
|
{
|
||||||
public readonly string type = "selfMoved";
|
public readonly string Type = "selfMoved";
|
||||||
public readonly Vector2 target;
|
public readonly Vector2 Target;
|
||||||
|
|
||||||
public SelfMovedPacket(Vector2 target)
|
public SelfMovedPacket(Vector2 target)
|
||||||
{
|
{
|
||||||
this.target = target;
|
this.Target = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace mine2d.backend.interactor;
|
||||||
|
|
||||||
[Interactor]
|
[Interactor]
|
||||||
class Breaking
|
class Breaking
|
||||||
{
|
{
|
||||||
|
|
@ -7,8 +12,8 @@ class Breaking
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
ctx.GameState.Players.ForEach(player =>
|
ctx.GameState.Players.ForEach(player =>
|
||||||
{
|
{
|
||||||
Math.Max(0, player.MiningCooldown -= 1);
|
player.MiningCooldown = Math.Max(0, player.MiningCooldown - 1);
|
||||||
if (player.Mining != null && player.MiningCooldown == 0)
|
if (player.Mining != Vector2.Zero && player.MiningCooldown == 0)
|
||||||
{
|
{
|
||||||
var chunk = ctx.GameState.World.GetChunkAt(player.Mining);
|
var chunk = ctx.GameState.World.GetChunkAt(player.Mining);
|
||||||
// chunk.SetTileAt(player.Mining, tile with { Hits = tile.Hits + 1 });
|
// chunk.SetTileAt(player.Mining, tile with { Hits = tile.Hits + 1 });
|
||||||
|
|
@ -22,4 +27,4 @@ class Breaking
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using mine2d.engine.system.annotations;
|
||||||
|
using mine2d.state;
|
||||||
|
|
||||||
|
namespace mine2d.backend.interactor;
|
||||||
|
|
||||||
[Interactor]
|
[Interactor]
|
||||||
class Connect
|
class Connect
|
||||||
{
|
{
|
||||||
|
|
@ -5,18 +11,18 @@ class Connect
|
||||||
public static void ConnectServer(ConnectPacket packet)
|
public static void ConnectServer(ConnectPacket packet)
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
var player = ctx.GameState.Players.Find(p => p.Name == packet.playerName);
|
var player = ctx.GameState.Players.Find(p => p.Name == packet.PlayerName);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
ctx.GameState.Players.Add(
|
ctx.GameState.Players.Add(
|
||||||
new Player
|
new Player
|
||||||
{
|
{
|
||||||
Name = packet.playerName,
|
Name = packet.PlayerName,
|
||||||
Guid = packet.playerGuid,
|
Guid = packet.PlayerGuid,
|
||||||
Position = new Vector2(20, 16 * 16),
|
Position = new Vector2(20, 16 * 16),
|
||||||
Movement = new Vector2(0, 0)
|
Movement = new Vector2(0, 0)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using mine2d.core;
|
||||||
|
using mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
namespace mine2d.backend.interactor;
|
||||||
|
|
||||||
[Interactor]
|
[Interactor]
|
||||||
class Move
|
class Move
|
||||||
{
|
{
|
||||||
|
|
@ -5,10 +11,10 @@ class Move
|
||||||
public static void MoveHybrid(MovePacket packet)
|
public static void MoveHybrid(MovePacket packet)
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
var player = ctx.GameState.Players.Find(p => p.Name == packet.playerName);
|
var player = ctx.GameState.Players.Find(p => p.Name == packet.PlayerName);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
{
|
{
|
||||||
player.Movement = packet.movement * 4;
|
player.Movement = packet.Movement * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,4 +32,4 @@ class Move
|
||||||
var camera = Context.Get().FrontendGameState.Camera;
|
var camera = Context.Get().FrontendGameState.Camera;
|
||||||
camera.CenterOn(PlayerEntity.GetSelf().Position);
|
camera.CenterOn(PlayerEntity.GetSelf().Position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
|
using mine2d.core.data;
|
||||||
|
using mine2d.core.tiles;
|
||||||
|
using mine2d.core.world;
|
||||||
|
|
||||||
|
namespace mine2d.core;
|
||||||
|
|
||||||
class Bootstrapper
|
class Bootstrapper
|
||||||
{
|
{
|
||||||
public static void Bootstrap()
|
public static void Bootstrap()
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
ctx.GameState.World = new World();
|
ctx.GameState.World = new World();
|
||||||
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(0, 1, STile.From(Tiles.stone)));
|
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(0, 1, STile.From(Tiles.Stone)));
|
||||||
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 1, STile.From(Tiles.stone)));
|
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 1, STile.From(Tiles.Stone)));
|
||||||
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 0, STile.From(Tiles.stone)));
|
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 0, STile.From(Tiles.Stone)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
|
namespace mine2d.core;
|
||||||
|
|
||||||
class Camera
|
class Camera
|
||||||
{
|
{
|
||||||
public Vector2 position;
|
public Vector2 Position;
|
||||||
|
|
||||||
public Camera()
|
public Camera()
|
||||||
{
|
{
|
||||||
position = Vector2.Zero;
|
this.Position = Vector2.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CenterOn(Vector2 target)
|
public void CenterOn(Vector2 target)
|
||||||
|
|
@ -13,6 +15,6 @@ class Camera
|
||||||
var scale = ctx.FrontendGameState.Settings.GameScale;
|
var scale = ctx.FrontendGameState.Settings.GameScale;
|
||||||
var windowWidth = ctx.FrontendGameState.WindowWidth;
|
var windowWidth = ctx.FrontendGameState.WindowWidth;
|
||||||
var windowHeight = ctx.FrontendGameState.WindowHeight;
|
var windowHeight = ctx.FrontendGameState.WindowHeight;
|
||||||
position = target - (new Vector2(windowWidth / 2, windowHeight / 2)) / scale;
|
this.Position = target - (new Vector2(windowWidth, windowHeight) / 2) / scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
namespace mine2d.core;
|
||||||
|
|
||||||
class Constants
|
class Constants
|
||||||
{
|
{
|
||||||
public const int ChunkSize = 32;
|
public const int ChunkSize = 32;
|
||||||
public const int TileSize = 16;
|
public const int TileSize = 16;
|
||||||
public static Vector2 gravity = new Vector2(0, 0.1f);
|
public static Vector2 Gravity = new Vector2(0, 0.1f);
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
|
using mine2d.state;
|
||||||
|
|
||||||
|
namespace mine2d.core;
|
||||||
|
|
||||||
class PlayerEntity
|
class PlayerEntity
|
||||||
{
|
{
|
||||||
public static bool isSelf(Player p)
|
public static bool IsSelf(Player p)
|
||||||
{
|
{
|
||||||
return p.Guid == GetSelf().Guid;
|
return p.Guid == GetSelf().Guid;
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +20,7 @@ class PlayerEntity
|
||||||
|
|
||||||
public static void Move(Player p)
|
public static void Move(Player p)
|
||||||
{
|
{
|
||||||
p.Movement += Constants.gravity;
|
p.Movement += Constants.Gravity;
|
||||||
p.Position += p.Movement;
|
p.Position += p.Movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,7 +32,7 @@ class PlayerEntity
|
||||||
{
|
{
|
||||||
var pL = p.Position + new Vector2(0, -8);
|
var pL = p.Position + new Vector2(0, -8);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pL) && world.GetChunkAt(pL).hasTileAt(pL);
|
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL);
|
||||||
if (hasCollision)
|
if (hasCollision)
|
||||||
{
|
{
|
||||||
p.Movement = p.Movement with { X = 0 };
|
p.Movement = p.Movement with { X = 0 };
|
||||||
|
|
@ -39,7 +43,7 @@ class PlayerEntity
|
||||||
{
|
{
|
||||||
var pR = p.Position + new Vector2(16, -8);
|
var pR = p.Position + new Vector2(16, -8);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pR) && world.GetChunkAt(pR).hasTileAt(pR);
|
world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
||||||
if (hasCollision)
|
if (hasCollision)
|
||||||
{
|
{
|
||||||
p.Movement = p.Movement with { X = 0 };
|
p.Movement = p.Movement with { X = 0 };
|
||||||
|
|
@ -51,8 +55,8 @@ class PlayerEntity
|
||||||
var pL = p.Position;
|
var pL = p.Position;
|
||||||
var pR = p.Position + new Vector2(16, 0);
|
var pR = p.Position + new Vector2(16, 0);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pL) && world.GetChunkAt(pL).hasTileAt(pL)
|
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
||||||
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).hasTileAt(pR);
|
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
||||||
if (hasCollision)
|
if (hasCollision)
|
||||||
{
|
{
|
||||||
p.Movement = p.Movement with { Y = 0 };
|
p.Movement = p.Movement with { Y = 0 };
|
||||||
|
|
@ -64,8 +68,8 @@ class PlayerEntity
|
||||||
var pL = p.Position + new Vector2(0, -32);
|
var pL = p.Position + new Vector2(0, -32);
|
||||||
var pR = p.Position + new Vector2(16, -32);
|
var pR = p.Position + new Vector2(16, -32);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pL) && world.GetChunkAt(pL).hasTileAt(pL)
|
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
||||||
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).hasTileAt(pR);
|
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
||||||
if (hasCollision)
|
if (hasCollision)
|
||||||
{
|
{
|
||||||
p.Movement = p.Movement with { Y = 0 };
|
p.Movement = p.Movement with { Y = 0 };
|
||||||
|
|
@ -73,4 +77,4 @@ class PlayerEntity
|
||||||
}
|
}
|
||||||
} while (hasCollision);
|
} while (hasCollision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
namespace mine2d.core.data;
|
||||||
|
|
||||||
class Chunk
|
class Chunk
|
||||||
{
|
{
|
||||||
public STile[,] Tiles { get; set; } = new STile[Constants.ChunkSize, Constants.ChunkSize];
|
public STile[,] Tiles { get; set; } = new STile[Constants.ChunkSize, Constants.ChunkSize];
|
||||||
|
|
@ -20,17 +22,17 @@ class Chunk
|
||||||
return this.Tiles[x, y];
|
return this.Tiles[x, y];
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasTileAt(Vector2 pos)
|
public bool HasTileAt(Vector2 pos)
|
||||||
{
|
{
|
||||||
return this.hasTileAt((int)pos.X, (int)pos.Y);
|
return this.HasTileAt((int)pos.X, (int)pos.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasTileAt(int x, int y)
|
public bool HasTileAt(int x, int y)
|
||||||
{
|
{
|
||||||
var posInChunk = this.GetPositionInChunk(new Vector2(x, y));
|
var posInChunk = this.GetPositionInChunk(new Vector2(x, y));
|
||||||
var tileX = (int)Math.Floor(posInChunk.X / Constants.TileSize);
|
var tileX = (int)Math.Floor(posInChunk.X / Constants.TileSize);
|
||||||
var tileY = (int)Math.Floor(posInChunk.Y / Constants.TileSize);
|
var tileY = (int)Math.Floor(posInChunk.Y / Constants.TileSize);
|
||||||
return this.hasTile(tileX, tileY);
|
return this.HasTile(tileX, tileY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public STile GetTileAt(Vector2 pos)
|
public STile GetTileAt(Vector2 pos)
|
||||||
|
|
@ -59,14 +61,14 @@ class Chunk
|
||||||
this.SetTile(tileX, tileY, tile);
|
this.SetTile(tileX, tileY, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasTile(int x, int y)
|
public bool HasTile(int x, int y)
|
||||||
{
|
{
|
||||||
return x >= 0 && x < this.Tiles.Length && y >= 0 && y < this.Tiles.Length && this.Tiles[x, y].Id != 0;
|
return x >= 0 && x < this.Tiles.Length && y >= 0 && y < this.Tiles.Length && this.Tiles[x, y].Id != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasTile(Vector2 pos)
|
public bool HasTile(Vector2 pos)
|
||||||
{
|
{
|
||||||
return this.hasTile((int)pos.X, (int)pos.Y);
|
return this.HasTile((int)pos.X, (int)pos.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 GetPositionInChunk(Vector2 pos)
|
public Vector2 GetPositionInChunk(Vector2 pos)
|
||||||
|
|
@ -74,4 +76,4 @@ class Chunk
|
||||||
return pos - new Vector2(this.X * Constants.ChunkSize * Constants.TileSize,
|
return pos - new Vector2(this.X * Constants.ChunkSize * Constants.TileSize,
|
||||||
this.Y * Constants.ChunkSize * Constants.TileSize);
|
this.Y * Constants.ChunkSize * Constants.TileSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using mine2d.core.tiles;
|
||||||
|
|
||||||
|
namespace mine2d.core.data;
|
||||||
|
|
||||||
struct STile
|
struct STile
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
@ -15,4 +19,4 @@ struct STile
|
||||||
{
|
{
|
||||||
return From((int)id);
|
return From((int)id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
namespace mine2d.core.data;
|
||||||
|
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
public Dictionary<string, Chunk> Chunks { get; set; } = new Dictionary<string, Chunk>();
|
public Dictionary<string, Chunk> Chunks { get; set; } = new Dictionary<string, Chunk>();
|
||||||
|
|
@ -75,6 +77,6 @@ class World
|
||||||
|
|
||||||
public bool HasTileAt(int x, int y)
|
public bool HasTileAt(int x, int y)
|
||||||
{
|
{
|
||||||
return this.HasChunkAt(x, y) && this.GetChunkAt(x, y).hasTileAt(new Vector2(x, y));
|
return this.HasChunkAt(x, y) && this.GetChunkAt(x, y).HasTileAt(new Vector2(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace mine2d.core.extensions;
|
||||||
|
|
||||||
|
public static class AssemblyExtensions
|
||||||
|
{
|
||||||
|
public static Type[] GetTypesSafe(this Assembly assembly)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#pragma warning disable IL2026
|
||||||
|
return assembly.GetTypes();
|
||||||
|
#pragma warning restore IL2026
|
||||||
|
}
|
||||||
|
catch (ReflectionTypeLoadException ex)
|
||||||
|
{
|
||||||
|
return ex.Types.Where(t => t != null).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace mine2d.core.extensions;
|
||||||
|
|
||||||
|
public static class TypeExtensions
|
||||||
|
{
|
||||||
|
public static Type MakeGenericTypeSafely(this Type type, params Type[] typeArguments)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#pragma warning disable IL2026
|
||||||
|
return type.MakeGenericType(typeArguments);
|
||||||
|
#pragma warning restore IL2026
|
||||||
|
}
|
||||||
|
catch (ReflectionTypeLoadException e)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using mine2d.core.data;
|
||||||
|
|
||||||
|
namespace mine2d.core.tiles;
|
||||||
|
|
||||||
class Tile
|
class Tile
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
@ -14,11 +18,10 @@ class Tile
|
||||||
var (ptr, size) = rl.LoadToIntPtr("assets." + textureName + ".png");
|
var (ptr, size) = rl.LoadToIntPtr("assets." + textureName + ".png");
|
||||||
var sdlBuffer = SDL_RWFromMem(ptr, size);
|
var sdlBuffer = SDL_RWFromMem(ptr, size);
|
||||||
var surface = IMG_Load_RW(sdlBuffer, 1);
|
var surface = IMG_Load_RW(sdlBuffer, 1);
|
||||||
var texture = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
this.texture = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
||||||
this.texture = texture;
|
|
||||||
if (breakingTexture == IntPtr.Zero)
|
if (breakingTexture == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
loadBreakingTexture();
|
LoadBreakingTexture();
|
||||||
}
|
}
|
||||||
SDL_FreeSurface(surface);
|
SDL_FreeSurface(surface);
|
||||||
}
|
}
|
||||||
|
|
@ -35,8 +38,8 @@ class Tile
|
||||||
var camera = Context.Get().FrontendGameState.Camera;
|
var camera = Context.Get().FrontendGameState.Camera;
|
||||||
renderer.DrawTexture(
|
renderer.DrawTexture(
|
||||||
this.texture,
|
this.texture,
|
||||||
(x - (int)camera.position.X) * scale,
|
(x - (int)camera.Position.X) * scale,
|
||||||
(y - (int)camera.position.Y) * scale,
|
(y - (int)camera.Position.Y) * scale,
|
||||||
Constants.TileSize * scale,
|
Constants.TileSize * scale,
|
||||||
Constants.TileSize * scale
|
Constants.TileSize * scale
|
||||||
);
|
);
|
||||||
|
|
@ -45,8 +48,8 @@ class Tile
|
||||||
var breakingOffset = (int)((double)tile.Hits / this.Hardness * 4);
|
var breakingOffset = (int)((double)tile.Hits / this.Hardness * 4);
|
||||||
renderer.DrawTexture(
|
renderer.DrawTexture(
|
||||||
breakingTexture,
|
breakingTexture,
|
||||||
(x - (int)camera.position.X) * scale,
|
(x - (int)camera.Position.X) * scale,
|
||||||
(y - (int)camera.position.Y) * scale,
|
(y - (int)camera.Position.Y) * scale,
|
||||||
Constants.TileSize * scale,
|
Constants.TileSize * scale,
|
||||||
Constants.TileSize * scale,
|
Constants.TileSize * scale,
|
||||||
breakingOffset,
|
breakingOffset,
|
||||||
|
|
@ -56,7 +59,7 @@ class Tile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadBreakingTexture()
|
private static void LoadBreakingTexture()
|
||||||
{
|
{
|
||||||
var rl = Context.Get().ResourceLoader;
|
var rl = Context.Get().ResourceLoader;
|
||||||
var (ptr, size) = rl.LoadToIntPtr("assets.breaking.png");
|
var (ptr, size) = rl.LoadToIntPtr("assets.breaking.png");
|
||||||
|
|
@ -65,4 +68,4 @@ class Tile
|
||||||
breakingTexture = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
breakingTexture = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
||||||
SDL_FreeSurface(surface);
|
SDL_FreeSurface(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
enum Tiles : int
|
namespace mine2d.core.tiles;
|
||||||
|
|
||||||
|
enum Tiles
|
||||||
{
|
{
|
||||||
stone = 1,
|
Stone = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
class TileRegistry
|
class TileRegistry
|
||||||
{
|
{
|
||||||
public Dictionary<int, Tile> Tiles { get; set; } = new Dictionary<int, Tile>();
|
public Dictionary<int, Tile> Tiles { get; set; } = new();
|
||||||
|
|
||||||
public void RegisterTile()
|
public void RegisterTile()
|
||||||
{
|
{
|
||||||
|
|
@ -16,4 +18,4 @@ class TileRegistry
|
||||||
{
|
{
|
||||||
return this.Tiles[id];
|
return this.Tiles[id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using mine2d.core.data;
|
||||||
|
|
||||||
|
namespace mine2d.core.world;
|
||||||
|
|
||||||
class ChunkGenerator
|
class ChunkGenerator
|
||||||
{
|
{
|
||||||
public static Chunk CreateFilledChunk(int x, int y, STile fill)
|
public static Chunk CreateFilledChunk(int x, int y, STile fill)
|
||||||
|
|
@ -12,4 +16,4 @@ class ChunkGenerator
|
||||||
}
|
}
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
enum Sound { }
|
enum Sound { }
|
||||||
|
|
||||||
class AudioPlayer
|
class AudioPlayer
|
||||||
|
|
@ -12,7 +14,7 @@ class AudioPlayer
|
||||||
|
|
||||||
public void Register(Sound name, string path)
|
public void Register(Sound name, string path)
|
||||||
{
|
{
|
||||||
var buffer = resourceLoader.LoadBytes(path);
|
var buffer = this.resourceLoader.LoadBytes(path);
|
||||||
this.audioFiles.Add(name, buffer);
|
this.audioFiles.Add(name, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,4 +24,4 @@ class AudioPlayer
|
||||||
var sound = SDL2.SDL_mixer.Mix_QuickLoad_WAV(buffer);
|
var sound = SDL2.SDL_mixer.Mix_QuickLoad_WAV(buffer);
|
||||||
SDL2.SDL_mixer.Mix_PlayChannel((int)name, sound, 0);
|
SDL2.SDL_mixer.Mix_PlayChannel((int)name, sound, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using static SDL2.SDL_ttf;
|
namespace mine2d.engine;
|
||||||
using static SDL2.SDL;
|
|
||||||
|
|
||||||
class FontManager
|
class FontManager
|
||||||
{
|
{
|
||||||
|
|
@ -17,20 +16,20 @@ class FontManager
|
||||||
|
|
||||||
public void RegisterFont(string name, string path, int fontSize)
|
public void RegisterFont(string name, string path, int fontSize)
|
||||||
{
|
{
|
||||||
if (fonts.ContainsKey(name))
|
if (this.fonts.ContainsKey(name))
|
||||||
return;
|
return;
|
||||||
var res = resourceLoader.LoadToIntPtr(path);
|
var res = this.resourceLoader.LoadToIntPtr(path);
|
||||||
var sdlBuffer = SDL_RWFromConstMem(res.ptr, res.size);
|
var sdlBuffer = SDL_RWFromConstMem(res.ptr, res.size);
|
||||||
var font = TTF_OpenFontRW(sdlBuffer, 1, fontSize);
|
var font = TTF_OpenFontRW(sdlBuffer, 1, fontSize);
|
||||||
if (font == IntPtr.Zero)
|
if (font == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception("TTF_OpenFont failed");
|
throw new Exception("TTF_OpenFont failed");
|
||||||
}
|
}
|
||||||
fonts.Add(name, font);
|
this.fonts.Add(name, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntPtr GetFont(string name)
|
public IntPtr GetFont(string name)
|
||||||
{
|
{
|
||||||
return fonts[name];
|
return this.fonts[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,30 +1,34 @@
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
abstract class Game
|
abstract class Game
|
||||||
{
|
{
|
||||||
public const int TPS = 128;
|
public const int Tps = 128;
|
||||||
private Queue<int> fpsQueue = new Queue<int>();
|
|
||||||
protected abstract void update(double dt);
|
private bool running = true;
|
||||||
protected abstract void draw();
|
private Queue<int> fpsQueue = new();
|
||||||
|
protected abstract void Update(double dt);
|
||||||
|
protected abstract void Draw();
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
var tLast = DateTime.Now;
|
var tLast = DateTime.Now;
|
||||||
var tAcc = TimeSpan.Zero;
|
var tAcc = TimeSpan.Zero;
|
||||||
while (true)
|
while (this.running)
|
||||||
{
|
{
|
||||||
var dt = DateTime.Now - tLast;
|
var dt = DateTime.Now - tLast;
|
||||||
tLast = DateTime.Now;
|
tLast = DateTime.Now;
|
||||||
tAcc += dt;
|
tAcc += dt;
|
||||||
var fps = (int)(1 / dt.TotalSeconds);
|
var fps = (int)(1 / dt.TotalSeconds);
|
||||||
fpsQueue.Enqueue(fps);
|
this.fpsQueue.Enqueue(fps);
|
||||||
while (fpsQueue.Count > fps)
|
while (this.fpsQueue.Count > fps)
|
||||||
fpsQueue.Dequeue();
|
this.fpsQueue.Dequeue();
|
||||||
while (tAcc >= TimeSpan.FromSeconds(1.0 / TPS))
|
while (tAcc >= TimeSpan.FromSeconds(1.0 / Tps))
|
||||||
{
|
{
|
||||||
update(dt.TotalSeconds);
|
this.Update(dt.TotalSeconds);
|
||||||
tAcc -= TimeSpan.FromSeconds(1.0 / TPS);
|
tAcc -= TimeSpan.FromSeconds(1.0 / Tps);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw();
|
this.Draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
class PacketUtils
|
using mine2d.backend.data;
|
||||||
|
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
|
public static class PacketUtils
|
||||||
{
|
{
|
||||||
public static string GetType(ValueType packet)
|
public static string GetType(ValueType packet)
|
||||||
{
|
{
|
||||||
|
|
@ -7,16 +11,16 @@ class PacketUtils
|
||||||
{
|
{
|
||||||
Console.WriteLine(pp.Name);
|
Console.WriteLine(pp.Name);
|
||||||
}
|
}
|
||||||
var p = t.GetField("type");
|
var p = t.GetField(nameof(IPacket.Type));
|
||||||
if (p == null)
|
if (p == null)
|
||||||
{
|
{
|
||||||
throw new Exception("p undef");
|
throw new ArgumentNullException(nameof(p), "p undef");
|
||||||
}
|
}
|
||||||
var v = p.GetValue(packet);
|
var v = p.GetValue(packet);
|
||||||
if (v == null)
|
if (v == null)
|
||||||
{
|
{
|
||||||
throw new Exception("v undef");
|
throw new ArgumentNullException(nameof(v), "v undef");
|
||||||
}
|
}
|
||||||
return (string)v;
|
return (string)v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
|
using mine2d.engine.utils;
|
||||||
|
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
class Renderer
|
class Renderer
|
||||||
{
|
{
|
||||||
private IntPtr renderer;
|
private readonly IntPtr renderer;
|
||||||
private IntPtr font;
|
private IntPtr font;
|
||||||
private SDL_Color color;
|
private SDL_Color color;
|
||||||
|
|
||||||
|
|
@ -15,13 +19,13 @@ class Renderer
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(this.renderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(this.renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Present()
|
public void Present()
|
||||||
{
|
{
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(this.renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawRect(double x, double y, int w, int h)
|
public void DrawRect(double x, double y, int w, int h)
|
||||||
|
|
@ -31,13 +35,15 @@ class Renderer
|
||||||
|
|
||||||
public void DrawRect(int x, int y, int w, int h)
|
public void DrawRect(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
SDL_Rect rect = new SDL_Rect();
|
var rect = new SDL_Rect
|
||||||
rect.x = x;
|
{
|
||||||
rect.y = y;
|
x = x,
|
||||||
rect.w = w;
|
y = y,
|
||||||
rect.h = h;
|
w = w,
|
||||||
|
h = h
|
||||||
|
};
|
||||||
|
|
||||||
SDL_RenderFillRect(renderer, ref rect);
|
SDL_RenderFillRect(this.renderer, ref rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawOutline(int x, int y, int w, int h)
|
public void DrawOutline(int x, int y, int w, int h)
|
||||||
|
|
@ -50,24 +56,24 @@ class Renderer
|
||||||
h = h
|
h = h
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = SDL_RenderDrawRect(renderer, ref rect);
|
_ = SDL_RenderDrawRect(this.renderer, ref rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawLines(double[][] points)
|
public void DrawLines(double[][] points)
|
||||||
{
|
{
|
||||||
SDL_Point[] sdlPoints = new SDL_Point[points.Length];
|
var sdlPoints = new SDL_Point[points.Length];
|
||||||
for (int i = 0; i < points.Length; i++)
|
for (var i = 0; i < points.Length; i++)
|
||||||
{
|
{
|
||||||
sdlPoints[i].x = (int)points[i][0];
|
sdlPoints[i].x = (int)points[i][0];
|
||||||
sdlPoints[i].y = (int)points[i][1];
|
sdlPoints[i].y = (int)points[i][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderDrawLines(renderer, sdlPoints, points.Length);
|
SDL_RenderDrawLines(this.renderer, sdlPoints, points.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetColor(int r, int g, int b, int a = 255)
|
public void SetColor(int r, int g, int b, int a = 255)
|
||||||
{
|
{
|
||||||
SDL_SetRenderDrawColor(renderer, (byte)r, (byte)g, (byte)b, (byte)a);
|
SDL_SetRenderDrawColor(this.renderer, (byte)r, (byte)g, (byte)b, (byte)a);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFont(IntPtr font, SDL_Color color)
|
public void SetFont(IntPtr font, SDL_Color color)
|
||||||
|
|
@ -79,24 +85,23 @@ class Renderer
|
||||||
public void SetFont(IntPtr font, Color color)
|
public void SetFont(IntPtr font, Color color)
|
||||||
{
|
{
|
||||||
this.font = font;
|
this.font = font;
|
||||||
this.color = color.toSDLColor();
|
this.color = color.ToSdlColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawText(string text, int x, int y, bool center = false)
|
public void DrawText(string text, int x, int y, bool center = false)
|
||||||
{
|
{
|
||||||
var surfaceMessage = TTF_RenderText_Solid(this.font, text, this.color);
|
var surfaceMessage = TTF_RenderText_Solid(this.font, text, this.color);
|
||||||
|
|
||||||
var texture = SDL_CreateTextureFromSurface(this.renderer, surfaceMessage);
|
var texture = SDL_CreateTextureFromSurface(this.renderer, surfaceMessage);
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
SDL_QueryTexture(texture, out _, out _, out width, out height);
|
SDL_QueryTexture(texture, out _, out _, out var width, out var height);
|
||||||
|
|
||||||
SDL_Rect rect = new SDL_Rect();
|
var rect = new SDL_Rect
|
||||||
rect.x = x;
|
{
|
||||||
rect.y = y;
|
x = x,
|
||||||
rect.w = width;
|
y = y,
|
||||||
rect.h = height;
|
w = width,
|
||||||
|
h = height
|
||||||
|
};
|
||||||
|
|
||||||
if (center)
|
if (center)
|
||||||
{
|
{
|
||||||
|
|
@ -111,12 +116,12 @@ class Renderer
|
||||||
|
|
||||||
public IntPtr GetRaw()
|
public IntPtr GetRaw()
|
||||||
{
|
{
|
||||||
return renderer;
|
return this.renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntPtr CreateTextureFromSurface(IntPtr surface)
|
public IntPtr CreateTextureFromSurface(IntPtr surface)
|
||||||
{
|
{
|
||||||
return SDL_CreateTextureFromSurface(renderer, surface);
|
return SDL_CreateTextureFromSurface(this.renderer, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawTexture(IntPtr texture, int x, int y, int w, int h)
|
public void DrawTexture(IntPtr texture, int x, int y, int w, int h)
|
||||||
|
|
@ -149,4 +154,4 @@ class Renderer
|
||||||
};
|
};
|
||||||
_ = SDL_RenderCopy(this.renderer, texture, ref srcRect, ref rect);
|
_ = SDL_RenderCopy(this.renderer, texture, ref srcRect, ref rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
class ResourceLoader
|
class ResourceLoader
|
||||||
{
|
{
|
||||||
private string assemblyName;
|
private string assemblyName;
|
||||||
|
|
@ -14,11 +16,12 @@ class ResourceLoader
|
||||||
#if (DEBUG)
|
#if (DEBUG)
|
||||||
Console.WriteLine("Loading resource: " + resourceName);
|
Console.WriteLine("Loading resource: " + resourceName);
|
||||||
return File.ReadAllText(ToPath(resourceName));
|
return File.ReadAllText(ToPath(resourceName));
|
||||||
#endif
|
#else
|
||||||
using var stream = this.GetType()
|
using var stream = this.GetType()
|
||||||
.Assembly.GetManifestResourceStream($"{this.assemblyName}.{resourceName}");
|
.Assembly.GetManifestResourceStream($"{this.assemblyName}.{resourceName}");
|
||||||
using var reader = new StreamReader(stream!);
|
using var reader = new StreamReader(stream!);
|
||||||
return reader.ReadToEnd();
|
return reader.ReadToEnd();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] LoadBytes(string resourceName)
|
public byte[] LoadBytes(string resourceName)
|
||||||
|
|
@ -49,4 +52,4 @@ class ResourceLoader
|
||||||
var s = resourceName.Split('.');
|
var s = resourceName.Split('.');
|
||||||
return String.Join('/', s[..^1]) + "." + s[^1];
|
return String.Join('/', s[..^1]) + "." + s[^1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
struct Line
|
struct Line
|
||||||
{
|
{
|
||||||
public Vector2 start;
|
public Vector2 Start;
|
||||||
public Vector2 end;
|
public Vector2 End;
|
||||||
|
|
||||||
public Line(Vector2 start, Vector2 end)
|
public Line(Vector2 start, Vector2 end)
|
||||||
{
|
{
|
||||||
this.start = start;
|
this.Start = start;
|
||||||
this.end = end;
|
this.End = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
|
namespace mine2d.engine;
|
||||||
|
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
IntPtr window;
|
IntPtr window;
|
||||||
|
|
||||||
public Window(string title, int w, int h)
|
public Window(string title, int w, int h)
|
||||||
{
|
{
|
||||||
window = SDL_CreateWindow(
|
this.window = SDL_CreateWindow(
|
||||||
title,
|
title,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
|
@ -41,4 +43,4 @@ class Window
|
||||||
{
|
{
|
||||||
return this.window;
|
return this.window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
enum EventPriority : int
|
namespace mine2d.engine.system;
|
||||||
|
|
||||||
|
enum EventPriority
|
||||||
{
|
{
|
||||||
Lowest = 0,
|
Lowest = 0,
|
||||||
Low = 1,
|
Low = 1,
|
||||||
|
|
@ -6,4 +8,4 @@ enum EventPriority : int
|
||||||
High = 3,
|
High = 3,
|
||||||
Highest = 4,
|
Highest = 4,
|
||||||
Important = 5,
|
Important = 5,
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
namespace mine2d.engine.system.annotations;
|
||||||
|
|
||||||
enum InteractorKind
|
enum InteractorKind
|
||||||
{
|
{
|
||||||
Client,
|
Client,
|
||||||
|
|
@ -19,4 +21,4 @@ class Interaction : Attribute
|
||||||
this.Type = type;
|
this.Type = type;
|
||||||
this.Kind = kind;
|
this.Kind = kind;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,33 +1,35 @@
|
||||||
|
namespace mine2d.engine.utils;
|
||||||
|
|
||||||
class Color
|
class Color
|
||||||
{
|
{
|
||||||
public int r,
|
public int R,
|
||||||
g,
|
G,
|
||||||
b,
|
B,
|
||||||
a;
|
A;
|
||||||
|
|
||||||
public Color(int r, int g, int b, int a)
|
public Color(int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
this.r = r;
|
this.R = r;
|
||||||
this.g = g;
|
this.G = g;
|
||||||
this.b = b;
|
this.B = b;
|
||||||
this.a = a;
|
this.A = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color(int r, int g, int b)
|
public Color(int r, int g, int b)
|
||||||
{
|
{
|
||||||
this.r = r;
|
this.R = r;
|
||||||
this.g = g;
|
this.G = g;
|
||||||
this.b = b;
|
this.B = b;
|
||||||
this.a = 255;
|
this.A = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SDL_Color toSDLColor()
|
public SDL_Color ToSdlColor()
|
||||||
{
|
{
|
||||||
SDL_Color color = new();
|
SDL_Color color = new();
|
||||||
color.r = (byte)r;
|
color.r = (byte)this.R;
|
||||||
color.g = (byte)g;
|
color.g = (byte)this.G;
|
||||||
color.b = (byte)b;
|
color.b = (byte)this.B;
|
||||||
color.a = (byte)a;
|
color.a = (byte)this.A;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
namespace mine2d.engine.utils;
|
||||||
|
|
||||||
class Point
|
class Point
|
||||||
{
|
{
|
||||||
public static double Distance(double x1, double y1, double x2, double y2)
|
public static double Distance(double x1, double y1, double x2, double y2)
|
||||||
{
|
{
|
||||||
return Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
|
return Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
using mine2d.backend.data;
|
||||||
|
using mine2d.core;
|
||||||
|
using mine2d.core.data;
|
||||||
|
using mine2d.frontend.renderer;
|
||||||
|
|
||||||
|
namespace mine2d.frontend;
|
||||||
|
|
||||||
class Frontend : IFrontend
|
class Frontend : IFrontend
|
||||||
{
|
{
|
||||||
public void Init()
|
public void Init()
|
||||||
|
|
@ -44,7 +51,7 @@ class Frontend : IFrontend
|
||||||
}
|
}
|
||||||
if (e.type == SDL_EventType.SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT)
|
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;
|
var amp = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + ctx.FrontendGameState.Camera.Position;
|
||||||
if (ctx.GameState.World.HasChunkAt(amp))
|
if (ctx.GameState.World.HasChunkAt(amp))
|
||||||
{
|
{
|
||||||
var chunk = ctx.GameState.World.GetChunkAt(amp);
|
var chunk = ctx.GameState.World.GetChunkAt(amp);
|
||||||
|
|
@ -122,9 +129,9 @@ class Frontend : IFrontend
|
||||||
if (
|
if (
|
||||||
e.key.keysym.scancode
|
e.key.keysym.scancode
|
||||||
is SDL_Scancode.SDL_SCANCODE_A
|
is SDL_Scancode.SDL_SCANCODE_A
|
||||||
or SDL_Scancode.SDL_SCANCODE_D
|
or SDL_Scancode.SDL_SCANCODE_D
|
||||||
or SDL_Scancode.SDL_SCANCODE_W
|
or SDL_Scancode.SDL_SCANCODE_W
|
||||||
or SDL_Scancode.SDL_SCANCODE_S
|
or SDL_Scancode.SDL_SCANCODE_S
|
||||||
&& e.key.repeat == 0
|
&& e.key.repeat == 0
|
||||||
&& e.type is SDL_EventType.SDL_KEYDOWN or SDL_EventType.SDL_KEYUP
|
&& e.type is SDL_EventType.SDL_KEYDOWN or SDL_EventType.SDL_KEYUP
|
||||||
)
|
)
|
||||||
|
|
@ -156,29 +163,29 @@ class Frontend : IFrontend
|
||||||
{
|
{
|
||||||
if (player.Name == ctx.FrontendGameState.PlayerName)
|
if (player.Name == ctx.FrontendGameState.PlayerName)
|
||||||
{
|
{
|
||||||
ctx.Renderer.SetColor(0, 0, 255, 255);
|
ctx.Renderer.SetColor(0, 0, 255);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx.Renderer.SetColor(255, 0, 0, 255);
|
ctx.Renderer.SetColor(255, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Renderer.DrawRect(
|
ctx.Renderer.DrawRect(
|
||||||
(player.Position.X - (int)camera.position.X) * scale,
|
(player.Position.X - (int)camera.Position.X) * scale,
|
||||||
(player.Position.Y - (int)camera.position.Y) * scale - 32 * scale,
|
(player.Position.Y - (int)camera.Position.Y) * scale - 32 * scale,
|
||||||
16 * scale,
|
16 * scale,
|
||||||
32 * scale
|
32 * scale
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
var absoluteMousePos = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + camera.position;
|
var absoluteMousePos = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + camera.Position;
|
||||||
if (ctx.GameState.World.HasTileAt((int)absoluteMousePos.X, (int)absoluteMousePos.Y))
|
if (ctx.GameState.World.HasTileAt((int)absoluteMousePos.X, (int)absoluteMousePos.Y))
|
||||||
{
|
{
|
||||||
var a = Constants.TileSize;
|
var a = Constants.TileSize;
|
||||||
var tilePos = new Vector2(absoluteMousePos.X - absoluteMousePos.X % a, absoluteMousePos.Y - absoluteMousePos.Y % a);
|
var tilePos = new Vector2(absoluteMousePos.X - absoluteMousePos.X % a, absoluteMousePos.Y - absoluteMousePos.Y % a);
|
||||||
ctx.Renderer.SetColor(255, 255, 255, 255);
|
ctx.Renderer.SetColor(255, 255, 255);
|
||||||
ctx.Renderer.DrawOutline(
|
ctx.Renderer.DrawOutline(
|
||||||
(int)tilePos.X * scale - (int)camera.position.X * scale,
|
(int)tilePos.X * scale - (int)camera.Position.X * scale,
|
||||||
(int)tilePos.Y * scale - (int)camera.position.Y * scale,
|
(int)tilePos.Y * scale - (int)camera.Position.Y * scale,
|
||||||
16 * scale,
|
16 * scale,
|
||||||
16 * scale
|
16 * scale
|
||||||
);
|
);
|
||||||
|
|
@ -186,4 +193,4 @@ class Frontend : IFrontend
|
||||||
|
|
||||||
ctx.Renderer.Present();
|
ctx.Renderer.Present();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
namespace mine2d.frontend;
|
||||||
|
|
||||||
interface IFrontend
|
interface IFrontend
|
||||||
{
|
{
|
||||||
public void Process();
|
public void Process();
|
||||||
public void Init();
|
public void Init();
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
namespace mine2d.frontend.renderer;
|
||||||
|
|
||||||
interface IRenderer
|
interface IRenderer
|
||||||
{
|
{
|
||||||
public void Render();
|
public void Render();
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using mine2d.core;
|
||||||
|
|
||||||
|
namespace mine2d.frontend.renderer;
|
||||||
|
|
||||||
class WorldRenderer : IRenderer
|
class WorldRenderer : IRenderer
|
||||||
{
|
{
|
||||||
public void Render()
|
public void Render()
|
||||||
|
|
@ -25,4 +29,4 @@ class WorldRenderer : IRenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Newtonsoft.Json.Linq;
|
using mine2d.backend.data;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace mine2d.network;
|
||||||
|
|
||||||
class Converter
|
class Converter
|
||||||
{
|
{
|
||||||
|
|
@ -33,4 +36,4 @@ class Converter
|
||||||
var jsonString = JsonConvert.SerializeObject(packet);
|
var jsonString = JsonConvert.SerializeObject(packet);
|
||||||
return Encoding.UTF8.GetBytes(jsonString);
|
return Encoding.UTF8.GetBytes(jsonString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
using mine2d.core;
|
||||||
|
using mine2d.core.data;
|
||||||
|
|
||||||
|
namespace mine2d.state;
|
||||||
|
|
||||||
class FrontendGameState
|
class FrontendGameState
|
||||||
{
|
{
|
||||||
public Vector2 MovementInput;
|
public Vector2 MovementInput;
|
||||||
|
|
@ -14,7 +19,7 @@ class FrontendGameState
|
||||||
class Settings
|
class Settings
|
||||||
{
|
{
|
||||||
public int GameScale = 4;
|
public int GameScale = 4;
|
||||||
public int UIScale = 4;
|
public int UiScale = 4;
|
||||||
public bool ShowCollision = true;
|
public bool ShowCollision = true;
|
||||||
public bool Fullscreen = false;
|
public bool Fullscreen = false;
|
||||||
}
|
}
|
||||||
|
|
@ -23,4 +28,4 @@ class GameState
|
||||||
{
|
{
|
||||||
public List<Player> Players { get; set; } = new List<Player>();
|
public List<Player> Players { get; set; } = new List<Player>();
|
||||||
public World World { get; set; }
|
public World World { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using mine2d.engine;
|
||||||
|
|
||||||
|
namespace mine2d.state;
|
||||||
|
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
public string Name;
|
public string Name;
|
||||||
|
|
@ -11,4 +15,4 @@ class Player
|
||||||
{
|
{
|
||||||
return new Line(this.Position, this.Position + new Vector2(16, 0));
|
return new Line(this.Position, this.Position + new Vector2(16, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue