diff options
| author | Joel Stålnacke <joel@saker.fi> | 2025-07-26 21:09:26 +0300 |
|---|---|---|
| committer | Joel Stålnacke <joel@saker.fi> | 2025-07-26 21:09:26 +0300 |
| commit | 63506e59366acddf4a9e017ad8aebeadcf58c164 (patch) | |
| tree | 2fa106661b85497fc1d63b7743a78e523ab48fba /client | |
| parent | 53f68bb7b0dce309723675c4b97f726a469031c0 (diff) | |
Diffstat (limited to 'client')
| -rw-r--r-- | client/Game.cs | 37 | ||||
| -rw-r--r-- | client/Player.cs | 24 | ||||
| -rw-r--r-- | client/Root.cs | 87 | ||||
| -rw-r--r-- | client/World.cs | 75 | ||||
| -rw-r--r-- | client/game.tscn | 13 | ||||
| -rw-r--r-- | client/player.tscn | 6 | ||||
| -rw-r--r-- | client/project.godot | 25 | ||||
| -rw-r--r-- | client/root.tscn | 6 | ||||
| -rw-r--r-- | client/world.tscn | 6 |
9 files changed, 185 insertions, 94 deletions
diff --git a/client/Game.cs b/client/Game.cs new file mode 100644 index 0000000..6bf6192 --- /dev/null +++ b/client/Game.cs @@ -0,0 +1,37 @@ +using Godot; +using System; +using Djup.Native; + +public partial class Game : Node2D +{ + private World world; + + private int[] balls = new int[100]; + private Random rng = new(); + + // Called when the node enters the scene tree for the first time. + public unsafe override void _Ready() + { + RenderingServer.SetDefaultClearColor(Colors.LightGray); + LibDjup.log_set_output((level, source, line, msg) => { + string level_name = level switch + { + LogLevel.Trace => "trace", + LogLevel.Debug => "debug", + LogLevel.Info => " info", + LogLevel.Warn => " warn", + LogLevel.Error => "error", + LogLevel.Fatal => "fatal", + _ => "UNKNOWN" + }; + GD.Print($"libdjup {source.PadLeft(10)}:{line.ToString().PadRight(3)} {level_name}: {msg}"); + }); + + world = GetNode<World>("World"); + + world.PutPlayer(0, new Djup.Native.Player() + { + Position = new Vec2(100f, 100f), + }); + } +} diff --git a/client/Player.cs b/client/Player.cs new file mode 100644 index 0000000..da95275 --- /dev/null +++ b/client/Player.cs @@ -0,0 +1,24 @@ +using Godot; +using System; +using Djup.Native; + +public partial class Player : Node2D +{ + [Export] + public World World { get; set; } + public uint Id { get; set; } = 0; + + public unsafe override void _Process(double delta) + { + byte input = 0; + if (Input.IsActionPressed("up")) + input |= (byte)PlayerInput.Up; + if (Input.IsActionPressed("down")) + input |= (byte)PlayerInput.Down; + if (Input.IsActionPressed("left")) + input |= (byte)PlayerInput.Left; + if (Input.IsActionPressed("right")) + input |= (byte)PlayerInput.Right; + World.SetPlayerInput(Id, input); + } +} diff --git a/client/Root.cs b/client/Root.cs deleted file mode 100644 index dfbf0da..0000000 --- a/client/Root.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Godot; -using System; -using Djup.Native; - -public partial class Root : Node2D -{ - private IntPtr native_world; - private int[] balls = new int[100]; - private Random rng = new(); - private const double Tps = 1d/60d; - - // Called when the node enters the scene tree for the first time. - public unsafe override void _Ready() - { - RenderingServer.SetDefaultClearColor(Colors.LightGray); - LibDjup.log_set_output((level, source, line, msg) => { - string level_name = level switch - { - LogLevel.Trace => "trace", - LogLevel.Debug => "debug", - LogLevel.Info => "info", - LogLevel.Warn => "warn", - LogLevel.Error => "error", - LogLevel.Fatal => "fatal" - }; - GD.Print($"libdjup {source}:{line} {level_name.PadLeft(5, ' ')}: {msg}"); - }); - - native_world = LibDjup.world_create(); - for (int i = 0; i < balls.Length; i++) - { - int id = LibDjup.world_create_entity(native_world, EntityKind.Ball); - if (id < 0) - { - throw new Exception("Failed to create entity"); - } - balls[i] = id; - Entity *ent; - var pos = new Vec2(5f * rng.Next(10), 5f * rng.Next(20)); - var vel = LibDjup.vec2_mul(LibDjup.vec2_normal(new Vec2(50f + 5f * rng.Next(10), 50f)), 25.0f); - GD.Print(vel, " --> ", LibDjup.vec2_length(vel)); - ent = LibDjup.world_find_entity(native_world, balls[i]); - ent->ball.Position = pos; - ent->ball.Velocity = vel; - } - } - - public override void _ExitTree() - { - LibDjup.world_free(native_world); - } - - private void DrawBall(Ball ball) - { - //Color color = rng.Next(5) switch - //{ - //0 => Colors.Black, - //1 => Colors.Blue, - //2 => Colors.Red, - //3 => Colors.Green, - //4 => Colors.Pink - //}; - Color color = Colors.Blue; - this.DrawCircle(new Vector2(ball.Position.X, ball.Position.Y), 5f, color, antialiased: true); - } - - public unsafe override void _Draw() - { - for (int i = 0; i < balls.Length; i++) - { - DrawBall(LibDjup.world_find_entity(native_world, balls[i])->ball); - } - } - - public override void _Process(double delta) - { - this.QueueRedraw(); - } - - public override void _PhysicsProcess(double delta) - { - if (LibDjup.world_tick(native_world, Tps) != 0) - { - GD.Print("world_tick failed"); - } - } -} diff --git a/client/World.cs b/client/World.cs new file mode 100644 index 0000000..8f5dfb6 --- /dev/null +++ b/client/World.cs @@ -0,0 +1,75 @@ +using Godot; +using System; +using Djup.Native; + +public partial class World : Node2D +{ + private IntPtr context; + private IntPtr currentSnapshot; + public const double Tps = 1d/60d; + + public unsafe override void _Ready() + { + context = LibDjup.physics_context_create(2); + currentSnapshot = LibDjup.physics_context_get_snapshot(context); + } + + public override void _ExitTree() + { + LibDjup.physics_context_free(context); + } + + public unsafe void PutPlayer(uint id, Djup.Native.Player player) + { + if (LibDjup.snapshot_put_player(currentSnapshot, id, &player) != 0) + { + throw new Exception($"Failed to put player {id}"); + } + } + + public void SetPlayerInput(uint playerId, byte input) + { + int ret = LibDjup.snapshot_set_player_input(currentSnapshot, playerId, input); + if (ret != 0) + { + throw new Exception($"Failed to set input of player {playerId}: {ret}"); + } + } + + private unsafe void DrawPlayer(Djup.Native.Player player) + { + float radius = 50f; + this.DrawCircle(new Vector2(player.Position.X, player.Position.Y), radius, Colors.DarkBlue, antialiased: true); + this.DrawCircle(new Vector2(player.Position.X, player.Position.Y), radius * 0.90f, Colors.Blue, antialiased: true); + } + + public unsafe override void _Draw() + { + Snapshot *s = (Snapshot *)currentSnapshot; + + for (int i = 0; i < Constants.WorldMaxPlayers; i++) + { + var p = s->Players[i]; + if (p.State == EntityState.Active) + { + DrawPlayer(p); + } + } + } + + public override void _Process(double delta) + { + this.QueueRedraw(); + } + + public override void _PhysicsProcess(double delta) + { + IntPtr next = LibDjup.physics_context_get_snapshot(context); + if (LibDjup.physics_tick(currentSnapshot, Tps, next) != 0) + { + throw new Exception("World tick failed"); + } + LibDjup.physics_context_return_snapshot(context, currentSnapshot); + currentSnapshot = next; + } +} diff --git a/client/game.tscn b/client/game.tscn new file mode 100644 index 0000000..4ec7809 --- /dev/null +++ b/client/game.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=4 format=3 uid="uid://w0k2j13hm04i"] + +[ext_resource type="Script" path="res://Game.cs" id="1_t8lam"] +[ext_resource type="PackedScene" uid="uid://drdk1by1fun2q" path="res://world.tscn" id="2_tm4sj"] +[ext_resource type="PackedScene" uid="uid://b0f23dtef1o4h" path="res://player.tscn" id="3_caccr"] + +[node name="Game" type="Node2D"] +script = ExtResource("1_t8lam") + +[node name="World" parent="." instance=ExtResource("2_tm4sj")] + +[node name="Player" parent="." node_paths=PackedStringArray("World") instance=ExtResource("3_caccr")] +World = NodePath("../World") diff --git a/client/player.tscn b/client/player.tscn new file mode 100644 index 0000000..b1f9f5f --- /dev/null +++ b/client/player.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://b0f23dtef1o4h"] + +[ext_resource type="Script" path="res://Player.cs" id="1_bjul0"] + +[node name="Player" type="Node2D"] +script = ExtResource("1_bjul0") diff --git a/client/project.godot b/client/project.godot index 6107d87..403aac4 100644 --- a/client/project.godot +++ b/client/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="Djup" -run/main_scene="res://root.tscn" +run/main_scene="res://game.tscn" config/features=PackedStringArray("4.3", "C#", "Forward Plus") config/icon="res://icon.svg" @@ -22,3 +22,26 @@ window/stretch/mode="canvas_items" [dotnet] project/assembly_name="Djup" + +[input] + +left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} diff --git a/client/root.tscn b/client/root.tscn deleted file mode 100644 index ded95a0..0000000 --- a/client/root.tscn +++ /dev/null @@ -1,6 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://drdk1by1fun2q"] - -[ext_resource type="Script" path="res://Root.cs" id="1_p5oo0"] - -[node name="Root" type="Node2D"] -script = ExtResource("1_p5oo0") diff --git a/client/world.tscn b/client/world.tscn new file mode 100644 index 0000000..0055d3b --- /dev/null +++ b/client/world.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://drdk1by1fun2q"] + +[ext_resource type="Script" path="res://World.cs" id="1_7wii1"] + +[node name="World" type="Node2D"] +script = ExtResource("1_7wii1") |
