summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/SceneDetailRender.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-29 16:02:35 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-29 16:02:35 +0800
commit975d6721973fa526014fb2401e97075ecbf51c2c (patch)
tree2099e87d01f742ce57868e20a20abb2ba2fa8e7c /src/LivingVillage.Desktop/SceneDetailRender.fs
parent3196b4914d037052db0cf191be0431dc4ac4d596 (diff)
downloadliving-village-975d6721973fa526014fb2401e97075ecbf51c2c.tar.gz
p78: 夜帧水面微光斑、生成器世界炊烟与桥头窄光晕
Diffstat (limited to 'src/LivingVillage.Desktop/SceneDetailRender.fs')
-rw-r--r--src/LivingVillage.Desktop/SceneDetailRender.fs75
1 files changed, 73 insertions, 2 deletions
diff --git a/src/LivingVillage.Desktop/SceneDetailRender.fs b/src/LivingVillage.Desktop/SceneDetailRender.fs
index abe0b89..df2fa10 100644
--- a/src/LivingVillage.Desktop/SceneDetailRender.fs
+++ b/src/LivingVillage.Desktop/SceneDetailRender.fs
@@ -79,7 +79,76 @@ module SceneDetailRender =
spriteBatch.Draw(pixel, Rectangle(x, y - Sim.tilePixels, half, 2 * Sim.tilePixels), litColor)
spriteBatch.Draw(pixel, Rectangle(x + half, y - Sim.tilePixels, w - half, 2 * Sim.tilePixels), darkColor)
- /// 一次性绘制全部 P47 场景细节(倒影 → 岸边芦苇 → 漂浮元素 → 近景前景层)。
+ /// P78 炊烟:生成器世界每户屋顶脊上方一缕,帧号驱动升腾/摇曳,夜帧更醒目。
+ /// 复用江南图集的 22-24 三相位烟精灵,只读、不改瓦片。
+ let private drawSmoke
+ (spriteBatch: SpriteBatch)
+ (textures: VillageArt.ArtTextures)
+ (camera: Vector2)
+ (map: MapGen.Result)
+ (tick: int64)
+ (nightStrength: float32) =
+ let alpha = SceneDetail.smokeAlphaAt nightStrength
+ let size = SceneDetail.smokeCellSize nightStrength
+ let source = VillageArt.atlasTileRectangle (22 + SceneDetail.smokeFrame tick)
+ let color =
+ if nightStrength > 0.5f then VillageArt.premultiply 238 230 214 alpha
+ else VillageArt.premultiply 222 226 228 alpha
+ for (x, y) in SceneDetail.smokeSourceTiles map do
+ let seed = x * 29 + y * 11
+ let dx, dy = SceneDetail.smokeDrift tick seed
+ let cx = tileX camera x + (Sim.tilePixels - size) / 2 + dx
+ let cy = tileY camera y + (Sim.tilePixels - size) / 2 + dy
+ spriteBatch.Draw(textures.TileAtlas, Rectangle(cx, cy, size, size), source, color)
+
+ /// P78 夜帧水面逐格微光斑:帧号驱动、位置确定性,暗部因此有两档以上层次而非整片死黑。
+ let private drawNightWater
+ (spriteBatch: SpriteBatch)
+ (pixel: Texture2D)
+ (camera: Vector2)
+ (map: MapGen.Result)
+ (tick: int64)
+ (nightStrength: float32) =
+ for (x, y) in SceneDetail.waterGlintTiles map do
+ let alpha = SceneDetail.waterGlintAlpha nightStrength (SceneDetail.waterGlintPhase tick x y)
+ if alpha > 0 then
+ let wobble = SceneDetail.waterGlintOffset tick x y
+ let cx = tileX camera x
+ let cy = tileY camera y
+ let soft = VillageArt.premultiply 150 190 232 (alpha / 3)
+ let cool = VillageArt.premultiply 198 224 255 alpha
+ spriteBatch.Draw(pixel, Rectangle(cx + 6 + wobble, cy + 12, 20, 4), soft)
+ spriteBatch.Draw(pixel, Rectangle(cx + 10 + wobble, cy + 13, 11, 2), cool)
+
+ /// P78 桥头灯柱窄光晕:只围灯柱一圈(半径 1 tile),夜里给灯柱一圈暖光而不铺满河面。
+ let private drawBridgeHalos
+ (spriteBatch: SpriteBatch)
+ (pixel: Texture2D)
+ (camera: Vector2)
+ (map: MapGen.Result)
+ (nightStrength: float32) =
+ let peak = int (78.0f * max 0.0f (min 1.0f nightStrength))
+ if peak > 0 then
+ let half = Sim.tilePixels / 2
+ let radius = SceneDetail.bridgeHaloRadiusTiles * Sim.tilePixels
+ for (x, y) in SceneDetail.bridgeLanternTiles map do
+ let cx = tileX camera x + half
+ let cy = tileY camera y + half
+ for (rect, color) in VillageArt.lanternGlowLayers cx cy radius 5 255 214 150 peak do
+ spriteBatch.Draw(pixel, rect, color)
+
+ /// P78 夜帧加成层(水面光斑 + 桥头窄光晕):在 veil 之后调用,故不被夜色乘暗、仍醒目。
+ let drawNight
+ (spriteBatch: SpriteBatch)
+ (pixel: Texture2D)
+ (camera: Vector2)
+ (map: MapGen.Result)
+ (tick: int64)
+ (nightStrength: float32) =
+ drawNightWater spriteBatch pixel camera map tick nightStrength
+ drawBridgeHalos spriteBatch pixel camera map nightStrength
+
+ /// 一次性绘制全部 P47 场景细节(倒影 → 岸边芦苇 → 漂浮元素 → 近景前景层 → P78 炊烟)。
let draw
(spriteBatch: SpriteBatch)
(textures: VillageArt.ArtTextures)
@@ -88,8 +157,10 @@ module SceneDetailRender =
(viewportWidth: int)
(viewportHeight: int)
(map: MapGen.Result)
- (tick: int64) =
+ (tick: int64)
+ (nightStrength: float32) =
drawReflections spriteBatch pixel camera map tick
drawBankReeds spriteBatch textures camera map
drawFloaters spriteBatch textures camera map tick
drawForeground spriteBatch textures pixel viewportWidth viewportHeight tick
+ drawSmoke spriteBatch textures camera map tick nightStrength