fix(ui): 棋盘小人修正批——用户三裁决落地(2026-09-25):①缩放=整数 1× 档 32×32 盒格内居中(HERO_SPRITE_SCALE 常量定档,cell_edge/32 填充公式作废——圣经 §8.2 禁非整数缩放硬规则+v1.9 注记 71% 占格合规预期,上批「填满格」代拍板系误判);②挥铲=握把锚 (18,12) 对齐英雄持握手位(以手为圆心、铲长为半径旋转,手=盒底往上 1/4 盒高·水平居中——hero_hand_point/hero_sprite_scale 出口,共享边中点+12% 偏置作废);③触发=格子点开那一刻确认(settle 同步受理后 refresh 同拍,措辞归位非代码变更);冒烟 557/0+ui_input/click/layout 三探针绿
This commit is contained in:
1 parent
b0880919ee
commit
65325d111d
3 files changed
+38
-18
No files matched your search
@@ -686,10 +686,11 @@ func _on_board_action(cell: Vector2i, kind: String) -> void:
|
||||
if accepted and kind == "dig" and settlement != null and settlement.minesweeper.current_board() != null and settlement.minesweeper.clear_map_cleared():
|
||||
board_zone.fx.play_clear_burst()
|
||||
if accepted and kind == "dig" and settlement != null and settlement.minesweeper != null:
|
||||
# 挖掘演出(棋盘小人贴图批 2026-09-25):挥铲三帧 + 角色弹跳——受理后一拍触发(挖掘不移动英雄,
|
||||
# 出手方向 = 目标格−英雄格;refresh 同拍重绘零冲突)
|
||||
# 挖掘演出(棋盘小人贴图批 2026-09-25):挥铲三帧 + 角色弹跳——触发=格子点开那一刻
|
||||
#(2026-09-25 用户裁决;settle_batch 同步受理即状态已变,动画纯表现与 refresh 同拍零竞态;
|
||||
# 挖掘不移动英雄,出手方向 = 目标格−英雄格,圆心=英雄持握手位)
|
||||
var hero_cell: Vector2i = settlement.minesweeper.hero_pos()
|
||||
board_zone.fx.play_shovel_swing(board_view.cell_origin(hero_cell), cell - hero_cell, board_view.cell_size)
|
||||
board_zone.fx.play_shovel_swing(board_view.hero_hand_point(), cell - hero_cell, board_view.hero_sprite_scale())
|
||||
board_view.play_hero_dig_bounce()
|
||||
elif accepted and kind == "move":
|
||||
board_view.notify_hero_move() # 原地移动(目标=当前格幂等受理)帧闪回执——refresh diff 前置告知
|
||||
|
||||
@@ -125,15 +125,16 @@ func play_flag_hit_projectile(heavy: bool) -> void:
|
||||
|
||||
const SHOVEL_FRAME_PX := 32.0 # 铲帧画布边长(缩放比与英雄帧同源)
|
||||
const SHOVEL_FRAME_S := 0.08 # ~80ms/帧(f0→f1→f2 共 ~240ms 即收)
|
||||
const SHOVEL_GRIP := Vector2(18, 12) # 握把锚点(素材侧锁定的画布坐标——出手位对齐点)
|
||||
const SHOVEL_GRIP := Vector2(18, 12) # 握把锚点(素材侧锁定的画布坐标——英雄持握手位对齐点)
|
||||
|
||||
var _shovel_texs: Array = [] # 惰性装载缓存(素材缺位 = 空表静默回退——素材不入 git)
|
||||
|
||||
|
||||
# 挖掘挥铲:origin = 英雄格左上(board_area 坐标系——BoardView.cell_origin 出口,fx 与棋盘同层同系);
|
||||
# dir = 挖掘方向单位格向量(素材铲头朝左——dir.x>0 翻转);edge = 格边长(缩放 = edge/32 与角色一致)。
|
||||
# 握把锚对齐英雄格与目标格共享边中点(出手位),铲头弧线自然落进目标格。
|
||||
func play_shovel_swing(origin: Vector2, dir: Vector2i, edge: float) -> void:
|
||||
# 挖掘挥铲:hand = 英雄持握手位(BoardView.hero_hand_point 出口,fx 与棋盘同层同系)——
|
||||
# 以手为圆心、铲长为半径旋转(2026-09-25 用户裁决;三帧系素材侧预烤的旋转相位,握把锚 (18,12)
|
||||
# 三帧同位,锚点钉死手位即成弧);dir = 挖掘方向单位格向量(素材铲头朝左——dir.x>0 翻转);
|
||||
# sprite_scale 与英雄精灵同档(整数 1×——原「共享边中点+12% 偏置」定位与 edge/32 缩放作废)。
|
||||
func play_shovel_swing(hand: Vector2, dir: Vector2i, sprite_scale: float) -> void:
|
||||
if _shovel_texs.is_empty():
|
||||
for p in ["res://assets/art/fx/shovel_swing_f0.png",
|
||||
"res://assets/art/fx/shovel_swing_f1.png",
|
||||
@@ -142,20 +143,17 @@ func play_shovel_swing(origin: Vector2, dir: Vector2i, edge: float) -> void:
|
||||
if t == null:
|
||||
return # 素材缺位——静默回退(fx 层占位演出不设断言面)
|
||||
_shovel_texs.append(t)
|
||||
var s := edge / SHOVEL_FRAME_PX
|
||||
var flip := dir.x > 0
|
||||
var grip := SHOVEL_GRIP
|
||||
if flip:
|
||||
grip.x = SHOVEL_FRAME_PX - SHOVEL_GRIP.x # flip_h 围绕纹理中心镜像——锚点 x 随镜
|
||||
var deliver := origin + Vector2(edge, edge) * 0.5 \
|
||||
+ Vector2(dir) * (edge * 0.5 + edge * 0.12) # 共享边中点再向目标格偏 12% 格宽
|
||||
var sp := Sprite2D.new()
|
||||
sp.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
sp.centered = true
|
||||
sp.texture = _shovel_texs[0]
|
||||
sp.flip_h = flip
|
||||
sp.scale = Vector2.ONE * s
|
||||
sp.position = deliver + (Vector2(SHOVEL_FRAME_PX, SHOVEL_FRAME_PX) * 0.5 - grip) * s
|
||||
sp.scale = Vector2.ONE * sprite_scale
|
||||
sp.position = hand + (Vector2(SHOVEL_FRAME_PX, SHOVEL_FRAME_PX) * 0.5 - grip) * sprite_scale
|
||||
add_child(sp)
|
||||
var tw := sp.create_tween()
|
||||
for i in [1, 2]:
|
||||
|
||||
@@ -57,6 +57,10 @@ const DEPTH_BEVEL := 0.6 # 顶面倒角强度
|
||||
|
||||
# 英雄单位演出参数(棋盘小人贴图批 2026-09-25——计划书 §3.B/C 时长档)
|
||||
const HERO_FRAME_PX := 32.0 # 英雄帧画布边长(素材 32×32 锁定——缩放比分母)
|
||||
const HERO_SPRITE_SCALE := 1.0 # 整数 1× 档、32×32 盒格内居中(2026-09-25 用户裁决:不要求覆盖
|
||||
# 格子——圣经 §8.2「禁非整数缩放」硬规则,v1.9 注记 45px 格 1× 占
|
||||
# ≈71% 合规;格边 <32 板溢出 ≤(32−cell)px 接受;计划书原 cell_edge/32
|
||||
# 填充公式作废)
|
||||
const HERO_MOVE_S := 0.14 # 位移时长(~140ms)
|
||||
const HERO_STEP_S := 0.18 # 走路帧周期 = 原地撞墙帧闪时长(~180ms)
|
||||
const HERO_DIG_S := 0.15 # 挖掘弹跳总时长(~150ms,半程压半程回)
|
||||
@@ -251,8 +255,8 @@ func _update_hero(hero: Vector2i) -> void:
|
||||
return
|
||||
if _world.hero == null:
|
||||
var sp: Sprite2D = _world.ensure_hero(_hero_tex_idle)
|
||||
sp.scale = Vector2.ONE * (_cell / HERO_FRAME_PX)
|
||||
sp.position = Vector2(hero) * (_cell + float(SEP)) + Vector2(_cell * 0.5, float(_cell))
|
||||
sp.scale = Vector2.ONE * HERO_SPRITE_SCALE
|
||||
sp.position = _hero_feet(hero)
|
||||
_hero_last = hero # 首建/随 rebuild 重建——即时落位无演出
|
||||
return
|
||||
if hero == _hero_last and not _hero_bump_pending:
|
||||
@@ -273,8 +277,8 @@ func _place_hero(from: Vector2i, to: Vector2i, instant: bool) -> void:
|
||||
var sp: Sprite2D = _world.hero
|
||||
if sp == null:
|
||||
return
|
||||
var s := _cell / HERO_FRAME_PX
|
||||
var feet := Vector2(to) * (_cell + float(SEP)) + Vector2(_cell * 0.5, float(_cell))
|
||||
var s := HERO_SPRITE_SCALE
|
||||
var feet := _hero_feet(to)
|
||||
if _hero_move_tw != null and _hero_move_tw.is_valid():
|
||||
_hero_move_tw.kill()
|
||||
if instant:
|
||||
@@ -322,7 +326,7 @@ func play_hero_dig_bounce() -> void:
|
||||
return
|
||||
if _hero_dig_tw != null and _hero_dig_tw.is_valid():
|
||||
_hero_dig_tw.kill()
|
||||
var s := _cell / HERO_FRAME_PX
|
||||
var s := HERO_SPRITE_SCALE
|
||||
sp.scale = Vector2(s, s)
|
||||
_hero_dig_tw = create_tween()
|
||||
_hero_dig_tw.tween_property(sp, "scale:y", s * HERO_BOUNCE, UiKit.motion(HERO_DIG_S * 0.5)).set_trans(Tween.TRANS_SINE)
|
||||
@@ -335,6 +339,23 @@ func cell_origin(c: Vector2i) -> Vector2:
|
||||
return _svp_container.position + Vector2(c) * (_cell + float(SEP))
|
||||
|
||||
|
||||
# 英雄 32×32 盒格内居中的脚底锚点(盒底中点——弹跳 scale.y 向此收敛)
|
||||
func _hero_feet(c: Vector2i) -> Vector2:
|
||||
var m := (_cell - HERO_FRAME_PX) * 0.5
|
||||
return cell_origin(c) + Vector2(m + HERO_FRAME_PX * 0.5, m + HERO_FRAME_PX)
|
||||
|
||||
|
||||
# 英雄持握手位(fx 同层坐标系)——挥铲特效圆心(2026-09-25 用户裁决:以手为圆心、铲长为半径
|
||||
# 旋转;手 = 盒底往上 1/4 盒高、水平居中)
|
||||
func hero_hand_point() -> Vector2:
|
||||
return _hero_feet(_hero_last) + Vector2(0.0, -HERO_FRAME_PX * 0.25)
|
||||
|
||||
|
||||
# 英雄精灵缩放档(fx 挥铲同档出口——两演出比例恒一致)
|
||||
func hero_sprite_scale() -> float:
|
||||
return HERO_SPRITE_SCALE
|
||||
|
||||
|
||||
# 真实输入路径(行为探针复用):合成点击 → 与真实 gui_input 同一翻译出口
|
||||
func click_cell(cell: Vector2i, button: int) -> void:
|
||||
var ev := InputEventMouseButton.new()
|
||||
|
||||
Reference in new issue
Block a user