diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-22 02:43:39 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-22 02:43:39 +0800 |
| commit | d3c0ef17cb1c4d30c1d586e2a5b616f58bd3d875 (patch) | |
| tree | 19d93967c15548f80a83d7bf6617b826fb5cb5e7 /src/LivingVillage.Desktop/Game.fs | |
| parent | ef78374c316587fb585b72e6d427cd6e61203655 (diff) | |
| download | living-village-d3c0ef17cb1c4d30c1d586e2a5b616f58bd3d875.tar.gz | |
feat(mapgen): 河道连续性不变量 + 桥/石板路网/沿河民居(P20 第二步)p20-map-gen-foundation
- 河道改为贯穿全图连续水带(每列一段、宽度 >= RiverWidth),置于核心区上下
两侧且不相交;新增不变量测试:逐列水段数恒定、每段宽度下限、任意水格
>=2 个水邻居(禁止断裂缺口与孤立水点)。
- Result 新增 Rivers/Bridges/Paths/Buildings/BridgeCrossingsOk;每河 2 座桥、
横贯主路 + 垂直连接路 + 远岸路 + 白墙黑瓦民居(门朝路)。
- 公开 isWalkable/floodFill;ReachabilityOk 现覆盖 30 spawn + 所有门 + 所有桥面,
BridgeCrossingsOk 保证每桥两岸同连通域。
- 回归:Desktop 115->119、Kernel 90 不变;final_digest 与基线一致。
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index 64dc3e2..5d2ba54 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -690,48 +690,58 @@ type LivingVillageGame() as this = printfn "menu-shot=done frames=%d" menuShotFrame this.Exit() - /// P20 证据:把一次 MapGen 绘制渲染到离屏 target 并落盘,返回绘制瓦片数。 - member private this.RenderMapGen (drawFitted: bool) : int * Texture2D = - let viewport = this.GraphicsDevice.Viewport - use target = new RenderTarget2D(this.GraphicsDevice, viewport.Width, viewport.Height) + /// P20 证据:把一次 MapGen 绘制渲染到指定尺寸离屏 target,返回绘制瓦片数与纹理。 + member private this.RenderMapGen (targetWidth: int) (targetHeight: int) (camX: int) (camY: int) (drawFitted: bool) : int * Texture2D = + use target = new RenderTarget2D(this.GraphicsDevice, targetWidth, targetHeight) this.GraphicsDevice.SetRenderTarget target this.GraphicsDevice.Clear(Color(18, 26, 20)) - let camX = max 0 ((mapGenResult.Width * Sim.tilePixels - viewport.Width) / 2) - let camY = max 0 ((mapGenResult.Height * Sim.tilePixels - viewport.Height) / 2) spriteBatch.Begin() let drawn = if drawFitted then - VillageArt.drawMapFitted spriteBatch artTextures viewport.Width viewport.Height mapGenResult Color.White + VillageArt.drawMapFitted spriteBatch artTextures pixel targetWidth targetHeight mapGenResult Color.White else - VillageArt.drawMapViewport spriteBatch artTextures (Vector2(float32 camX, float32 camY)) viewport.Width viewport.Height mapGenResult 0L Color.White + VillageArt.drawMapViewport spriteBatch artTextures pixel (Vector2(float32 camX, float32 camY)) targetWidth targetHeight mapGenResult 0L Color.White spriteBatch.End() this.GraphicsDevice.SetRenderTarget null - let data = Array.zeroCreate<Color> (viewport.Width * viewport.Height) + let data = Array.zeroCreate<Color> (targetWidth * targetHeight) target.GetData<Color>(data) - let texture = new Texture2D(this.GraphicsDevice, viewport.Width, viewport.Height) + let texture = new Texture2D(this.GraphicsDevice, targetWidth, targetHeight) texture.SetData(data) (drawn, texture) - /// P20 证据:整图等比渲染 + 1:1 视口裁剪帧各存一张,打印绘制计数后退出。 + /// P20 证据:整图放大渲染(每瓦片 6px)+ 1:1 视口裁剪帧各存一张,打印计数后退出。 member private this.DrawMapGenShot () = System.IO.Directory.CreateDirectory recordDirectory |> ignore let viewport = this.GraphicsDevice.Viewport - let fittedDrawn, fittedTexture = this.RenderMapGen true + let mapCell = 6 + let fittedDrawn, fittedTexture = this.RenderMapGen (mapGenResult.Width * mapCell) (mapGenResult.Height * mapCell) 0 0 true use _fitted = fittedTexture - use stream = System.IO.File.Create(sprintf "%s/mapgen-%dx%d-seed%d.png" recordDirectory mapGenResult.Width mapGenResult.Height (int mapGenResult.Seed)) - fittedTexture.SaveAsPng(stream, viewport.Width, viewport.Height) - printfn "mapgen-fitted drawn=%d viewport=%dx%d" fittedDrawn viewport.Width viewport.Height + use stream = System.IO.File.Create(sprintf "%s/p20b-map-%dx%d-seed%d.png" recordDirectory mapGenResult.Width mapGenResult.Height (int mapGenResult.Seed)) + fittedTexture.SaveAsPng(stream, fittedTexture.Width, fittedTexture.Height) + printfn "mapgen-fitted drawn=%d png=%dx%d" fittedDrawn fittedTexture.Width fittedTexture.Height - let camX = max 0 ((mapGenResult.Width * Sim.tilePixels - viewport.Width) / 2) - let camY = max 0 ((mapGenResult.Height * Sim.tilePixels - viewport.Height) / 2) - let culledDrawn, culledTexture = this.RenderMapGen false + let clampRange maximum value = max 0 (min (max 0 maximum) value) + let camX = clampRange (mapGenResult.Width * Sim.tilePixels - viewport.Width) ((mapGenResult.Width * Sim.tilePixels - viewport.Width) / 2) + let camY = clampRange (mapGenResult.Height * Sim.tilePixels - viewport.Height) ((mapGenResult.Height * Sim.tilePixels - viewport.Height) / 2) + let culledDrawn, culledTexture = this.RenderMapGen viewport.Width viewport.Height camX camY false use _culled = culledTexture - use culledStream = System.IO.File.Create(sprintf "%s/mapgen-culled-%dx%d-seed%d.png" recordDirectory mapGenResult.Width mapGenResult.Height (int mapGenResult.Seed)) + use culledStream = System.IO.File.Create(sprintf "%s/p20b-culled-%dx%d-seed%d.png" recordDirectory mapGenResult.Width mapGenResult.Height (int mapGenResult.Seed)) culledTexture.SaveAsPng(culledStream, viewport.Width, viewport.Height) let total = mapGenResult.Width * mapGenResult.Height let visible = MapGen.visibleTileCount mapGenResult.Width mapGenResult.Height camX camY viewport.Width viewport.Height printfn "mapgen-cull drawn=%d visible=%d total=%d culled=%.1f%%" culledDrawn visible total (100.0 * (1.0 - float culledDrawn / float total)) + match mapGenResult.Bridges with + | (bx, by) :: _ -> + let detailCamX = clampRange (mapGenResult.Width * Sim.tilePixels - viewport.Width) (bx * Sim.tilePixels - viewport.Width / 2) + let detailCamY = clampRange (mapGenResult.Height * Sim.tilePixels - viewport.Height) (by * Sim.tilePixels - viewport.Height / 2) + let detailDrawn, detailTexture = this.RenderMapGen viewport.Width viewport.Height detailCamX detailCamY false + use _detail = detailTexture + use detailStream = System.IO.File.Create(sprintf "%s/p20b-detail-%dx%d-seed%d.png" recordDirectory mapGenResult.Width mapGenResult.Height (int mapGenResult.Seed)) + detailTexture.SaveAsPng(detailStream, detailTexture.Width, detailTexture.Height) + printfn "mapgen-detail drawn=%d bridge=(%d,%d) camera=(%d,%d)" detailDrawn bx by detailCamX detailCamY + | [] -> () + let smallWatch = System.Diagnostics.Stopwatch.StartNew() let smallMap = MapGen.generateWithSize 64 48 (uint64 4242) smallWatch.Stop() @@ -742,7 +752,7 @@ type LivingVillageGame() as this = this.GraphicsDevice.SetRenderTarget frameTarget for _ in 1 .. 30 do spriteBatch.Begin() - VillageArt.drawMapViewport spriteBatch artTextures (Vector2(float32 camX, float32 camY)) viewport.Width viewport.Height mapGenResult 0L Color.White |> ignore + VillageArt.drawMapViewport spriteBatch artTextures pixel (Vector2(float32 camX, float32 camY)) viewport.Width viewport.Height mapGenResult 0L Color.White |> ignore spriteBatch.End() this.GraphicsDevice.SetRenderTarget null frameWatch.Stop() |
