feat: 优化打斗逻辑
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "stand_2",
|
||||
"_name": "stand5_2",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {
|
||||
"embeddedPlayerGroups": []
|
||||
@@ -9,7 +9,7 @@
|
||||
"_native": "",
|
||||
"sample": 20,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"wrapMode": 2,
|
||||
"enableTrsBlending": false,
|
||||
"_duration": 1.25,
|
||||
"_hash": 500763545,
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
"embeddedPlayerGroups": []
|
||||
},
|
||||
"_native": "",
|
||||
"sample": 60,
|
||||
"sample": 8,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"wrapMode": 2,
|
||||
"enableTrsBlending": false,
|
||||
"_duration": 0.6,
|
||||
"_duration": 1,
|
||||
"_hash": 500763545,
|
||||
"_tracks": [
|
||||
{
|
||||
@@ -62,13 +62,13 @@
|
||||
"__type__": "cc.ObjectCurve",
|
||||
"_times": [
|
||||
0,
|
||||
0.08333333333333333,
|
||||
0.16666666666666666,
|
||||
0.125,
|
||||
0.25,
|
||||
0.3333333333333333,
|
||||
0.4166666666666667,
|
||||
0.375,
|
||||
0.5,
|
||||
0.5833333333333334
|
||||
0.625,
|
||||
0.75,
|
||||
0.875
|
||||
],
|
||||
"_values": [
|
||||
{
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
"embeddedPlayerGroups": []
|
||||
},
|
||||
"_native": "",
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"sample": 20,
|
||||
"speed": 0.5,
|
||||
"wrapMode": 2,
|
||||
"enableTrsBlending": false,
|
||||
"_duration": 0.6,
|
||||
"_duration": 0.4,
|
||||
"_hash": 500763545,
|
||||
"_tracks": [
|
||||
{
|
||||
@@ -61,20 +61,15 @@
|
||||
{
|
||||
"__type__": "cc.ObjectCurve",
|
||||
"_times": [
|
||||
0,
|
||||
0.08333333333333333,
|
||||
0.16666666666666666,
|
||||
0.05,
|
||||
0.1,
|
||||
0.15,
|
||||
0.2,
|
||||
0.25,
|
||||
0.3333333333333333,
|
||||
0.4166666666666667,
|
||||
0.5,
|
||||
0.5833333333333334
|
||||
0.3,
|
||||
0.35
|
||||
],
|
||||
"_values": [
|
||||
{
|
||||
"__uuid__": "78ffae32-3bfe-41cb-823f-3b0bca65732a@f9941",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "8742c745-dcb8-44d8-a276-62e561e81dab@f9941",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
|
||||
@@ -982,19 +982,40 @@ export class PlayerController extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
// 播放玩家攻击动画(只传递基础动画名称)
|
||||
this.switchAnimation('attack');
|
||||
// 检查是否是 guai_10,如果是则使用特殊战斗逻辑
|
||||
if (otherCollider.node.name === 'guai_10') {
|
||||
await this.handleGuai10SpecialAttack(selfCollider, otherCollider, playerLabel, monsterLabel, playerHp, monsterHp, playerAnimation);
|
||||
} else {
|
||||
// 原有的普通战斗逻辑
|
||||
await this.handleNormalAttack(otherCollider, playerLabel, monsterLabel, playerHp, monsterHp, playerAnimation);
|
||||
}
|
||||
|
||||
// 监听玩家攻击动画结束事件
|
||||
playerAnimation.once(Animation.EventType.FINISHED, async () => {
|
||||
if (!this.player || !playerLabel.isValid || !monsterLabel.isValid) {
|
||||
this.isAttacking = false;
|
||||
|
||||
// 停止攻击音效
|
||||
if (this.attackAudio) {
|
||||
const audioSource = this.attackAudio.getComponent(AudioSource);
|
||||
if (audioSource) {
|
||||
audioSource.stop();
|
||||
console.log('停止攻击音效');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理普通怪物的攻击逻辑
|
||||
*/
|
||||
private async handleNormalAttack(otherCollider: Collider2D, playerLabel: Label, monsterLabel: Label, playerHp: number, monsterHp: number, playerAnimation: Animation) {
|
||||
// 播放玩家攻击动画(只传递基础动画名称)
|
||||
this.switchAnimation('attack');
|
||||
|
||||
// 监听玩家攻击动画结束事件
|
||||
return new Promise<void>((resolve) => {
|
||||
playerAnimation.once(Animation.EventType.FINISHED, async () => {
|
||||
if (!this.player || !playerLabel.isValid || !monsterLabel.isValid) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1009,19 +1030,140 @@ export class PlayerController extends Component {
|
||||
await this.handleMonsterAttack(otherCollider, playerLabel, monsterHp);
|
||||
}
|
||||
|
||||
this.isAttacking = false;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 停止攻击音效
|
||||
if (this.attackAudio) {
|
||||
const audioSource = this.attackAudio.getComponent(AudioSource);
|
||||
if (audioSource) {
|
||||
audioSource.stop();
|
||||
console.log('停止攻击音效');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 处理 guai_10 的特殊攻击逻辑:玩家攻击 → 怪物还击 → 玩家再攻击 → 最终判定
|
||||
*/
|
||||
private async handleGuai10SpecialAttack(selfCollider: Collider2D, otherCollider: Collider2D, playerLabel: Label, monsterLabel: Label, playerHp: number, monsterHp: number, playerAnimation: Animation) {
|
||||
console.log('开始 guai_10 特殊战斗逻辑');
|
||||
|
||||
// 第一轮:玩家攻击
|
||||
console.log('第一轮:玩家攻击');
|
||||
this.switchAnimation('attack');
|
||||
|
||||
// 等待玩家攻击动画结束
|
||||
await new Promise<void>((resolve) => {
|
||||
playerAnimation.once(Animation.EventType.FINISHED, () => {
|
||||
console.log('玩家第一轮攻击完成');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
// 检查节点是否仍然有效
|
||||
if (!this.player || !otherCollider.node || !otherCollider.node.isValid || !playerLabel.isValid || !monsterLabel.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 第二轮:怪物还击
|
||||
console.log('第二轮:怪物还击');
|
||||
await this.playMonsterAttackAnimation(otherCollider);
|
||||
|
||||
// 检查节点是否仍然有效
|
||||
if (!this.player || !otherCollider.node || !otherCollider.node.isValid || !playerLabel.isValid || !monsterLabel.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保玩家在怪物攻击后回到站立状态,然后再进行第三轮攻击
|
||||
this.switchAnimation('stand');
|
||||
|
||||
// 添加短暂延迟,让玩家站立动画播放一下
|
||||
await new Promise<void>((resolve) => {
|
||||
this.scheduleOnce(() => {
|
||||
resolve();
|
||||
}, 0.2);
|
||||
});
|
||||
|
||||
// 第三轮:玩家再次攻击
|
||||
console.log('第三轮:玩家再次攻击');
|
||||
this.switchAnimation('attack');
|
||||
|
||||
// 等待玩家攻击动画结束
|
||||
await new Promise<void>((resolve) => {
|
||||
playerAnimation.once(Animation.EventType.FINISHED, () => {
|
||||
console.log('玩家第三轮攻击完成');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// 检查节点是否仍然有效
|
||||
if (!this.player || !otherCollider.node || !otherCollider.node.isValid || !playerLabel.isValid || !monsterLabel.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 最终判定:比较生命值
|
||||
console.log('最终判定,玩家HP:', playerHp, '怪物HP:', monsterHp);
|
||||
|
||||
if (playerHp >= monsterHp) {
|
||||
// 玩家获胜
|
||||
await this.handlePlayerWin(otherCollider, playerLabel, monsterHp);
|
||||
} else {
|
||||
// 玩家失败
|
||||
this.executePlayerDefeat(otherCollider, playerLabel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放怪物攻击动画
|
||||
*/
|
||||
private async playMonsterAttackAnimation(otherCollider: Collider2D): Promise<void> {
|
||||
const animNode = otherCollider.node.getChildByName('Anim');
|
||||
const monsterAnimation = animNode ? animNode.getComponent(Animation) : null;
|
||||
|
||||
if (monsterAnimation) {
|
||||
console.log(`尝试播放怪物攻击动画: ${otherCollider.node.name}_attack`);
|
||||
|
||||
// 检查动画是否存在
|
||||
const attackAnimState = monsterAnimation.getState(`${otherCollider.node.name}_attack`);
|
||||
if (!attackAnimState) {
|
||||
console.warn(`怪物攻击动画 ${otherCollider.node.name}_attack 不存在,跳过怪物攻击动画`);
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
// 添加超时机制,防止动画卡住
|
||||
const timeout = setTimeout(() => {
|
||||
console.log('怪物攻击动画超时,强制继续');
|
||||
// 确保怪物切换回站立状态
|
||||
this.switchMonsterToStand(otherCollider.node.name, monsterAnimation);
|
||||
resolve();
|
||||
}, 3000); // 3秒超时
|
||||
|
||||
monsterAnimation.play(`${otherCollider.node.name}_attack`);
|
||||
console.log('开始播放怪物攻击动画');
|
||||
|
||||
// 监听怪物攻击动画结束
|
||||
monsterAnimation.once(Animation.EventType.FINISHED, () => {
|
||||
clearTimeout(timeout);
|
||||
console.log('怪物攻击动画完成,切换回站立状态');
|
||||
// 怪物攻击完成后切换回站立动画
|
||||
this.switchMonsterToStand(otherCollider.node.name, monsterAnimation);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.warn('未找到怪物动画组件,跳过怪物攻击动画');
|
||||
// 如果没有怪物动画组件,直接返回
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将怪物切换到站立动画
|
||||
*/
|
||||
private switchMonsterToStand(monsterName: string, monsterAnimation: Animation) {
|
||||
const standAnimName = `${monsterName}_stand`;
|
||||
const standAnimState = monsterAnimation.getState(standAnimName);
|
||||
|
||||
if (standAnimState) {
|
||||
monsterAnimation.play(standAnimName);
|
||||
console.log(`怪物切换到站立动画: ${standAnimName}`);
|
||||
} else {
|
||||
console.warn(`怪物站立动画 ${standAnimName} 不存在`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user