From 745406dc65aecc438a53f96badc387a32b7a338f Mon Sep 17 00:00:00 2001 From: Joel Stålnacke Date: Thu, 19 Mar 2026 22:30:56 +0200 Subject: Add Mibo project The Djup project is DesktopGL project --- .config/dotnet-tools.json | 36 +++++ Djup.Native/AddRuntimeTargetsToDepsJson.targets | 12 -- Djup.Native/Constants.cs | 7 - Djup.Native/Djup.Native.csproj | 39 ------ Djup.Native/LibDjup.cs | 54 -------- Djup.Native/Program.cs | 3 - Djup.Native/Types.cs | 89 ------------ Djup.Native/patch-deps.sh | 4 - .../scripts/AddRuntimeTargetsToDepsJson.targets | 12 ++ Djup.Native/scripts/patch-deps.sh | 4 + Djup.Native/src/Constants.cs | 7 + Djup.Native/src/Djup.Native.csproj | 40 ++++++ Djup.Native/src/LibDjup.cs | 54 ++++++++ Djup.Native/src/Program.cs | 3 + Djup.Native/src/Types.cs | 89 ++++++++++++ Djup.Native/src/packages.lock.json | 6 + Djup.Testing/src/Djup.Testing.fsproj | 1 + Djup.Testing/src/packages.lock.json | 31 +++++ Djup.slnx | 9 +- Djup/src/Content/Content.mgcb | 14 ++ Djup/src/Djup.fsproj | 32 +++++ Djup/src/Icon.bmp | Bin 0 -> 262282 bytes Djup/src/Icon.ico | Bin 0 -> 147541 bytes Djup/src/Program.fs | 153 +++++++++++++++++++++ Djup/src/app.manifest | 29 ++++ Djup/src/packages.lock.json | 72 ++++++++++ 26 files changed, 591 insertions(+), 209 deletions(-) create mode 100644 .config/dotnet-tools.json delete mode 100644 Djup.Native/AddRuntimeTargetsToDepsJson.targets delete mode 100644 Djup.Native/Constants.cs delete mode 100644 Djup.Native/Djup.Native.csproj delete mode 100644 Djup.Native/LibDjup.cs delete mode 100644 Djup.Native/Program.cs delete mode 100644 Djup.Native/Types.cs delete mode 100755 Djup.Native/patch-deps.sh create mode 100644 Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets create mode 100755 Djup.Native/scripts/patch-deps.sh create mode 100644 Djup.Native/src/Constants.cs create mode 100644 Djup.Native/src/Djup.Native.csproj create mode 100644 Djup.Native/src/LibDjup.cs create mode 100644 Djup.Native/src/Program.cs create mode 100644 Djup.Native/src/Types.cs create mode 100644 Djup.Native/src/packages.lock.json create mode 100644 Djup.Testing/src/packages.lock.json create mode 100644 Djup/src/Content/Content.mgcb create mode 100644 Djup/src/Djup.fsproj create mode 100644 Djup/src/Icon.bmp create mode 100644 Djup/src/Icon.ico create mode 100644 Djup/src/Program.fs create mode 100644 Djup/src/app.manifest create mode 100644 Djup/src/packages.lock.json diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..a4ce7f6 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,36 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-mgcb": { + "version": "3.8.4", + "commands": ["mgcb"], + "rollForward": false + }, + "dotnet-mgcb-editor": { + "version": "3.8.4", + "commands": ["mgcb-editor"], + "rollForward": false + }, + "dotnet-mgcb-editor-linux": { + "version": "3.8.4", + "commands": ["mgcb-editor-linux"], + "rollForward": false + }, + "dotnet-mgcb-editor-windows": { + "version": "3.8.4", + "commands": ["mgcb-editor-windows"], + "rollForward": false + }, + "dotnet-mgcb-editor-mac": { + "version": "3.8.4", + "commands": ["mgcb-editor-mac"], + "rollForward": false + }, + "fantomas": { + "version": "7.0.2", + "commands": ["fantomas"], + "rollForward": false + } + } +} diff --git a/Djup.Native/AddRuntimeTargetsToDepsJson.targets b/Djup.Native/AddRuntimeTargetsToDepsJson.targets deleted file mode 100644 index fbb4c43..0000000 --- a/Djup.Native/AddRuntimeTargetsToDepsJson.targets +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/Djup.Native/Constants.cs b/Djup.Native/Constants.cs deleted file mode 100644 index 90692be..0000000 --- a/Djup.Native/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Djup.Native; - -public static class Constants -{ - public const int WorldMaxPlayers = 5; - public const int WorldMaxBullets = 5000; -} diff --git a/Djup.Native/Djup.Native.csproj b/Djup.Native/Djup.Native.csproj deleted file mode 100644 index f3c2781..0000000 --- a/Djup.Native/Djup.Native.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - net10.0 - enable - enable - true - - - - $(MSBuildThisFileDirectory)../lib/build - - - - - runtimes/linux-x64/native/libdjup.so - Always - runtimes/linux-x64/native/ - true - - - - - - - $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) - true - - - - - runtimes/linux-x64/native/libdjup.so - Always - - - - - - diff --git a/Djup.Native/LibDjup.cs b/Djup.Native/LibDjup.cs deleted file mode 100644 index 15dcdad..0000000 --- a/Djup.Native/LibDjup.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Djup.Native; - -public static partial class LibDjup -{ - const string LibraryName = "djup"; - const string Prefix = "dp_"; - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(hello_world))] - public static partial void hello_world(); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(get_num))] - public static partial int get_num(); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(get_vec2))] - public static partial Vec2 get_vec2(); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(vec2_mul))] - public static partial Vec2 vec2_mul(Vec2 v, float scalar); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(vec2_normal))] - public static partial Vec2 vec2_normal(Vec2 v); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(vec2_length))] - public static partial float vec2_length(Vec2 v); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(log_set_output))] - public static partial Vec2 log_set_output([MarshalAs(UnmanagedType.FunctionPtr)] LoggerDelegate logger); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(log_set_level))] - public static partial Vec2 log_set_level(LogLevel minLevel); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_create))] - public static partial IntPtr physics_context_create(uint snapshots); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_free))] - public static partial void physics_context_free(IntPtr context); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_get_snapshot))] - public static partial IntPtr physics_context_get_snapshot(IntPtr context); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_return_snapshot))] - public static partial void physics_context_return_snapshot(IntPtr context, IntPtr snapshot); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_tick))] - public static partial int physics_tick(IntPtr currentSnapshot, double delta, IntPtr nextSnapshot); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(snapshot_put_player))] - public static unsafe partial int snapshot_put_player(IntPtr snapshot, uint playerId, Player *player); - - [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(snapshot_set_player_input))] - public static partial int snapshot_set_player_input(IntPtr snapshot, uint playerId, byte input); -} diff --git a/Djup.Native/Program.cs b/Djup.Native/Program.cs deleted file mode 100644 index 1b374b8..0000000 --- a/Djup.Native/Program.cs +++ /dev/null @@ -1,3 +0,0 @@ -/*using Djup.Native;*/ -/**/ -/*LibDjup.hello_world();*/ diff --git a/Djup.Native/Types.cs b/Djup.Native/Types.cs deleted file mode 100644 index 7d9c41e..0000000 --- a/Djup.Native/Types.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Djup.Native; - -[StructLayout(LayoutKind.Sequential)] -public struct Vec2 -{ - public float X { get; } - public float Y { get; } - - public Vec2(float x, float y) - { - Debug.Assert(float.IsFinite(x)); - Debug.Assert(float.IsFinite(y)); - - X = x; - Y = y; - } - - public override string ToString() => $"({X}, {Y})"; -} - -public enum EntityState : byte -{ - Inactive = 0, - Active, - Removed, - Dead -} - -public enum PlayerInput : byte -{ - Up = 1 << 0, - Down = 1 << 1, - Left = 1 << 2, - Right = 1 << 3 -} - -[StructLayout(LayoutKind.Sequential)] -public struct Player -{ - public EntityState State { get; } - private byte input; - public Vec2 Position { get; set; } - public Vec2 Velocity { get; set; } -} - -[StructLayout(LayoutKind.Sequential)] -public struct Bullet -{ - public EntityState State { get; set; } - public Vec2 Position { get; set; } - public Vec2 Velocity { get; set; } -} - -[StructLayout(LayoutKind.Sequential)] -public struct Snapshot -{ - [InlineArray(Constants.WorldMaxPlayers)] - public struct PlayerArray - { - private Player _element0; - } - - [InlineArray(Constants.WorldMaxBullets)] - public struct BallArray - { - private Bullet _element0; - } - - private byte active; - public uint Tick { get; } - public PlayerArray Players { get; } - public BallArray Bullets { get; } -} - -public enum LogLevel -{ - Trace, - Debug, - Info, - Warn, - Error, - Fatal -} - -public delegate void LoggerDelegate(LogLevel level, string source, int line, string message); diff --git a/Djup.Native/patch-deps.sh b/Djup.Native/patch-deps.sh deleted file mode 100755 index 8015323..0000000 --- a/Djup.Native/patch-deps.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -depsjson="$(find "$1" -name '*.deps.json')" -patched="$(jq '.targets.".NETCoreApp,Version=v10.0"."Djup.Native/1.0.0" += {"runtimeTargets": {"runtimes/linux-x64/native/libdjup.so": {"rid": "linux-x64", "assetType": "native"} }}' "$depsjson")" -echo -n "$patched" > "$depsjson" diff --git a/Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets b/Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets new file mode 100644 index 0000000..fbb4c43 --- /dev/null +++ b/Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets @@ -0,0 +1,12 @@ + + + + + + + diff --git a/Djup.Native/scripts/patch-deps.sh b/Djup.Native/scripts/patch-deps.sh new file mode 100755 index 0000000..8015323 --- /dev/null +++ b/Djup.Native/scripts/patch-deps.sh @@ -0,0 +1,4 @@ +#!/bin/sh +depsjson="$(find "$1" -name '*.deps.json')" +patched="$(jq '.targets.".NETCoreApp,Version=v10.0"."Djup.Native/1.0.0" += {"runtimeTargets": {"runtimes/linux-x64/native/libdjup.so": {"rid": "linux-x64", "assetType": "native"} }}' "$depsjson")" +echo -n "$patched" > "$depsjson" diff --git a/Djup.Native/src/Constants.cs b/Djup.Native/src/Constants.cs new file mode 100644 index 0000000..90692be --- /dev/null +++ b/Djup.Native/src/Constants.cs @@ -0,0 +1,7 @@ +namespace Djup.Native; + +public static class Constants +{ + public const int WorldMaxPlayers = 5; + public const int WorldMaxBullets = 5000; +} diff --git a/Djup.Native/src/Djup.Native.csproj b/Djup.Native/src/Djup.Native.csproj new file mode 100644 index 0000000..a581a58 --- /dev/null +++ b/Djup.Native/src/Djup.Native.csproj @@ -0,0 +1,40 @@ + + + + net10.0 + enable + enable + true + true + + + + $(MSBuildThisFileDirectory)../../lib/build + + + + + runtimes/linux-x64/native/libdjup.so + Always + runtimes/linux-x64/native/ + true + + + + + + + $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) + true + + + + + runtimes/linux-x64/native/libdjup.so + Always + + + + + + diff --git a/Djup.Native/src/LibDjup.cs b/Djup.Native/src/LibDjup.cs new file mode 100644 index 0000000..15dcdad --- /dev/null +++ b/Djup.Native/src/LibDjup.cs @@ -0,0 +1,54 @@ +using System.Runtime.InteropServices; + +namespace Djup.Native; + +public static partial class LibDjup +{ + const string LibraryName = "djup"; + const string Prefix = "dp_"; + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(hello_world))] + public static partial void hello_world(); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(get_num))] + public static partial int get_num(); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(get_vec2))] + public static partial Vec2 get_vec2(); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(vec2_mul))] + public static partial Vec2 vec2_mul(Vec2 v, float scalar); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(vec2_normal))] + public static partial Vec2 vec2_normal(Vec2 v); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(vec2_length))] + public static partial float vec2_length(Vec2 v); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(log_set_output))] + public static partial Vec2 log_set_output([MarshalAs(UnmanagedType.FunctionPtr)] LoggerDelegate logger); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(log_set_level))] + public static partial Vec2 log_set_level(LogLevel minLevel); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_create))] + public static partial IntPtr physics_context_create(uint snapshots); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_free))] + public static partial void physics_context_free(IntPtr context); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_get_snapshot))] + public static partial IntPtr physics_context_get_snapshot(IntPtr context); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_context_return_snapshot))] + public static partial void physics_context_return_snapshot(IntPtr context, IntPtr snapshot); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(physics_tick))] + public static partial int physics_tick(IntPtr currentSnapshot, double delta, IntPtr nextSnapshot); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(snapshot_put_player))] + public static unsafe partial int snapshot_put_player(IntPtr snapshot, uint playerId, Player *player); + + [LibraryImport(LibraryName, EntryPoint = Prefix + nameof(snapshot_set_player_input))] + public static partial int snapshot_set_player_input(IntPtr snapshot, uint playerId, byte input); +} diff --git a/Djup.Native/src/Program.cs b/Djup.Native/src/Program.cs new file mode 100644 index 0000000..1b374b8 --- /dev/null +++ b/Djup.Native/src/Program.cs @@ -0,0 +1,3 @@ +/*using Djup.Native;*/ +/**/ +/*LibDjup.hello_world();*/ diff --git a/Djup.Native/src/Types.cs b/Djup.Native/src/Types.cs new file mode 100644 index 0000000..7d9c41e --- /dev/null +++ b/Djup.Native/src/Types.cs @@ -0,0 +1,89 @@ +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Djup.Native; + +[StructLayout(LayoutKind.Sequential)] +public struct Vec2 +{ + public float X { get; } + public float Y { get; } + + public Vec2(float x, float y) + { + Debug.Assert(float.IsFinite(x)); + Debug.Assert(float.IsFinite(y)); + + X = x; + Y = y; + } + + public override string ToString() => $"({X}, {Y})"; +} + +public enum EntityState : byte +{ + Inactive = 0, + Active, + Removed, + Dead +} + +public enum PlayerInput : byte +{ + Up = 1 << 0, + Down = 1 << 1, + Left = 1 << 2, + Right = 1 << 3 +} + +[StructLayout(LayoutKind.Sequential)] +public struct Player +{ + public EntityState State { get; } + private byte input; + public Vec2 Position { get; set; } + public Vec2 Velocity { get; set; } +} + +[StructLayout(LayoutKind.Sequential)] +public struct Bullet +{ + public EntityState State { get; set; } + public Vec2 Position { get; set; } + public Vec2 Velocity { get; set; } +} + +[StructLayout(LayoutKind.Sequential)] +public struct Snapshot +{ + [InlineArray(Constants.WorldMaxPlayers)] + public struct PlayerArray + { + private Player _element0; + } + + [InlineArray(Constants.WorldMaxBullets)] + public struct BallArray + { + private Bullet _element0; + } + + private byte active; + public uint Tick { get; } + public PlayerArray Players { get; } + public BallArray Bullets { get; } +} + +public enum LogLevel +{ + Trace, + Debug, + Info, + Warn, + Error, + Fatal +} + +public delegate void LoggerDelegate(LogLevel level, string source, int line, string message); diff --git a/Djup.Native/src/packages.lock.json b/Djup.Native/src/packages.lock.json new file mode 100644 index 0000000..4a91a8c --- /dev/null +++ b/Djup.Native/src/packages.lock.json @@ -0,0 +1,6 @@ +{ + "version": 1, + "dependencies": { + "net10.0": {} + } +} \ No newline at end of file diff --git a/Djup.Testing/src/Djup.Testing.fsproj b/Djup.Testing/src/Djup.Testing.fsproj index 91a3a4c..706d8fe 100644 --- a/Djup.Testing/src/Djup.Testing.fsproj +++ b/Djup.Testing/src/Djup.Testing.fsproj @@ -3,6 +3,7 @@ net10.0 true + true diff --git a/Djup.Testing/src/packages.lock.json b/Djup.Testing/src/packages.lock.json new file mode 100644 index 0000000..ad79414 --- /dev/null +++ b/Djup.Testing/src/packages.lock.json @@ -0,0 +1,31 @@ +{ + "version": 1, + "dependencies": { + "net10.0": { + "FsCheck": { + "type": "Direct", + "requested": "[3.3.2, )", + "resolved": "3.3.2", + "contentHash": "JlK719ZlP/ofbsN0qXYrfqbe2SCgp4D1BEyJynkzyurMI2JqUkWgZHXgEu0pXVdj35zU/GWsXrGYA68sSdAmHQ==", + "dependencies": { + "FSharp.Core": "5.0.2" + } + }, + "FSharp.Core": { + "type": "Direct", + "requested": "[10.1.201, )", + "resolved": "10.1.201", + "contentHash": "s5w9LWYurZ9yZdIppoIaYLkRadyT5s3u0wbQCb0J4bQd3ubIlIWQ3Nd5+ll1y3pv5OnTS373dP8T1S/BP46QXg==" + }, + "Fuchu": { + "type": "Direct", + "requested": "[1.1.0, )", + "resolved": "1.1.0", + "contentHash": "PNiweqWAt+ONHX6QUtFlbm4+xDbvwYTi5Vv67C0IFd6M+K2Qm9bTXLqNBqZTpIX5dPLpwW1SmARPawaXxdc9jw==", + "dependencies": { + "FSharp.Core": "4.3.4" + } + } + } + } +} \ No newline at end of file diff --git a/Djup.slnx b/Djup.slnx index befed83..11b7b93 100644 --- a/Djup.slnx +++ b/Djup.slnx @@ -1,7 +1,14 @@ + + + + - + + + + diff --git a/Djup/src/Content/Content.mgcb b/Djup/src/Content/Content.mgcb new file mode 100644 index 0000000..8b0866b --- /dev/null +++ b/Djup/src/Content/Content.mgcb @@ -0,0 +1,14 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin/$(Platform) +/intermediateDir:obj/$(Platform) +/platform:DesktopGL +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# diff --git a/Djup/src/Djup.fsproj b/Djup/src/Djup.fsproj new file mode 100644 index 0000000..dad45e9 --- /dev/null +++ b/Djup/src/Djup.fsproj @@ -0,0 +1,32 @@ + + + + WinExe + net10.0 + Major + true + false + false + app.manifest + Icon.ico + + + + + + + + + + + + + + + + + + + + + diff --git a/Djup/src/Icon.bmp b/Djup/src/Icon.bmp new file mode 100644 index 0000000..2b48165 Binary files /dev/null and b/Djup/src/Icon.bmp differ diff --git a/Djup/src/Icon.ico b/Djup/src/Icon.ico new file mode 100644 index 0000000..7d9dec1 Binary files /dev/null and b/Djup/src/Icon.ico differ diff --git a/Djup/src/Program.fs b/Djup/src/Program.fs new file mode 100644 index 0000000..2427252 --- /dev/null +++ b/Djup/src/Program.fs @@ -0,0 +1,153 @@ +module Djup.Program + +open System +open Microsoft.Xna.Framework +open Microsoft.Xna.Framework.Graphics +open Microsoft.Xna.Framework.Input +open Mibo.Elmish +open Mibo.Elmish.Graphics2D +open Mibo.Input + +// ───────────────────────────────────────────────────────────── +// Input +// ───────────────────────────────────────────────────────────── + +type GameAction = + | MoveLeft + | MoveRight + | MoveUp + | MoveDown + +let inputMap = + InputMap.empty + |> InputMap.key MoveLeft Keys.Left + |> InputMap.key MoveLeft Keys.A + |> InputMap.key MoveRight Keys.Right + |> InputMap.key MoveRight Keys.D + |> InputMap.key MoveUp Keys.Up + |> InputMap.key MoveUp Keys.W + |> InputMap.key MoveDown Keys.Down + |> InputMap.key MoveDown Keys.S + +// ───────────────────────────────────────────────────────────── +// Model +// ───────────────────────────────────────────────────────────── + +type Model = { + Position: Vector2 + Velocity: Vector2 + Input: ActionState +} + +// ───────────────────────────────────────────────────────────── +// Messages +// ───────────────────────────────────────────────────────────── + +type Msg = + | Tick of GameTime + | InputChanged of ActionState + +// ───────────────────────────────────────────────────────────── +// Init +// ───────────────────────────────────────────────────────────── + +let init(ctx: GameContext) : struct (Model * Cmd) = + let model = { + Position = Vector2(400.f, 300.f) + Velocity = Vector2(200.f, 150.f) + Input = ActionState.empty + } + + model, Cmd.none + +// ───────────────────────────────────────────────────────────── +// Update +// ───────────────────────────────────────────────────────────── + +let update (msg: Msg) (model: Model) : struct (Model * Cmd) = + match msg with + | InputChanged input -> { model with Input = input }, Cmd.none + + | Tick gt -> + let dt = float32 gt.ElapsedGameTime.TotalSeconds + + // Manual movement + let speed = 200.f + let mutable manualVelocity = Vector2.Zero + + if model.Input.Held.Contains MoveLeft then + manualVelocity.X <- manualVelocity.X - speed + + if model.Input.Held.Contains MoveRight then + manualVelocity.X <- manualVelocity.X + speed + + if model.Input.Held.Contains MoveUp then + manualVelocity.Y <- manualVelocity.Y - speed + + if model.Input.Held.Contains MoveDown then + manualVelocity.Y <- manualVelocity.Y + speed + + // Bouncing logic + let mutable velocity = model.Velocity + + let mutable position = + model.Position + (velocity * dt) + (manualVelocity * dt) + + if position.X < 0.f || position.X > 800.f - 32.f then + velocity.X <- -velocity.X + + if position.Y < 0.f || position.Y > 600.f - 32.f then + velocity.Y <- -velocity.Y + + { + model with + Position = position + Velocity = velocity + }, + Cmd.none + +// ───────────────────────────────────────────────────────────── +// View +// ───────────────────────────────────────────────────────────── + +let view (ctx: GameContext) (model: Model) (buffer: RenderBuffer) = + // Draw player (using a 1x1 pixel texture if no asset loaded, or load one) + let pixel = + Assets.getOrCreate + "pixel" + (fun gd -> + let t = new Texture2D(gd, 1, 1) + t.SetData([| Color.White |]) + t) + ctx + + Draw2D.sprite + pixel + (Rectangle(int model.Position.X, int model.Position.Y, 32, 32)) + |> Draw2D.withColor Color.Red + |> Draw2D.submit buffer + +// ───────────────────────────────────────────────────────────── +// Program +// ───────────────────────────────────────────────────────────── + +[] +let main _ = + let program = + Program.mkProgram init update + |> Program.withAssets + |> Program.withRenderer(fun g -> Batch2DRenderer.create g view) + |> Program.withInput + |> Program.withSubscription(fun ctx _ -> + InputMapper.subscribeStatic inputMap InputChanged ctx) + |> Program.withTick Tick + |> Program.withConfig(fun (game, graphics) -> + game.Content.RootDirectory <- "Content" + game.Window.Title <- "Mibo 2D Game" + game.IsMouseVisible <- true + graphics.PreferredBackBufferWidth <- 800 + graphics.PreferredBackBufferHeight <- 600) + + use game = new ElmishGame(program) + game.Run() + 0 diff --git a/Djup/src/app.manifest b/Djup/src/app.manifest new file mode 100644 index 0000000..b27ce83 --- /dev/null +++ b/Djup/src/app.manifest @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + true + permonitorv2,permonitor + + + + diff --git a/Djup/src/packages.lock.json b/Djup/src/packages.lock.json new file mode 100644 index 0000000..64ca908 --- /dev/null +++ b/Djup/src/packages.lock.json @@ -0,0 +1,72 @@ +{ + "version": 1, + "dependencies": { + "net10.0": { + "FSharp.Core": { + "type": "Direct", + "requested": "[10.1.201, )", + "resolved": "10.1.201", + "contentHash": "s5w9LWYurZ9yZdIppoIaYLkRadyT5s3u0wbQCb0J4bQd3ubIlIWQ3Nd5+ll1y3pv5OnTS373dP8T1S/BP46QXg==" + }, + "Mibo": { + "type": "Direct", + "requested": "[1.*, )", + "resolved": "1.6.0", + "contentHash": "HcElja4XxQ8E1vJc93+78Sb/lQB6jTy0VyOuMQRqwQfHeo4tQMx+6JkLj2OJVaeWE4BhC/P+C5tcONLnW3RGfg==", + "dependencies": { + "FSharp.Core": "10.0.102", + "FSharp.UMX": "1.1.0", + "JDeck": "1.0.0" + } + }, + "MonoGame.Content.Builder.Task": { + "type": "Direct", + "requested": "[3.8.*, )", + "resolved": "3.8.4.1", + "contentHash": "jf6IZXMiOhuybRaWQt//u+804yzMRGk3ZRvlBJG/0iusRwTunJsQvA6tMMJJc7gjUrY6rUkzRqwinKWXugyHfA==" + }, + "MonoGame.Framework.DesktopGL": { + "type": "Direct", + "requested": "[3.8.*, )", + "resolved": "3.8.4.1", + "contentHash": "YybxIIT5+Ky78E/XdkS0glyluMr2EeDZwx2LqXULAOCqiKt1+aDrjPZaqLL5qpNgBcMEHUeZJ4YjWe4TAZlWLw==", + "dependencies": { + "MonoGame.Library.OpenAL": "1.24.3.2", + "MonoGame.Library.SDL": "2.32.2.1", + "NVorbis": "0.10.4" + } + }, + "FSharp.UMX": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "0+4w4/yBL5z7w1/k198ooPbfMqkzMSXPRVZEVingnwAdjM//QIFG25eJbB3RtoSQAusBwV5B3VcSudxJejd5Bg==", + "dependencies": { + "FSharp.Core": "4.3.4" + } + }, + "JDeck": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "a4d+USHnlc3+zPZb7MOKXD58BbVMaO1sajROxPQH5m+g08QtqVcr4PlNs6cT5QuP13lKpHlw9X+9UlAcXmguYA==", + "dependencies": { + "FSharp.Core": "9.0.100" + } + }, + "MonoGame.Library.OpenAL": { + "type": "Transitive", + "resolved": "1.24.3.2", + "contentHash": "nGRsXQXs+NSUC3C5w90hFQfyKdZPpBnHnyg2w+Dw/2pUH7s+CoRWTJNYbzzdJf3+aeUvfvG4rTbFvMKDDj5olA==" + }, + "MonoGame.Library.SDL": { + "type": "Transitive", + "resolved": "2.32.2.1", + "contentHash": "T4E2ppGlSTC2L9US1rxtdg3qTbarRzNId31xZoumUW9cf9Nq8nRQPMu9GzvZGrhfSySf0+UWPEj1rlicps+P/w==" + }, + "NVorbis": { + "type": "Transitive", + "resolved": "0.10.4", + "contentHash": "WYnil3DhQHzjCY0dM9I2B3r1vWip90AOuQd25KE4NrjPQBg0tBJFluRLm5YPnO5ZLDmwrfosY8jCQGQRmWI/Pg==" + } + } + } +} \ No newline at end of file -- cgit v1.2.3