summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/VillageArt.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/VillageArt.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/VillageArt.fs')
-rw-r--r--src/LivingVillage.Desktop/VillageArt.fs40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/LivingVillage.Desktop/VillageArt.fs b/src/LivingVillage.Desktop/VillageArt.fs
index 51e17e0..19c9aa6 100644
--- a/src/LivingVillage.Desktop/VillageArt.fs
+++ b/src/LivingVillage.Desktop/VillageArt.fs
@@ -724,9 +724,34 @@ module VillageArt =
/// P20 证据用:把整张 MapGen 地图等比缩放到视口内绘制,返回绘制的瓦片数。
/// 仅用于 `LV_MAPGEN_SHOT` 整图取证,不参与正常游戏循环。
+ let private fillRect (spriteBatch: SpriteBatch) (pixel: Texture2D) (color: XnaColor) (x: int) (y: int) (w: int) (h: int) =
+ spriteBatch.Draw(pixel, XnaRectangle(x, y, max 1 w, max 1 h), color)
+
+ /// 整图证据里叠加桥面与沿河民居(白墙黑瓦色块 + 门)。
+ let private drawMapStructures
+ (spriteBatch: SpriteBatch)
+ (textures: ArtTextures)
+ (pixel: Texture2D)
+ (tileX: int -> int)
+ (tileY: int -> int)
+ (cell: int)
+ (map: MapGen.Result) =
+ let bridgeSource = tileSourceRectangle BridgeSprite
+ for (x, y) in map.Bridges do
+ spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY y, cell, cell), bridgeSource, XnaColor.White)
+ for building in map.Buildings do
+ for row in building.Top .. building.Top + building.Height - 1 do
+ // 白墙朝向道路一行(门所在行),其余为黑瓦屋顶,两侧河岸朝向一致。
+ let color =
+ if row = building.DoorY then XnaColor(236, 232, 220)
+ else XnaColor(48, 52, 60)
+ fillRect spriteBatch pixel color (tileX building.Left) (tileY row) (building.Width * cell) (cell)
+ fillRect spriteBatch pixel (XnaColor(96, 60, 42)) (tileX building.DoorX) (tileY building.DoorY) cell cell
+
let drawMapFitted
(spriteBatch: SpriteBatch)
(textures: ArtTextures)
+ (pixel: Texture2D)
(viewportWidth: int)
(viewportHeight: int)
(map: MapGen.Result)
@@ -737,6 +762,8 @@ module VillageArt =
let cell = max 1 (int (float32 Sim.tilePixels * scale))
let offsetX = (viewportWidth - map.Width * cell) / 2
let offsetY = (viewportHeight - map.Height * cell) / 2
+ let tileX x = offsetX + x * cell
+ let tileY y = offsetY + y * cell
let spriteOf code =
match code with
| 1 -> WaterSprite
@@ -746,13 +773,15 @@ module VillageArt =
for y in 0 .. map.Height - 1 do
for x in 0 .. map.Width - 1 do
let code = map.Tiles.[y * map.Width + x]
- spriteBatch.Draw(textures.TileAtlas, XnaRectangle(offsetX + x * cell, offsetY + y * cell, cell, cell), tileSourceRectangle (spriteOf code), tint)
+ spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY y, cell, cell), tileSourceRectangle (spriteOf code), tint)
+ drawMapStructures spriteBatch textures pixel tileX tileY cell map
map.Width * map.Height
/// P20 证据用:按相机做视口裁剪,只绘制可见瓦片(1:1 像素),返回实际绘制数。
let drawMapViewport
(spriteBatch: SpriteBatch)
(textures: ArtTextures)
+ (pixel: Texture2D)
(camera: XnaVector2)
(viewportWidth: int)
(viewportHeight: int)
@@ -761,6 +790,8 @@ module VillageArt =
(tint: XnaColor) : int =
let x0, y0, x1, y1 =
MapGen.visibleTileRange map.Width map.Height (int camera.X) (int camera.Y) viewportWidth viewportHeight
+ let tileX x = x * Sim.tilePixels - int camera.X
+ let tileY y = y * Sim.tilePixels - int camera.Y
let spriteOf (x: int) (y: int) code =
match code with
| 1 ->
@@ -775,12 +806,9 @@ module VillageArt =
for y in y0 .. y1 do
for x in x0 .. x1 do
let code = map.Tiles.[y * map.Width + x]
- spriteBatch.Draw(
- textures.TileAtlas,
- XnaRectangle(x * Sim.tilePixels - int camera.X, y * Sim.tilePixels - int camera.Y, Sim.tilePixels, Sim.tilePixels),
- tileSourceRectangle (spriteOf x y code),
- tint)
+ spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY y, Sim.tilePixels, Sim.tilePixels), tileSourceRectangle (spriteOf x y code), tint)
drawn <- drawn + 1
+ drawMapStructures spriteBatch textures pixel tileX tileY Sim.tilePixels map
drawn
let drawCharacter