From e30f6dcb9af6224719d32fb9e9e56edf76a1e01b Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 30 Sep 2026 05:07:47 +0800 Subject: [PATCH] =?UTF-8?q?iter9-T3:=20=E5=8D=A1=E2=91=A0=20=E6=A3=8B?= =?UTF-8?q?=E7=9B=98=E6=B8=B2=E6=9F=93=E8=90=BD=E7=A0=81=EF=BC=88=E5=9C=A3?= =?UTF-8?q?=E7=BB=8F=20v3.5=20=E5=86=BB=E7=BB=93=E2=91=A0=E6=89=B9=20B1?= =?UTF-8?q?=EF=BC=89=E2=80=94=E2=80=94E=20=E6=A0=BC=E9=AB=98=E5=A2=99=2030?= =?UTF-8?q?%=20=E6=89=BF=E6=8E=A5=EF=BC=88CellUnit=20=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?facade=5Fstrip/tex=5Ffacade+E=5FFACADE=5FFRAC=20=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=EF=BC=8C=E5=A2=99=E9=A1=B6=20center=20=E7=93=A6?= =?UTF-8?q?=E7=89=87=E9=A1=B6=E9=83=A8=E5=8C=BA=E5=B8=A6=E5=8E=9F=E4=BA=AE?= =?UTF-8?q?=E5=BA=A6=E7=9B=B4=E8=B4=B4+=E5=A2=99=E8=84=9A=E9=98=B4?= =?UTF-8?q?=E7=BA=BF=201px=EF=BC=8C=E6=96=B9=E5=90=91=E7=A8=BF=20draw=5Ffa?= =?UTF-8?q?cade/is=5Ffacade=5Fcell=20=E7=A7=BB=E6=A4=8D=EF=BC=89+(b)-(c)?= =?UTF-8?q?=20=E4=BA=A4=E7=95=8C=E6=97=A0=E8=BE=B9=E6=A1=86=EF=BC=88?= =?UTF-8?q?=E5=A2=99=E6=A0=BC=E5=8C=97=E5=90=91=202px=20=E6=8F=8F=E8=BE=B9?= =?UTF-8?q?=E7=93=A6=E7=89=87=E6=80=81=E9=80=80=E5=BD=B9=EF=BC=8C=E5=B9=B3?= =?UTF-8?q?=E8=89=B2=E5=9B=9E=E9=80=80=E4=BF=9D=E7=95=99=EF=BC=89+?= =?UTF-8?q?=E5=9C=B0=E6=9D=BF=E5=BD=92=E4=B8=80=20L0.10=EF=BC=88=5Fnormali?= =?UTF-8?q?ze=5Ffloor=5Fluma=20=E7=A8=8B=E5=BA=8F=E5=BD=92=E4=B8=80?= =?UTF-8?q?=EF=BC=9A8=C3=978=20=E7=BA=BF=E6=80=A7=E5=9F=9F=E6=B5=8B?= =?UTF-8?q?=E5=85=89+=E5=A2=9E=E7=9B=8A=E9=92=B3=20[0.6,1.8]=EF=BC=8C?= =?UTF-8?q?=E6=96=B9=E5=90=91=E7=A8=BF=20=5Fv3=5Fdarken=5Ffloors=20?= =?UTF-8?q?=E5=90=8C=E5=BC=8F=EF=BC=9B=E5=8D=97=E5=90=91=E5=8E=9A=E5=BA=A6?= =?UTF-8?q?=E9=9D=A2/D=20=E6=8A=95=E5=BD=B1=E9=9B=B6=E8=A7=A6=E7=A2=B0?= =?UTF-8?q?=EF=BC=89=EF=BC=9B=E8=BD=BB=E9=97=B8=3D=E5=86=92=E7=83=9F=20596?= =?UTF-8?q?/0+ui=5Finput=20=E5=8D=81=E5=9B=9B=E6=96=AD=E8=A8=80+click=20?= =?UTF-8?q?=E9=97=AE=E9=A2=98=3D0+layout=20=E9=80=80=E5=87=BA=200=EF=BC=88?= =?UTF-8?q?=E9=A6=96=E8=B7=91=20SCRIPT=20ERROR=3DImage.duplicate()=20Varia?= =?UTF-8?q?nt=20=E6=8E=A8=E6=96=AD=EF=BC=8Ctyped=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/presentation/views/board_cell_unit.gd | 27 ++++++++++++++ game/presentation/views/board_view.gd | 42 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/game/presentation/views/board_cell_unit.gd b/game/presentation/views/board_cell_unit.gd index 7187ebd4..b4435c6b 100644 --- a/game/presentation/views/board_cell_unit.gd +++ b/game/presentation/views/board_cell_unit.gd @@ -73,12 +73,22 @@ const FACADE_FAR_COL := Color(0, 0, 0, 0.82) # 立面远段黑罩(墙 const PROJECTION_NEAR_COL := Color(0, 0, 0, 0.28) # 投影贴墙段(地面 66→46 实测 α≈0.28) const PROJECTION_MID_COL := Color(0, 0, 0, 0.16) # 投影中段(渐隐) const PROJECTION_EDGE_COL := Color(0, 0, 0, 0.06) # 投影远段(渐隐收边) +# ── E 格高墙面(圣经 v3.5 冻结① 2026-09-30——地面格南邻墙→南部 30% 承接墙面:墙顶纹理原亮度 +# 直贴零暗档零阴影〔用户终裁「它们是同样颜色的」〕;墙脚阴线只画地面/墙面交界;(b)-(c) 交界 +# 无边框由 BoardView 侧跳过墙格北向描边承载)── +const E_FACADE_FRAC := 0.30 # 墙面承接高(格边比——用户指令 30%) +const E_FACADE_FOOT_COL := Color8(52, 42, 32) # 墙脚阴线(方向稿同色) # ── 素材槽位(本批全 null = 程序化占位服役;art-bible §8.2 格面 32×32 暂定档)── var tex_base: Texture2D = null # ① 砖面底 var tex_mutation: Texture2D = null # ② 变异纹带 var tex_glyph: Texture2D = null # ③ 数字 var tex_badge: Texture2D = null # ③' 徽章 var tex_flag: Texture2D = null # ④ 旗 +var tex_facade: Texture2D = null # ⑥ E 格墙面材质(v3.5——南邻墙顶 center 瓦片同源,BoardView 注入) +var facade_strip := false: # E 格开关(BoardView paint 按「已开格且南邻未开墙」写入——瓦片态专用) + set(v): + facade_strip = v + queue_redraw() # 变异角标(迭代 6 T6——程序化,tex_mutation 纹带槽留给变异纹带六型自产批): # "flat_damage" = 未开格伤害型变异,左下角危险红三角(开格有代价的策略纹理标记) @@ -119,6 +129,7 @@ func _draw() -> void: draw_rect(or_, oc, true) _draw_south_facade() _draw_north_projection() + _draw_e_facade() # 瓦片态描边覆盖层(高墙瓦片接线批 2026-09-26):tex_base 在位时 BoardView 传入的 bg_sb # 已降级为「透明底 + 描边」载体——呼吸微光/主角蓝框画在瓦片之上(art-bible §1.2 叠层序 # 不变:底 < 纹带 < 数字 < 旗 < 焦点高亮);素材缺位回退走 elif 程序化原样,零观感变化 @@ -130,6 +141,7 @@ func _draw() -> void: # 半条边=沿邻边自角点起 edge/2;角点圆 r=6 贴角点圆心,近白芯 r=2.5 提亮) if contact_col.a > 0.0: _draw_north_projection() # 平色回退+微光并发的英雄格补画(瓦片路径已画——同像素重复无观感差) + _draw_e_facade() # E 格墙面补画(同上——英雄格兼 E 格时瓦片路径已画,重复无害) var band := 4.0 var half := edge * 0.5 for b in contact_bands: @@ -251,6 +263,21 @@ func _draw_north_projection() -> void: draw_rect(Rect2(0.0, seg * 2.0, edge, seg), PROJECTION_EDGE_COL, true) +# E 格高墙面(圣经 v3.5 冻结① 2026-09-30——方向稿 draw_facade 移植):本格已开且南邻为墙 → +# 南部 30% 承接墙面。材质 = 墙顶 center 瓦片顶部 30% 区带**原亮度**直贴(零暗档零阴影); +# 墙脚阴线只画地面/墙面交界(strip 顶缘 1px);墙面底缘(格界处)不画任何线——直接接南侧墙顶 +# (v3.4 用户裁定:白边导致两截)。仅瓦片态服役(tex_facade 缺位 = 平色回退原语义不动)。 +func _draw_e_facade() -> void: + if not facade_strip or tex_facade == null: + return + var strip_h := edge * E_FACADE_FRAC + var y0 := edge - strip_h + var ts := tex_facade.get_size() + draw_texture_rect_region(tex_facade, Rect2(0.0, y0, edge, strip_h), + Rect2(0.0, 0.0, ts.x, ts.y * E_FACADE_FRAC)) + draw_rect(Rect2(0.0, y0, edge, 1.0), E_FACADE_FOOT_COL, true) + + # 文字位绘制:水平居中 + 垂直居中(基线 = (格高 − 字高)/2 + 上伸部——旧 Button 居中对齐等价) func _draw_glyph(g: String, col: Color, fs: int) -> void: var f := font if font != null else ThemeDB.fallback_font diff --git a/game/presentation/views/board_view.gd b/game/presentation/views/board_view.gd index 484ec1b9..2df89b18 100644 --- a/game/presentation/views/board_view.gd +++ b/game/presentation/views/board_view.gd @@ -714,6 +714,8 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: u.outline_sides.assign([]) # typed Array[int](代码审查批 3 类型收紧——assign 保持引用语义) u.facade_south = false u.proj_band = 0.0 + u.tex_facade = null + u.facade_strip = false var south_n: Vector2i = c + Vector2i(0, 1) var north_n: Vector2i = c + Vector2i(0, -1) var south_in: bool = south_n.x >= 0 and south_n.y >= 0 and south_n.x < _board.width and south_n.y < _board.height @@ -729,11 +731,18 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: var code := 0 if d.y < 0 else (1 if d.y > 0 else (2 if d.x < 0 else 3)) if code == 1 and u.facade_south: continue # 南缘由立面件承载(高光+双段暗带)——2px 描边让位防三重叠黑 + if code == 0 and _tiles_ok: + continue # v3.5 冻结① (b)-(c) 交界无边框:墙面直贴接墙顶(E 格墙面件在邻格承载)——北向描边退役(平色回退态保留描边) u.outline_sides.append(code) else: # 地面投影:北邻墙格在本已开格北缘投渐隐暗带(ITB 同款高度线索——带宽按格边比例常量) if north_in and not _minesweeper.is_revealed(north_n): u.proj_band = u.edge * WALL_PROJECTION_FRAC + # E 格高墙面(圣经 v3.5 冻结①——方向稿 is_facade_cell 口径):已开格南邻未开墙 → 南部 30% + # 承接墙面(材质=同板墙顶 center 瓦片,原亮度直贴);仅瓦片态启用——平色回退保持原语义 + if south_in and not _minesweeper.is_revealed(south_n) and _tiles_ok: + u.facade_strip = true + u.tex_facade = _tiles.get("wall_center") # ②( 魔法道具叠加层(迭代 7 T4):真视格=红内缩框;预读格=奖励身份徽章(identity_resolver 既有 # 只读面取字形——零数据复制,badge 位复用);已开格标记自然退位(refresh 逐拍重算) if not revealed: @@ -848,6 +857,11 @@ func _load_board_tiles(board_type: String = "dungeon") -> void: if tex == null: _request_dungeon_fallback(board_type) return + # 地板归一(圣经 v3.5 冻结①/§1.4 样张 v3 记录——已开格底归一世界底层档 L≈0.10,带 0.08–0.14): + # 方向稿 _v3_darken_floors 同式移植;现行瓦片 L≈0.036 低于带下沿故实为提亮;素材重产归资产批, + # 本归一为程序代役(逐批装载时对 freshly-loaded 原图测光,幂等) + for i in range(floors.size()): + floors[i] = _normalize_floor_luma(floors[i]) # 六镜像件(词表 §二:wall_e←wall_w / wall_ne←wall_nw / wall_se←wall_sw / # wall_end_e←wall_end_w / wall_in_ne←wall_in_nw / wall_in_se←wall_in_sw;只水平翻转禁旋转 # ——北受光不受损) @@ -880,6 +894,34 @@ static func _flip_tex(tex: Texture2D) -> Texture2D: return ImageTexture.create_from_image(img) +# 地板瓦片明度归一(v3.5 批 B1——方向稿 _v3_darken_floors 同式移植):8×8 双线性重采样均值测光 +# (sRGB→线性域,Rec.709 系数),增益 k=(目标/实测)^(1/2.2) 钳 [0.6,1.8],逐通道 sRGB 域线性拉伸。 +# 输入恒为 freshly-loaded 原图(load_tex 每次盘读)——幂等可重入;32×32 五变体开销可忽略 +static func _normalize_floor_luma(tex: Texture2D, target_l: float = 0.10) -> Texture2D: + var img: Image = tex.get_image() + if img.is_compressed(): + img.decompress() + img.convert(Image.FORMAT_RGBA8) + var small: Image = img.duplicate() + small.resize(8, 8, Image.INTERPOLATE_BILINEAR) + var sum := 0.0 + for y in range(8): + for x in range(8): + var p := small.get_pixel(x, y) + sum += 0.2126 * _srgb_lin(p.r) + 0.7152 * _srgb_lin(p.g) + 0.0722 * _srgb_lin(p.b) + var k := pow(target_l / maxf(sum / 64.0, 0.001), 1.0 / 2.2) + k = clampf(k, 0.6, 1.8) + for y in range(img.get_height()): + for x in range(img.get_width()): + var c := img.get_pixel(x, y) + img.set_pixel(x, y, Color(minf(c.r * k, 1.0), minf(c.g * k, 1.0), minf(c.b * k, 1.0), c.a)) + return ImageTexture.create_from_image(img) + + +static func _srgb_lin(c: float) -> float: + return c / 12.92 if c <= 0.04045 else pow((c + 0.055) / 1.055, 2.4) + + # 格坐标确定性散列(禁 RNG/禁 randomize 纪律——「初始化随机落定禁逐轮重掷」圣经原则三落点: # 同格坐标恒同值,refresh/重绘/逐轮不变)。乘加混合 + 移位雪崩;64 位整型乘法回绕即哈希语义 #(GDScript int 溢出静默回绕),板域 10×10/12×12 内 mod 10/mod 5 分布均匀