summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/VillageArt.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Desktop/VillageArt.fs')
-rw-r--r--src/LivingVillage.Desktop/VillageArt.fs50
1 files changed, 38 insertions, 12 deletions
diff --git a/src/LivingVillage.Desktop/VillageArt.fs b/src/LivingVillage.Desktop/VillageArt.fs
index 12c17ba..f303620 100644
--- a/src/LivingVillage.Desktop/VillageArt.fs
+++ b/src/LivingVillage.Desktop/VillageArt.fs
@@ -154,6 +154,9 @@ module VillageArt =
| StoneLanternSprite
| WaterVatSprite
| StallSprite
+ | RoofEaveOverhangSprite
+ | WallLatticeSprite
+ | CourtyardDoorSprite
type private XnaColor = Microsoft.Xna.Framework.Color
type private XnaRectangle = Microsoft.Xna.Framework.Rectangle
@@ -496,7 +499,7 @@ module VillageArt =
let characterAtlasRelativePath = "Assets/jiangnan-characters.png"
let interiorAtlasRelativePath = "Assets/jiangnan-interior.png"
- let worldTileCount = 28
+ let worldTileCount = 31
let worldAtlasWidth = Sim.tilePixels * worldTileCount
let worldAtlasHeight = Sim.tilePixels
let characterAtlasWidth = 32 * 5 * 4 * 6
@@ -570,6 +573,9 @@ module VillageArt =
| StoneLanternSprite -> 25
| WaterVatSprite -> 26
| StallSprite -> 27
+ | RoofEaveOverhangSprite -> 28
+ | WallLatticeSprite -> 29
+ | CourtyardDoorSprite -> 30
XnaRectangle(index * Sim.tilePixels, 0, Sim.tilePixels, Sim.tilePixels)
let private tilePosition x y : TilePosition =
@@ -603,6 +609,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)
@@ -618,18 +631,31 @@ module VillageArt =
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
+ let drawCell sprite x y =
+ spriteBatch.Draw(textures.TileAtlas, XnaRectangle(tileX x, tileY y, cell, cell), tileSourceRectangle sprite, XnaColor.White)
+ 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
/// 桥头灯笼瓦片:每座桥每列的最上/最下一格(桥两端),用于挂灯笼与夜间暖光。
let bridgeLanternTiles (map: MapGen.Result) : (int * int) list =