summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/VillageArt.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 10:14:31 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 10:14:31 +0800
commitb377e750a6a3f35c5d64a29f14ac3fbd87d4a752 (patch)
tree8baac5fca38fdcecda4a00eed7a58b1031ab9dca /src/LivingVillage.Desktop/VillageArt.fs
parentd36e86ac637ccc477479f88bea511c49b0a6a67c (diff)
parent5f12e63f2d2203267c30666f1559e06ec637b91c (diff)
downloadliving-village-b377e750a6a3f35c5d64a29f14ac3fbd87d4a752.tar.gz
merge: P26 美术整改(民居第二变体/河岸装饰/夜月光/HUD 双景可读)— Hermes 复验通过
Diffstat (limited to 'src/LivingVillage.Desktop/VillageArt.fs')
-rw-r--r--src/LivingVillage.Desktop/VillageArt.fs60
1 files changed, 48 insertions, 12 deletions
diff --git a/src/LivingVillage.Desktop/VillageArt.fs b/src/LivingVillage.Desktop/VillageArt.fs
index 12c17ba..d2fcc1a 100644
--- a/src/LivingVillage.Desktop/VillageArt.fs
+++ b/src/LivingVillage.Desktop/VillageArt.fs
@@ -154,6 +154,10 @@ module VillageArt =
| StoneLanternSprite
| WaterVatSprite
| StallSprite
+ | RoofEaveOverhangSprite
+ | WallLatticeSprite
+ | CourtyardDoorSprite
+ | RevetmentStoneSprite
type private XnaColor = Microsoft.Xna.Framework.Color
type private XnaRectangle = Microsoft.Xna.Framework.Rectangle
@@ -496,7 +500,7 @@ module VillageArt =
let characterAtlasRelativePath = "Assets/jiangnan-characters.png"
let interiorAtlasRelativePath = "Assets/jiangnan-interior.png"
- let worldTileCount = 28
+ let worldTileCount = 32
let worldAtlasWidth = Sim.tilePixels * worldTileCount
let worldAtlasHeight = Sim.tilePixels
let characterAtlasWidth = 32 * 5 * 4 * 6
@@ -570,6 +574,10 @@ module VillageArt =
| StoneLanternSprite -> 25
| WaterVatSprite -> 26
| StallSprite -> 27
+ | RoofEaveOverhangSprite -> 28
+ | WallLatticeSprite -> 29
+ | CourtyardDoorSprite -> 30
+ | RevetmentStoneSprite -> 31
XnaRectangle(index * Sim.tilePixels, 0, Sim.tilePixels, Sim.tilePixels)
let private tilePosition x y : TilePosition =
@@ -603,6 +611,13 @@ module VillageArt =
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)
+ /// P26 民居立面变体:按位置确定性交替两种立面(沿河沿路分布)。
+ /// 0 = 黛瓦脊 + 木墙/窗 + 门(P24 原样);1 = 挑檐挑出 + 木格栅窗 + 院门。
+ /// 纯函数、不改变任何瓦片/可达性语义;64x48 与 256x192 的 tiles checksum 不受影响。
+ let houseFacadeVariant (building: MapGen.Building) : int =
+ let remainder = (building.Left + building.Top) % 2
+ if remainder < 0 then remainder + 2 else remainder
+
/// 生成器世界里的桥面与沿河民居(白墙黑瓦色块 + 门);坐标由调用方按相机换算。
let private drawMapStructures
(spriteBatch: SpriteBatch)
@@ -613,23 +628,44 @@ module VillageArt =
(cell: int)
(map: MapGen.Result) =
let bridgeSource = tileSourceRectangle BridgeSprite
+ let drawCell sprite x y =
+ spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY y, cell, cell), tileSourceRectangle sprite, XnaColor.White)
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
let left = building.Left
let right = building.Left + building.Width - 1
- // P24:改用 256x192 同款民宅部件——黛瓦(脊/檐)+ 木墙/窗 + 门。
- for row in building.Top .. building.DoorY - 1 do
- let roofSprite = if row = building.Top then RoofRidgeSprite else RoofEaveSprite
- let source = tileSourceRectangle roofSprite
+ match houseFacadeVariant building with
+ | 0 ->
+ // 变体 A(P24):黛瓦(脊/檐)+ 木墙/窗 + 门。
+ for row in building.Top .. building.DoorY - 1 do
+ let roofSprite = if row = building.Top then RoofRidgeSprite else RoofEaveSprite
+ for x in left .. right do
+ drawCell roofSprite x row
+ for x in left .. right do
+ let wallSprite =
+ if x = building.DoorX then DoorSprite
+ elif (x - left) % 2 = 0 then WallWindowSprite
+ else WallWoodSprite
+ drawCell wallSprite x building.DoorY
+ | _ ->
+ // 变体 B(P26):挑檐向两侧各出一格 + 木格栅窗 + 院门。
+ for x in (left - 1) .. (right + 1) do
+ drawCell RoofEaveOverhangSprite x building.Top
for x in left .. right do
- spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY row, cell, cell), source, XnaColor.White)
- for x in left .. right do
- let wallSprite =
- if x = building.DoorX then DoorSprite
- elif (x - left) % 2 = 0 then WallWindowSprite
- else WallWoodSprite
- spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY building.DoorY, cell, cell), tileSourceRectangle wallSprite, XnaColor.White)
+ let wallSprite =
+ if x = building.DoorX then CourtyardDoorSprite
+ elif (x - left) % 2 = 0 then WallLatticeSprite
+ else WallWoodSprite
+ drawCell wallSprite x building.DoorY
+ // P26 河岸装饰:护岸石垒 / 芦苇 / 垂柳(垂柳占上下两格),只在大图生成。
+ for decoration in map.Decorations do
+ match decoration.Kind with
+ | MapGen.RiverDecorationKind.RevetmentStone -> drawCell RevetmentStoneSprite decoration.X decoration.Y
+ | MapGen.RiverDecorationKind.Reeds -> drawCell ReedSprite decoration.X decoration.Y
+ | MapGen.RiverDecorationKind.Willow ->
+ drawCell WillowTopSprite decoration.X decoration.Y
+ drawCell WillowBaseSprite decoration.X (decoration.Y + 1)
/// 桥头灯笼瓦片:每座桥每列的最上/最下一格(桥两端),用于挂灯笼与夜间暖光。
let bridgeLanternTiles (map: MapGen.Result) : (int * int) list =