# tests/unit/presentation/animation_frame_spec_test.gd — 动画帧数规格守门(定值面=本测试) # 断言面:①帧数规格表冻结(待机循环 4 帧/攻击准备 6 帧单次/受击 2 帧——样张冻结定值, # 规格表与圣经 §8.4 帧数规格条对照,守门防漂移);②现役四态单帧形制锚定(idle/walk 32×32、attack 92×92、 # hit 88×92——现役为单帧状态件,序列帧资产入包时按规格表逐件判帧数并同批换代本套件); # ③死亡=灰化+碎裂退场(非帧件,无帧数断言面)。 # 运行:godot --headless --path game --script res://tests/unit/presentation/animation_frame_spec_test.gd extends SceneTree const Kit := preload("res://tests/unit/test_kit.gd") # 帧数规格表(样张冻结值——多帧序列帧资产的生产规格;现役单帧占位件不适用本表) const SPEC := {"idle": 4, "attack": 6, "hit": 2} # 现役单帧形制(宽,高)——序列帧资产替换形制时同批修订本表并激活规格逐件断言 const CURRENT_FORM := { "character_hero_idle.png": Vector2i(32, 32), "character_hero_walk.png": Vector2i(32, 32), "character_hero_attack.png": Vector2i(92, 92), "character_hero_hit.png": Vector2i(88, 92), } func _init() -> void: # 判据出处: design/art/art-bible.md:539 (帧数规格条——样张冻结定值组) _test_spec_table() _test_current_form() quit(Kit.finish("animation_frame_spec_test")) # ① 规格表冻结面(帧数档定值单点=本表) func _test_spec_table() -> void: # 判据出处: design/art/art-bible.md:539 (帧数规格表冻结组) Kit.check("待机循环 4 帧在表〔帧规格 V1〕", SPEC.get("idle", 0) == 4) Kit.check("攻击准备 6 帧单次在表〔帧规格 V2〕", SPEC.get("attack", 0) == 6) Kit.check("受击 2 帧在表〔帧规格 V3〕", SPEC.get("hit", 0) == 2) # ② 现役单帧形制锚定(真实加载链——资产被换形制而未走规格表时此处红) func _test_current_form() -> void: # 判据出处: design/art/art-bible.md:539 (现役单帧形制组) for fn: String in CURRENT_FORM: var tex: Texture2D = load("res://assets/art/character/" + fn) var want := Vector2(CURRENT_FORM[fn]) Kit.check("现役件在库且形制冻结:%s %s〔帧规格 V4〕" % [fn, want], tex != null and tex.get_size() == want)