diff --git a/assets/bundle1/anim/player/1/attack/3/attack3.anim b/assets/bundle1/anim/player/1/attack/3/attack3.anim index ecd9a59..f3e506f 100644 --- a/assets/bundle1/anim/player/1/attack/3/attack3.anim +++ b/assets/bundle1/anim/player/1/attack/3/attack3.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/bundle1/anim/player/1/attack/5/attack5.anim b/assets/bundle1/anim/player/1/attack/5/attack5.anim index a2c513a..3ff8ee7 100644 --- a/assets/bundle1/anim/player/1/attack/5/attack5.anim +++ b/assets/bundle1/anim/player/1/attack/5/attack5.anim @@ -1,7 +1,7 @@ [ { "__type__": "cc.AnimationClip", - "_name": "attack", + "_name": "attack5", "_objFlags": 0, "__editorExtras__": { "embeddedPlayerGroups": [] @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/bundle1/anim/player/2/attack/3/attack3_2.anim b/assets/bundle1/anim/player/2/attack/3/attack3_2.anim index 62ed6e8..9d154fc 100644 --- a/assets/bundle1/anim/player/2/attack/3/attack3_2.anim +++ b/assets/bundle1/anim/player/2/attack/3/attack3_2.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.5166666666666667, "_hash": 500763545, diff --git a/assets/bundle1/anim/player/2/attack/5/attack5_2.anim b/assets/bundle1/anim/player/2/attack/5/attack5_2.anim index 7b8bbf7..1cf2b50 100644 --- a/assets/bundle1/anim/player/2/attack/5/attack5_2.anim +++ b/assets/bundle1/anim/player/2/attack/5/attack5_2.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.5166666666666667, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/1/attack/guai_1_attack.anim b/assets/resources/anim/xiaoguai/1/attack/guai_1_attack.anim index 50f1e6b..ff74241 100644 --- a/assets/resources/anim/xiaoguai/1/attack/guai_1_attack.anim +++ b/assets/resources/anim/xiaoguai/1/attack/guai_1_attack.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/10/attack/guai_10_attack.anim b/assets/resources/anim/xiaoguai/10/attack/guai_10_attack.anim index a668c1a..9fb9838 100644 --- a/assets/resources/anim/xiaoguai/10/attack/guai_10_attack.anim +++ b/assets/resources/anim/xiaoguai/10/attack/guai_10_attack.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.5166666666666667, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/2/attack/guai_2_attack.anim b/assets/resources/anim/xiaoguai/2/attack/guai_2_attack.anim index 4e6b435..9be95eb 100644 --- a/assets/resources/anim/xiaoguai/2/attack/guai_2_attack.anim +++ b/assets/resources/anim/xiaoguai/2/attack/guai_2_attack.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/4/stand/guai_4_stand.anim b/assets/resources/anim/xiaoguai/4/stand/guai_4_stand.anim index 9e77bff..0e90e1e 100644 --- a/assets/resources/anim/xiaoguai/4/stand/guai_4_stand.anim +++ b/assets/resources/anim/xiaoguai/4/stand/guai_4_stand.anim @@ -1,7 +1,7 @@ [ { "__type__": "cc.AnimationClip", - "_name": "guai_2_stand", + "_name": "guai_4_stand", "_objFlags": 0, "__editorExtras__": { "embeddedPlayerGroups": [] @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/6/attack/guai_6_attack.anim b/assets/resources/anim/xiaoguai/6/attack/guai_6_attack.anim index e369591..629396f 100644 --- a/assets/resources/anim/xiaoguai/6/attack/guai_6_attack.anim +++ b/assets/resources/anim/xiaoguai/6/attack/guai_6_attack.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/7/attack/guai_7_attack.anim b/assets/resources/anim/xiaoguai/7/attack/guai_7_attack.anim index 5664048..27323cc 100644 --- a/assets/resources/anim/xiaoguai/7/attack/guai_7_attack.anim +++ b/assets/resources/anim/xiaoguai/7/attack/guai_7_attack.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.5166666666666667, "_hash": 500763545, diff --git a/assets/resources/anim/xiaoguai/9/attack/guai_9_attack.anim b/assets/resources/anim/xiaoguai/9/attack/guai_9_attack.anim index 001608e..9eb574d 100644 --- a/assets/resources/anim/xiaoguai/9/attack/guai_9_attack.anim +++ b/assets/resources/anim/xiaoguai/9/attack/guai_9_attack.anim @@ -9,7 +9,7 @@ "_native": "", "sample": 60, "speed": 1, - "wrapMode": 2, + "wrapMode": 1, "enableTrsBlending": false, "_duration": 0.6, "_hash": 500763545, diff --git a/assets/scenes/main.scene b/assets/scenes/main.scene index 465bb45..bf086e0 100644 --- a/assets/scenes/main.scene +++ b/assets/scenes/main.scene @@ -5830,8 +5830,8 @@ "_prefab": null, "_lpos": { "__type__": "cc.Vec3", - "x": -400.503, - "y": 15.062, + "x": -447.377, + "y": 57.053, "z": 0 }, "_lrot": { @@ -7098,8 +7098,8 @@ "_prefab": null, "_lpos": { "__type__": "cc.Vec3", - "x": -115.124, - "y": 474.868, + "x": -75.252, + "y": 454.446, "z": 0 }, "_lrot": { diff --git a/assets/scripts/PlayerController.ts b/assets/scripts/PlayerController.ts index 9742e6d..eb9b505 100644 --- a/assets/scripts/PlayerController.ts +++ b/assets/scripts/PlayerController.ts @@ -730,16 +730,22 @@ export class PlayerController extends Component { } } - // 播放攻击动画 - const animNode = otherCollider.node.getChildByName('Anim'); - const monsterAnimation = animNode ? animNode.getComponent(Animation) : null; - if (monsterAnimation) { - monsterAnimation.play(`${otherCollider.node.name}_attack`); - } - this.switchAnimation(this.currentDirection === 3 ? 'attack3' : 'attack5'); + // 获取玩家动画组件 + const playerAnimNode = this.player.getChildByName('Anim'); + const playerAnimation = playerAnimNode ? playerAnimNode.getComponent(Animation) : null; - // 1.2秒后判定攻击结果 - this.scheduleOnce(async () => { + if (!playerAnimation) { + console.warn('未找到玩家动画组件'); + this.isAttacking = false; + return; + } + + // 播放玩家攻击动画 + const attackAnimationName = this.currentDirection === 3 ? 'attack3' : 'attack5'; + this.switchAnimation(attackAnimationName); + + // 监听玩家攻击动画结束事件 + playerAnimation.once(Animation.EventType.FINISHED, async () => { if (!this.player || !playerLabel.isValid || !monsterLabel.isValid) { this.isAttacking = false; if (this.attackAudio) { @@ -750,81 +756,16 @@ export class PlayerController extends Component { } return; } + // 比较生命值,判断输赢 console.log('判定攻击结果,玩家HP:', playerHp, '怪物HP:', monsterHp); + if (playerHp >= monsterHp) { - const hit = otherCollider.node.getChildByName('Hit'); - - if (hit) { - hit.active = true; - } - - this.hasWinTimes++; - // 玩家获胜 - console.log('玩家获胜!更新玩家生命值为:', playerHp + monsterHp); - - // 玩家生命值增加怪物生命值 - const newPlayerHp = playerHp + monsterHp; - playerLabel.string = newPlayerHp.toString(); - - // 播放生命值标签的强调动画 - this.playLabelEmphasisAnimation(playerLabel); - - // 播放怪物死亡动画 - if (monsterAnimation) { - monsterAnimation.play(`${otherCollider.node.name}_die`); - } - - // 如果是攻击 guai_2 并且成功,创建道具飞向 player 的动画 - if (otherCollider.node.name === 'guai_2') { - await this.createPropsFlyToPlayerAnimation(); - } - - // 1秒后怪物消失 - this.scheduleOnce(() => { - if (!otherCollider.node || !otherCollider.node.isValid) { - return; - } - - console.log('怪物已消失'); - otherCollider.node.destroy(); - - if (this.hasWinTimes === 7) { - this.isWin = true; - this.showBonusPopup(); - } - - }, 1); - - this.switchAnimation('stand'); // 玩家站立 - - + // 玩家获胜,直接执行后续流程,不需要播放怪物攻击动画 + await this.handlePlayerWin(otherCollider, playerLabel, monsterHp); } else { - // 怪物获胜 - console.log('怪物获胜!玩家生命值变为0'); - - // 玩家生命值变为0 - playerLabel.string = '0'; - - // 播放生命值标签的失败动画 - this.playLabelFailAnimation(playerLabel); - - // 玩家死亡动画 - this.switchAnimation('die'); - - // 怪物站立动画 - if (monsterAnimation) { - monsterAnimation.play(`${otherCollider.node.name}_stand`); - } - - // 设置游戏结束标志,禁止后续寻路 - this.isGameOver = true; - console.log('游戏结束,禁止寻路'); - - // 显示失败弹窗 - this.scheduleOnce(() => { - this.showFailedDialog(); - }, 1); // 延迟1秒显示失败弹窗,让玩家死亡动画播放完成 + // 玩家输了,需要播放怪物攻击动画 + await this.handleMonsterAttack(otherCollider, playerLabel, monsterHp); } this.isAttacking = false; @@ -837,7 +778,117 @@ export class PlayerController extends Component { console.log('停止攻击音效'); } } - }, 1.2); + }); + } + + /** + * 处理玩家获胜的情况 + */ + private async handlePlayerWin(otherCollider: Collider2D, playerLabel: Label, monsterHp: number) { + const hit = otherCollider.node.getChildByName('Hit'); + if (hit) { + hit.active = true; + } + + this.hasWinTimes++; + // 玩家获胜 + console.log('玩家获胜!更新玩家生命值为:', parseInt(playerLabel.string) + monsterHp); + + // 玩家生命值增加怪物生命值 + const playerHp = parseInt(playerLabel.string) || 0; + const newPlayerHp = playerHp + monsterHp; + playerLabel.string = newPlayerHp.toString(); + + // 播放生命值标签的强调动画 + this.playLabelEmphasisAnimation(playerLabel); + + // 播放怪物死亡动画 + const animNode = otherCollider.node.getChildByName('Anim'); + const monsterAnimation = animNode ? animNode.getComponent(Animation) : null; + if (monsterAnimation) { + monsterAnimation.play(`${otherCollider.node.name}_die`); + } + + // 如果是攻击 guai_2 并且成功,创建道具飞向 player 的动画 + if (otherCollider.node.name === 'guai_2') { + await this.createPropsFlyToPlayerAnimation(); + } + + // 1秒后怪物消失 + this.scheduleOnce(() => { + if (!otherCollider.node || !otherCollider.node.isValid) { + return; + } + + console.log('怪物已消失'); + otherCollider.node.destroy(); + + if (this.hasWinTimes === 7) { + this.isWin = true; + this.showBonusPopup(); + } + }, 1); + + this.switchAnimation('stand'); // 玩家站立 + } + + /** + * 处理怪物攻击的情况 + */ + private async handleMonsterAttack(otherCollider: Collider2D, playerLabel: Label, monsterHp: number) { + // 播放怪物攻击动画 + const animNode = otherCollider.node.getChildByName('Anim'); + const monsterAnimation = animNode ? animNode.getComponent(Animation) : null; + + if (monsterAnimation) { + // 创建Promise来监听怪物攻击动画结束 + return new Promise((resolve) => { + monsterAnimation.play(`${otherCollider.node.name}_attack`); + + // 监听怪物攻击动画结束 + monsterAnimation.once(Animation.EventType.FINISHED, () => { + // 怪物攻击动画结束后,执行玩家死亡逻辑 + this.executePlayerDefeat(otherCollider, playerLabel); + resolve(); + }); + }); + } else { + // 如果没有怪物动画组件,直接执行玩家死亡逻辑 + this.executePlayerDefeat(otherCollider, playerLabel); + } + } + + /** + * 执行玩家失败逻辑 + */ + private executePlayerDefeat(otherCollider: Collider2D, playerLabel: Label) { + // 怪物获胜 + console.log('怪物获胜!玩家生命值变为0'); + + // 玩家生命值变为0 + playerLabel.string = '0'; + + // 播放生命值标签的失败动画 + this.playLabelFailAnimation(playerLabel); + + // 玩家死亡动画 + this.switchAnimation('die'); + + // 怪物站立动画 + const animNode = otherCollider.node.getChildByName('Anim'); + const monsterAnimation = animNode ? animNode.getComponent(Animation) : null; + if (monsterAnimation) { + monsterAnimation.play(`${otherCollider.node.name}_stand`); + } + + // 设置游戏结束标志,禁止后续寻路 + this.isGameOver = true; + console.log('游戏结束,禁止寻路'); + + // 显示失败弹窗 + this.scheduleOnce(() => { + this.showFailedDialog(); + }, 1); // 延迟1秒显示失败弹窗,让玩家死亡动画播放完成 } private handleBoxCollision(otherCollider: Collider2D) {