From b6b95988e525a68ea7426ecc9690b18a1b3bbfe8 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 21 Sep 2026 00:26:30 +0800 Subject: feat(m6c): 完成江南村庄中文交付 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成江南村庄场景、角色表现和中文界面的 M6c 交付范围。 新增 CJK 字形图集、中文文案与运行时加载,补充民居情境交互和确定性村庄美术表现。 更新资源复制与 Linux/macOS 打包校验,加入 188 字符清单、资源许可说明和对应原型测试。 补充江南美术方向与 M6c 交付说明,并保持原有模拟内核和桌面构建入口不变。 --- src/LivingVillage.Desktop/VillagePresentation.fs | 45 +++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src/LivingVillage.Desktop/VillagePresentation.fs') diff --git a/src/LivingVillage.Desktop/VillagePresentation.fs b/src/LivingVillage.Desktop/VillagePresentation.fs index 95dc178..eee7fac 100644 --- a/src/LivingVillage.Desktop/VillagePresentation.fs +++ b/src/LivingVillage.Desktop/VillagePresentation.fs @@ -1,5 +1,8 @@ namespace LivingVillage.Desktop +open System +open LivingVillage.Kernel.Sim + module VillagePresentation = (** @@ -17,6 +20,11 @@ module VillagePresentation = { X: int Y: int } + [] + type PixelPosition = + { X: float32 + Y: float32 } + [] type SimulationTick = | SimulationTick of int64 @@ -74,6 +82,11 @@ module VillagePresentation = | Outside | Inside of HomeId + type HomeInputAction = + | EnterHomeAction of HomeId + | ExitHomeAction of HomeId + | DialogueAction + type HomeTransitionError = | NotNearHomeDoor | AlreadyInsideHome of HomeId @@ -120,7 +133,18 @@ module VillagePresentation = let scene : PrototypeScene = createScene () - let private manhattanDistance first second : int = + let sceneOrigin : TilePosition = + tile 25 18 + + let sceneTileFromPixel (pixel: PixelPosition) : TilePosition = + { X = int (Math.Floor(float pixel.X / float tilePixels)) - sceneOrigin.X + Y = int (Math.Floor(float pixel.Y / float tilePixels)) - sceneOrigin.Y } + + let worldTileForSceneTile (sceneTile: TilePosition) : TilePosition = + { X = sceneOrigin.X + sceneTile.X + Y = sceneOrigin.Y + sceneTile.Y } + + let private manhattanDistance (first: TilePosition) (second: TilePosition) : int = abs (first.X - second.X) + abs (first.Y - second.Y) let isNearHomeDoor (position: TilePosition) (home: Home) : bool = @@ -143,6 +167,25 @@ module VillagePresentation = else Error(HomeNotFound homeId) + let homeInputAction (pixel: PixelPosition) (mode: HomeMode) : HomeInputAction = + let scenePosition = sceneTileFromPixel pixel + + match mode with + | Outside -> + match enterHome scenePosition Outside with + | Ok(Inside homeId) -> EnterHomeAction homeId + | _ -> DialogueAction + | Inside homeId -> + match scene.Homes |> List.tryFind (fun home -> home.Id = homeId) with + | Some home when isNearHomeDoor scenePosition home -> + match exitHome mode with + | Ok Outside -> ExitHomeAction homeId + | _ -> DialogueAction + | _ -> DialogueAction + + let resetHomeMode () : HomeMode = + Outside + let directionForInput (input: DirectionInput) : Direction option = match input with | UpInput -> Some North -- cgit v1.2.3