From e2f80547943eb200c75eae8332f15d28317df7da Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 9 Apr 2026 19:01:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9stop=E4=B9=8B=E5=90=8EsetAnim?= =?UTF-8?q?ation=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Game_Surface_3/docs/Spine动画集成手册.md | 51 ++++++++++++++++--- .../Projects/Game_Surface_3/js/SpineMgr.js | 24 +++++++++ .../client/Projects/Spine/js/SpineMgr.js | 1 + 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/codes/games/client/Projects/Game_Surface_3/docs/Spine动画集成手册.md b/codes/games/client/Projects/Game_Surface_3/docs/Spine动画集成手册.md index e7398eb..23c6f2a 100644 --- a/codes/games/client/Projects/Game_Surface_3/docs/Spine动画集成手册.md +++ b/codes/games/client/Projects/Game_Surface_3/docs/Spine动画集成手册.md @@ -375,9 +375,43 @@ gameabc_face.spineMgr.playQueue("hero", ["intro", "idle"], false); --- -### 4.14 remove(id) +### 4.14 stop(id) -**销毁指定 Spine 实例,释放内存。** +**停止指定 Spine 实例的动画并隐藏。** 实例保留在内存中,可随时重新播放。 +与 `setVisible(false)` 不同,`stop` 会彻底清空动画轨道、重置骨骼姿态,并清除待执行命令队列。 + +```javascript +// 停止单个 Spine 动画(保留实例,可重播) +gameabc_face.spineMgr.stop("hero"); + +// 之后可以重新播放 +gameabc_face.spineMgr.playOnce("hero", "attack"); +``` + +| 行为 | 说明 | +|------|------| +| 隐藏 | `visible = false` | +| 清空动画轨道 | `state.clearTracks()` | +| 重置骨骼姿态 | `skeleton.setToSetupPose()` | +| 清除待执行命令 | 删除 `_pendingCmds[id]` | +| 清除自动隐藏标记 | `_hideOnComplete = false` | + +--- + +### 4.15 stopAll() + +**停止所有 Spine 实例的动画并隐藏。** 所有实例保留在内存中,可随时重新播放。 + +```javascript +// 停止全部 Spine 动画(如:切换游戏场景时) +gameabc_face.spineMgr.stopAll(); +``` + +--- + +### 4.16 remove(id) + +**彻底销毁指定 Spine 实例,释放内存。** 销毁后无法重新播放,需要重新 `load` 或自动加载。 ```javascript gameabc_face.spineMgr.remove("hero"); @@ -385,15 +419,17 @@ gameabc_face.spineMgr.remove("hero"); --- -### 4.15 removeAll() +### 4.17 removeAll() -**销毁所有 Spine 实例。** +**彻底销毁所有 Spine 实例,释放内存。** ```javascript gameabc_face.spineMgr.removeAll(); ``` -### 4.16 spine_onComplete(spineId, animName, trackIndex) *(事件回调)* +--- + +### 4.18 spine_onComplete(spineId, animName, trackIndex) *(事件回调)* **动画完成回调。每次动画播放一轮结束时触发。** 在 `js/Spine_Event.js` 中定义。 @@ -418,7 +454,7 @@ gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { --- -### 4.17 spine_onEvent(spineId, eventName, intValue, floatValue, stringValue) *(事件回调)* +### 4.19 spine_onEvent(spineId, eventName, intValue, floatValue, stringValue) *(事件回调)* **自定义事件回调。当动画播放到 Spine 编辑器中定义的 Event 关键帧时触发。** 在 `js/Spine_Event.js` 中定义。 @@ -449,7 +485,7 @@ gameabc_face.spine_onEvent = function(spineId, eventName, intValue, floatValue, ## 5. 事件系统(详细说明) Spine 动画在运行时会触发两类事件,回调定义在 `js/Spine_Event.js` 中。 -API 签名见 [4.16](#416-spine_oncompletespineid-animname-trackindex--事件回调) 和 [4.17](#417-spine_oneventspineid-eventname-intvalue-floatvalue-stringvalue--事件回调)。 +API 签名见 [4.18](#418-spine_oncompletespineid-animname-trackindex--事件回调) 和 [4.19](#419-spine_oneventspineid-eventname-intvalue-floatvalue-stringvalue--事件回调)。 ### 5.1 动画完成事件 spine_onComplete @@ -674,6 +710,7 @@ gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { - Canvas 2D 渲染性能有限,建议同屏 Spine 实例不超过 **5-8 个** - 不可见的实例调用 `setVisible(id, false)`,跳过渲染和更新 +- 场景切换时调用 `stopAll()` 一键关闭所有 Spine 动画 - 不再需要的实例调用 `remove(id)` 释放内存 ### 8.3 减少骨骼复杂度 diff --git a/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js b/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js index db3fd98..b6dded3 100644 --- a/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js +++ b/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js @@ -227,6 +227,7 @@ var SpineMgr = { this._queueCmd(id, "setAnimation", [animName, loop, track]); return null; } + e.visible = true; if (!e.ready) { this._queueCmd(id, "setAnimation", [animName, loop, track]); return null; @@ -355,12 +356,35 @@ var SpineMgr = { } }, + stop: function(id) { + var e = this._entries[id]; + if (!e) return; + e.visible = false; + e._hideOnComplete = false; + e._hideAfterCompletes = 0; + delete this._pendingCmds[id]; + if (e.state) { + e.state.clearTracks(); + } + if (e.skeleton) { + e.skeleton.setToSetupPose(); + } + }, + + stopAll: function() { + for (var id in this._entries) { + this.stop(id); + } + }, + remove: function(id) { delete this._entries[id]; + delete this._pendingCmds[id]; }, removeAll: function() { this._entries = {}; + this._pendingCmds = {}; } }; diff --git a/codes/games/client/Projects/Spine/js/SpineMgr.js b/codes/games/client/Projects/Spine/js/SpineMgr.js index 9a989b0..b6dded3 100644 --- a/codes/games/client/Projects/Spine/js/SpineMgr.js +++ b/codes/games/client/Projects/Spine/js/SpineMgr.js @@ -227,6 +227,7 @@ var SpineMgr = { this._queueCmd(id, "setAnimation", [animName, loop, track]); return null; } + e.visible = true; if (!e.ready) { this._queueCmd(id, "setAnimation", [animName, loop, track]); return null;