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; } }