summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-18 22:48:42 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-18 22:48:42 +0800
commitb237a11908442a227361fae24dbdd0dbb287fac9 (patch)
tree0f31cbfe87b652fd06b3160817a86f8a39ed011d /src/LivingVillage.Kernel
parent7a035096ac513a5f5021788f8ad6cffb49452a38 (diff)
downloadliving-village-b237a11908442a227361fae24dbdd0dbb287fac9.tar.gz
feat: M0 骨架 — F# 解决方案 + MonoGame DesktopGL 游戏循环 + 32x32 瓦片地图 + 化身 WASD + 镜头跟随 + FPS 计数
Diffstat (limited to 'src/LivingVillage.Kernel')
-rw-r--r--src/LivingVillage.Kernel/LivingVillage.Kernel.fsproj11
-rw-r--r--src/LivingVillage.Kernel/Sim.fs46
2 files changed, 57 insertions, 0 deletions
diff --git a/src/LivingVillage.Kernel/LivingVillage.Kernel.fsproj b/src/LivingVillage.Kernel/LivingVillage.Kernel.fsproj
new file mode 100644
index 0000000..a8ed312
--- /dev/null
+++ b/src/LivingVillage.Kernel/LivingVillage.Kernel.fsproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net8.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="Sim.fs" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/LivingVillage.Kernel/Sim.fs b/src/LivingVillage.Kernel/Sim.fs
new file mode 100644
index 0000000..d1b2e57
--- /dev/null
+++ b/src/LivingVillage.Kernel/Sim.fs
@@ -0,0 +1,46 @@
+namespace LivingVillage.Kernel
+
+module Sim =
+
+ type Vec2 =
+ { X: float32
+ Y: float32 }
+
+ type Avatar =
+ { Pos: Vec2 }
+
+ type Input =
+ { MoveX: float32
+ MoveY: float32 }
+
+ type TimeStep =
+ { Dt: float32
+ Input: Input }
+
+ type World =
+ { Tick: int64
+ Avatar: Avatar }
+
+ let mapWidthTiles = 64
+ let mapHeightTiles = 48
+ let tilePixels = 32
+ let avatarSpeed = 160.0f
+
+ let initialWorld () : World =
+ let centerX = float32 (mapWidthTiles * tilePixels / 2 - tilePixels / 2)
+ let centerY = float32 (mapHeightTiles * tilePixels / 2 - tilePixels / 2)
+ { Tick = 0L
+ Avatar = { Pos = { X = centerX; Y = centerY } } }
+
+ let clamp v lo hi = if v < lo then lo elif v > hi then hi else v
+
+ let step (ts: TimeStep) (world: World) : World =
+ let maxX = float32 (mapWidthTiles * tilePixels - tilePixels)
+ let maxY = float32 (mapHeightTiles * tilePixels - tilePixels)
+ let dx = ts.Input.MoveX * avatarSpeed * ts.Dt
+ let dy = ts.Input.MoveY * avatarSpeed * ts.Dt
+ { Tick = world.Tick + 1L
+ Avatar =
+ { Pos =
+ { X = clamp (world.Avatar.Pos.X + dx) 0.0f maxX
+ Y = clamp (world.Avatar.Pos.Y + dy) 0.0f maxY } } }