diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-21 21:53:53 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-21 21:53:53 +0800 |
| commit | b5ffb35fc0824a297ff88297390310acb6c45335 (patch) | |
| tree | 08ef71069e75719e2c92ddd538ec7d58866752f2 /src/LivingVillage.Desktop/Game.fs | |
| parent | 3777d74423bcc941d48ca69bdf6bbc912a80ba57 (diff) | |
| download | living-village-b5ffb35fc0824a297ff88297390310acb6c45335.tar.gz | |
fix(desktop): 灯笼光晕按自身 alpha 预乘并改径向层叠,消除夜间纯白方块
- 新增 VillageArt.premultiply:MonoGame SpriteBatch 默认预乘混合,直传
Color(r,g,b,a) 会直接加 rgb 导致多层暖色饱和成 75x75 纯白块
- lanternGlowLayers 用同心圆 pixel run 做径向衰减,逐层预乘,只在
RiverLantern 实体处绘制
- 水面相位改 waterFrameTickAt=(tick/32+x+2y)%3,同一帧相邻砖相位不同
- 炊烟改为 drawWorld 末尾独立一遍,位置 offsetTile 0 -3,画在屋瓦/竹子之上
- 角色脚底对齐 characterFeetOffset=16 并加预乘椭圆接触阴影
- 补全 Interaction.itemName 的 ItemKind 匹配(否则非 Food 交易会崩溃且告警)
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index c91fe6e..6918e00 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -741,28 +741,28 @@ type LivingVillageGame() as this = profile.WorldTint // Warm lantern glows strengthen as night falls (pure function of tick phase). - // Soft radial falloff made of wide translucent rings; no hot white core, - // the lantern sprite itself stays readable underneath. + // Concentric premultiplied circles fall off radially from each lantern tile, so + // the core stays a soft warm disc instead of saturating into a white block, and + // no glow is painted where there is no lantern entity. if profile.LanternGlow > 0.3f then let glow = profile.LanternGlow - let haloAlpha = int (34.0f * glow) - let ringAlpha = int (18.0f * glow) + let peakAlpha = int (140.0f * glow) for prop in renderPlan.Props do match prop.Kind with | VillageArt.RenderPropKind.RiverLantern -> let position = VillageArt.worldTile renderPlan prop.Position - let screenX = position.X * Sim.tilePixels - int camera.X + Sim.tilePixels / 2 - let screenY = position.Y * Sim.tilePixels - int camera.Y - Sim.tilePixels / 2 - spriteBatch.Draw(pixel, Rectangle(screenX - 30, screenY - 30, 76, 76), Color(252, 196, 128, int (float32 ringAlpha * 0.5f))) - spriteBatch.Draw(pixel, Rectangle(screenX - 24, screenY - 24, 64, 64), Color(252, 206, 148, ringAlpha)) - spriteBatch.Draw(pixel, Rectangle(screenX - 18, screenY - 18, 52, 52), Color(252, 216, 148, haloAlpha)) - spriteBatch.Draw(pixel, Rectangle(screenX - 12, screenY - 12, 40, 40), Color(255, 226, 168, haloAlpha)) + let centerX = position.X * Sim.tilePixels - int camera.X + Sim.tilePixels / 2 + let centerY = position.Y * Sim.tilePixels - int camera.Y + Sim.tilePixels / 2 + for (rect, color) in VillageArt.lanternGlowLayers centerX centerY 44 6 255 214 150 peakAlpha do + spriteBatch.Draw(pixel, rect, color) | _ -> () + VillageArt.drawGroundShadow spriteBatch pixel camera world.Avatar.Pos let avatarSpec = VillageArt.avatarSpriteSpec avatarFacing avatarMoving world.Tick VillageArt.drawCharacter spriteBatch artTextures camera world.Avatar.Pos avatarSpec profile.WorldTint for npc in world.Npcs do + VillageArt.drawGroundShadow spriteBatch pixel camera npc.Pos let spec = VillageArt.npcSpriteSpecAtTarget npc.Id npc.Pos npc.Mind.Target world.Tick VillageArt.drawCharacter spriteBatch artTextures camera npc.Pos spec profile.WorldTint spriteBatch.End() |
