summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/Game.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 02:43:39 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 02:43:39 +0800
commitd3c0ef17cb1c4d30c1d586e2a5b616f58bd3d875 (patch)
tree19d93967c15548f80a83d7bf6617b826fb5cb5e7 /src/LivingVillage.Desktop/Game.fs
parentef78374c316587fb585b72e6d427cd6e61203655 (diff)
downloadliving-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.fs50
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()