|
@@ -1,10 +1,11 @@
|
|
|
-import { _decorator, Component, Node, ProgressBar, tween } from 'cc';
|
|
|
|
|
|
|
+import { _decorator, Component, Node, ProgressBar, tween } from 'cc';
|
|
|
const { ccclass, property } = _decorator;
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 血条动画组件
|
|
* 血条动画组件
|
|
|
* 使用两个重叠的血条实现黄色血皮滑动动画效果
|
|
* 使用两个重叠的血条实现黄色血皮滑动动画效果
|
|
|
* 红色血条显示当前血量,黄色血条用于滑动动画
|
|
* 红色血条显示当前血量,黄色血条用于滑动动画
|
|
|
|
|
+ * 血条默认隐藏,只在受伤时显示并播放动画
|
|
|
*/
|
|
*/
|
|
|
@ccclass('HPBarAnimation')
|
|
@ccclass('HPBarAnimation')
|
|
|
export class HPBarAnimation extends Component {
|
|
export class HPBarAnimation extends Component {
|
|
@@ -21,11 +22,18 @@ export class HPBarAnimation extends Component {
|
|
|
})
|
|
})
|
|
|
public yellowBarNode: Node = null;
|
|
public yellowBarNode: Node = null;
|
|
|
|
|
|
|
|
|
|
+ @property({
|
|
|
|
|
+ type: Node,
|
|
|
|
|
+ tooltip: 'HPBar根节点'
|
|
|
|
|
+ })
|
|
|
|
|
+ public hpBarRootNode: Node = null;
|
|
|
|
|
+
|
|
|
private redProgressBar: ProgressBar = null;
|
|
private redProgressBar: ProgressBar = null;
|
|
|
private yellowProgressBar: ProgressBar = null;
|
|
private yellowProgressBar: ProgressBar = null;
|
|
|
private currentProgress: number = 1.0;
|
|
private currentProgress: number = 1.0;
|
|
|
private targetProgress: number = 1.0;
|
|
private targetProgress: number = 1.0;
|
|
|
private currentTween: any = null; // 当前正在运行的动画
|
|
private currentTween: any = null; // 当前正在运行的动画
|
|
|
|
|
+ private hideTimer: any = null; // 隐藏血条的定时器
|
|
|
|
|
|
|
|
start() {
|
|
start() {
|
|
|
this.initializeComponents();
|
|
this.initializeComponents();
|
|
@@ -38,6 +46,11 @@ export class HPBarAnimation extends Component {
|
|
|
// 获取组件所属的敌人节点信息
|
|
// 获取组件所属的敌人节点信息
|
|
|
const enemyNode = this.node;
|
|
const enemyNode = this.node;
|
|
|
const enemyName = enemyNode ? enemyNode.name : 'Unknown';
|
|
const enemyName = enemyNode ? enemyNode.name : 'Unknown';
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有设置HPBar根节点,尝试自动查找
|
|
|
|
|
+ if (!this.hpBarRootNode) {
|
|
|
|
|
+ this.hpBarRootNode = this.node.getChildByName('HPBar');
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 获取红色血条组件
|
|
// 获取红色血条组件
|
|
|
if (this.redBarNode) {
|
|
if (this.redBarNode) {
|
|
@@ -64,6 +77,9 @@ export class HPBarAnimation extends Component {
|
|
|
} else {
|
|
} else {
|
|
|
console.error(`[HPBarAnimation] [${enemyName}] 黄色血条节点未设置!`);
|
|
console.error(`[HPBarAnimation] [${enemyName}] 黄色血条节点未设置!`);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 初始化时隐藏血条
|
|
|
|
|
+ this.hideHealthBar();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -98,11 +114,53 @@ export class HPBarAnimation extends Component {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 显示血条
|
|
|
|
|
+ */
|
|
|
|
|
+ public showHealthBar() {
|
|
|
|
|
+ if (this.hpBarRootNode && this.hpBarRootNode.isValid) {
|
|
|
|
|
+ this.hpBarRootNode.active = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 清除隐藏定时器
|
|
|
|
|
+ if (this.hideTimer) {
|
|
|
|
|
+ clearTimeout(this.hideTimer);
|
|
|
|
|
+ this.hideTimer = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 隐藏血条
|
|
|
|
|
+ */
|
|
|
|
|
+ public hideHealthBar() {
|
|
|
|
|
+ if (this.hpBarRootNode && this.hpBarRootNode.isValid) {
|
|
|
|
|
+ this.hpBarRootNode.active = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 延迟隐藏血条
|
|
|
|
|
+ * @param delay 延迟时间(秒)
|
|
|
|
|
+ */
|
|
|
|
|
+ private scheduleHideHealthBar(delay: number = 3.0) {
|
|
|
|
|
+ // 清除之前的定时器
|
|
|
|
|
+ if (this.hideTimer) {
|
|
|
|
|
+ clearTimeout(this.hideTimer);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置新的定时器
|
|
|
|
|
+ this.hideTimer = setTimeout(() => {
|
|
|
|
|
+ this.hideHealthBar();
|
|
|
|
|
+ this.hideTimer = null;
|
|
|
|
|
+ }, delay * 1000);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 更新血条进度并播放动画
|
|
* 更新血条进度并播放动画
|
|
|
* @param newProgress 新的血量百分比 (0-1)
|
|
* @param newProgress 新的血量百分比 (0-1)
|
|
|
|
|
+ * @param showBar 是否显示血条(默认为true)
|
|
|
*/
|
|
*/
|
|
|
- public updateProgress(newProgress: number) {
|
|
|
|
|
|
|
+ public updateProgress(newProgress: number, showBar: boolean = true) {
|
|
|
const enemyName = this.node ? this.node.name : 'Unknown';
|
|
const enemyName = this.node ? this.node.name : 'Unknown';
|
|
|
|
|
|
|
|
if (!this.redProgressBar || !this.yellowProgressBar) {
|
|
if (!this.redProgressBar || !this.yellowProgressBar) {
|
|
@@ -113,6 +171,11 @@ export class HPBarAnimation extends Component {
|
|
|
// 限制进度范围
|
|
// 限制进度范围
|
|
|
newProgress = Math.max(0, Math.min(1, newProgress));
|
|
newProgress = Math.max(0, Math.min(1, newProgress));
|
|
|
|
|
|
|
|
|
|
+ // 如果需要显示血条
|
|
|
|
|
+ if (showBar) {
|
|
|
|
|
+ this.showHealthBar();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 如果血量增加或没有变化,直接更新
|
|
// 如果血量增加或没有变化,直接更新
|
|
|
if (newProgress >= this.currentProgress) {
|
|
if (newProgress >= this.currentProgress) {
|
|
|
this.currentProgress = newProgress;
|
|
this.currentProgress = newProgress;
|
|
@@ -125,6 +188,13 @@ export class HPBarAnimation extends Component {
|
|
|
this.yellowProgressBar.progress = newProgress;
|
|
this.yellowProgressBar.progress = newProgress;
|
|
|
}
|
|
}
|
|
|
this.updateBarDisplay();
|
|
this.updateBarDisplay();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果血量满了,立即隐藏血条
|
|
|
|
|
+ if (newProgress >= 1.0) {
|
|
|
|
|
+ this.scheduleHideHealthBar(1.0); // 1秒后隐藏
|
|
|
|
|
+ } else if (showBar) {
|
|
|
|
|
+ this.scheduleHideHealthBar(3.0); // 3秒后隐藏
|
|
|
|
|
+ }
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -182,6 +252,11 @@ export class HPBarAnimation extends Component {
|
|
|
}
|
|
}
|
|
|
// 清除动画引用
|
|
// 清除动画引用
|
|
|
this.currentTween = null;
|
|
this.currentTween = null;
|
|
|
|
|
+
|
|
|
|
|
+ // 动画完成后延迟隐藏血条
|
|
|
|
|
+ if (newProgress > 0) {
|
|
|
|
|
+ this.scheduleHideHealthBar(3.0); // 3秒后隐藏血条
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
.start();
|
|
.start();
|
|
@@ -198,7 +273,27 @@ export class HPBarAnimation extends Component {
|
|
|
* 重置血条到满血状态
|
|
* 重置血条到满血状态
|
|
|
*/
|
|
*/
|
|
|
public resetToFull() {
|
|
public resetToFull() {
|
|
|
- this.updateProgress(1.0);
|
|
|
|
|
|
|
+ this.updateProgress(1.0, false); // 重置时不显示血条
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 重置血条到满血状态并隐藏
|
|
|
|
|
+ */
|
|
|
|
|
+ public resetToFullAndHide() {
|
|
|
|
|
+ this.currentProgress = 1.0;
|
|
|
|
|
+ this.targetProgress = 1.0;
|
|
|
|
|
+
|
|
|
|
|
+ // 同步更新两个血条到满血状态
|
|
|
|
|
+ if (this.redProgressBar && this.redProgressBar.isValid) {
|
|
|
|
|
+ this.redProgressBar.progress = 1.0;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.yellowProgressBar && this.yellowProgressBar.isValid) {
|
|
|
|
|
+ this.yellowProgressBar.progress = 1.0;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.updateBarDisplay();
|
|
|
|
|
+
|
|
|
|
|
+ // 立即隐藏血条
|
|
|
|
|
+ this.hideHealthBar();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
onDestroy() {
|
|
onDestroy() {
|
|
@@ -207,5 +302,11 @@ export class HPBarAnimation extends Component {
|
|
|
this.currentTween.stop();
|
|
this.currentTween.stop();
|
|
|
this.currentTween = null;
|
|
this.currentTween = null;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 清理隐藏血条的定时器,防止内存泄漏
|
|
|
|
|
+ if (this.hideTimer) {
|
|
|
|
|
+ clearTimeout(this.hideTimer);
|
|
|
|
|
+ this.hideTimer = null;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|