summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop.Tests
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-21 13:15:39 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-21 13:15:39 +0800
commit0b9753543bd726818c61d76384d56a30b862e1ac (patch)
tree06b21006dc540b5d9995caf394bb4c8084b9294e /src/LivingVillage.Desktop.Tests
parent76a6850bb88546fc21f5f78a53fbda04e77c8b52 (diff)
downloadliving-village-0b9753543bd726818c61d76384d56a30b862e1ac.tar.gz
feat(desktop): 村民与主角四帧行走动画
人物图集 5 变体 x 4 向 x 4 帧(2560x48,全部经 make-jiangnan-art.py 原创,四种腿步:站立/左跨/站立微跳/右跨镜像);animationFrame 按 tick/4 mod 4 确定性取帧(16 tick 一循环,禁实时时钟);快照式回归断言四帧循环与逐帧图集列映射,主角同规则。
Diffstat (limited to 'src/LivingVillage.Desktop.Tests')
-rw-r--r--src/LivingVillage.Desktop.Tests/PrototypeTests.fs29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs
index d77abd6..450e94b 100644
--- a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs
+++ b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs
@@ -324,7 +324,7 @@ type PrototypeTests () =
Assert.IsTrue(first.PanelY + first.PanelHeight <= 720)
[<TestMethod>]
- member _.NpcVariantsAreStableAndAnimationCoversFourDirectionsAndTwoFrames () =
+ member _.NpcVariantsAreStableAndAnimationCoversFourDirectionsAndFourFrames () =
let sameNpc = npcVisualVariant (NpcId 7)
let repeatedNpc = npcVisualVariant (NpcId 7)
let otherNpc = npcVisualVariant (NpcId 8)
@@ -341,7 +341,9 @@ type PrototypeTests () =
Assert.IsTrue(sprites |> List.forall (fun sprite -> sprite.Frame = FrameTwo))
Assert.AreEqual<AnimationFrame>(FrameOne, (VillageArt.animationFrame 0L))
Assert.AreEqual<AnimationFrame>(FrameTwo, (VillageArt.animationFrame 4L))
- Assert.AreEqual<AnimationFrame>(FrameOne, (VillageArt.animationFrame 8L))
+ Assert.AreEqual<AnimationFrame>(FrameThree, (VillageArt.animationFrame 8L))
+ Assert.AreEqual<AnimationFrame>(FrameFour, (VillageArt.animationFrame 12L))
+ Assert.AreEqual<AnimationFrame>(FrameOne, (VillageArt.animationFrame 16L))
[<TestMethod>]
member _.VillagersUseFourDistinctVariantsDistinctFromTheAvatar () =
@@ -359,7 +361,28 @@ type PrototypeTests () =
rect.X)
|> Set.ofList
Assert.AreEqual<int>(4, variantXes.Count)
- Assert.AreEqual<int>(1280, VillageArt.characterAtlasWidth)
+ Assert.AreEqual<int>(2560, VillageArt.characterAtlasWidth)
+
+ [<TestMethod>]
+ member _.WalkAnimationCoversFourFramesDeterministically () =
+ // 16-tick cycle, new frame every 4 sim ticks, no wall-clock dependency.
+ let frames = [ 0L; 4L; 8L; 12L; 16L; 20L ] |> List.map VillageArt.animationFrame
+ Assert.AreEqual<AnimationFrame list>([ FrameOne; FrameTwo; FrameThree; FrameFour; FrameOne; FrameTwo ], frames)
+
+ let cycleFrames =
+ [ 0L; 4L; 8L; 12L ]
+ |> List.map VillageArt.animationFrame
+ |> List.distinct
+ Assert.AreEqual<AnimationFrame list>([ FrameOne; FrameTwo; FrameThree; FrameFour ], cycleFrames)
+
+ // Every frame maps to a distinct atlas cell column across the five variants.
+ // Every frame maps to a distinct atlas cell column across the five variants.
+ let perFrameX =
+ [ FrameOne; FrameTwo; FrameThree; FrameFour ]
+ |> List.map (fun frame ->
+ let rect = characterSourceRectangle { Variant = IndigoRobe; Direction = NorthFacing; Frame = frame }
+ rect.X / 32)
+ Assert.AreEqual<int list>([ 0; 1; 2; 3 ], perFrameX)
[<TestMethod>]
member _.ChineseCopyProvidesFormalSceneTimeMenuAndStatusLabels () =