黑神话共4条血条
白色血条:当前生命值
绿色血条:恢复生命后生命值
暗红血条:第一次伤害前血量
浅红血条:当前伤害距离上一次伤害的的血量
加血效果,先有一个绿色条显示血量会恢复到哪,间隔一小段时间后,白色血条缓动和绿色血量一样长。
1 当前血量50
2 喝药恢复到100,则绿色血条立即100,白色血条仍旧50
3 间隔1s后,白色血条缓动到100。

白色血量直接显示伤害后血量,暗红血条显示第一次伤害前血量位置,浅红血条显示连击的每次伤害血量位置。
每次连击,浅红血条都会显示该次攻击的伤害量。
间隔一小段时间,浅红血条和白色血条一样长,无连击一小段时间后,暗红血条缓动到和白色血条一样长。
1 当前血量100,第一次伤害10,白色血条90,暗红血条100,浅红血条100
2 第二次伤害10,白色血条80,暗红血条100,浅红血条90
3 第三次伤害10,白色血条70,暗红血条100,浅红血条80
4 无伤害0.5s,浅红血条消失
5 无伤害1s,暗红血条缓动到白色血条一样长

伤害时喝药,暗红和浅红血条都消失,走绿色血条逻辑。
喝药时受伤害,绿色血条消失,白色血条直接显示当当前生命位置,走暗红和浅色血条逻辑。
HpProgress.ts:
import { _decorator, Component, Node, Tween, tween, UITransform, v3 } from 'cc';
const { ccclass, property } = _decorator;
/**
 * 血条
 */
@ccclass('HpProgress')
export class HpProgress extends Component {
    @property({ type: Node, tooltip: "暗红" })
    bigRed: Node = null;
    @property({ type: Node, tooltip: "浅红" })
    smallRed: Node = null;
    @property({ type: Node, tooltip: "绿色" })
    green: Node = null;
    @property({ type: Node, tooltip: "白色" })
    write: Node = null;
    /**当前进度 */
    private rate: number = 1;
    /**是否连击中。产生伤害时,连击开始=true。当喝血或者暗红色血条消失时,连击结束=false */
    private keepHit: boolean = false;
    /**白色血条、绿色血条、暗红血条持续时间 */
    private time1: number = 2;
    /**持续时间结束后,白色血条或暗红血条tween缓动时间 */
    private time2: number = 0.5;
    /**浅红血条持续时间 */
    private time3: number = 1;
    /**持续时间结束后,浅红血条tween缓动时间 */
    private time4: number = 0.2;
    /**减血时白色血条、加血时绿色血条变化tween时间 */
    private time5: number = 0.1;
    /**血条原始宽度 */
    private oriWidth: number;
    protected onLoad(): void {
        this.oriWidth = this.bigRed.getComponent(UITransform).width;
    }
    /**设置血条原始长度 */
    public setOriWidth(oriWidth: number) {
        this.oriWidth = oriWidth;
    }
    /**
     * 设置时间
     * @param time1 
     * @param time2 
     * @param time3 
     */
    public setTime(time1: number, time2: number, time3: number) {
        this.time1 = time1;
        this.time2 = time2;
        this.time3 = time3;
    }
    /**
     * 设置血条进度
     * @param rate     进度 [0,1]
     * @param bTween   是否有缓动动画,true直接设置,false缓动动画
     */
    public setHpPro(rate: number, bTween: boolean) {
        rate = Math.max(0, rate);
        rate = Math.min(1, rate);
        //无动画
        if (bTween == false) {
            //停止所有计时器
            this.stopWriteTimer();
            this.stopBigRedTimer();
            this.stopSamllRedTimer();
            this.stopGreenTween();
            //血条直接设置到当前血量位置
            this.bigRed.getComponent(UITransform).width = this.oriWidth * rate;
            this.smallRed.getComponent(UITransform).width = this.oriWidth * rate;
            this.green.getComponent(UITransform).width = this.oriWidth * rate;
            this.write.getComponent(UITransform).width = this.oriWidth * rate;
            this.rate = rate;
            return;
        }
        //减血,有动画
        if (rate < this.rate) {
            //停止绿色、白色血条计时器
            this.stopWriteTimer();
            this.stopGreenTween();
            //白色血条缓动到血量位置
            tween(this.write.getComponent(UITransform)).to(this.time5, { width: this.oriWidth * rate }).start();
            //绿色血条直接设置到血量
            this.green.getComponent(UITransform).width = this.oriWidth * rate;
            //非连击,即第一次伤害,暗红和浅红血条保持在第一次伤害前血量位置
            if (this.keepHit == false) {
                this.bigRed.getComponent(UITransform).width = this.oriWidth * this.rate;
                this.smallRed.getComponent(UITransform).width = this.oriWidth * this.rate;
                //连击
                this.keepHit = true;
                //连击,暗红血条不动,浅红血条设置在上一次伤害时血量
            } else {
                this.smallRed.getComponent(UITransform).width = this.oriWidth * this.rate;
            }
            //保存进度
            this.rate = rate;
            //启动浅红血条计时器
            this.stopSamllRedTimer();
            this.startSmallRedTimer();
            //启动暗红血条计时器
            this.stopBigRedTimer();
            this.startBigRedTimer();
            //加血,有动画
        } else if (rate > this.rate) {
            //连击停止
            this.keepHit = false;
            //停止绿色、暗红、浅红血条计时器
            this.stopSamllRedTimer();
            this.stopBigRedTimer();
            this.stopGreenTween();
            //绿色血条缓动到血量位置
            tween(this.green.getComponent(UITransform)).to(this.time5, { width: this.oriWidth * rate }).start();
            //白色血条不动
            //暗红血条、浅色血条设置到白色血条位置
            this.bigRed.getComponent(UITransform).width = this.write.getComponent(UITransform).width;
            this.smallRed.getComponent(UITransform).width = this.write.getComponent(UITransform).width;
            //保存进度
            this.rate = rate;
            //启动白色血条计时器
            this.stopWriteTimer();
            this.startWriteTimer();
        }
    }
    /**启动浅红血条计时器 */
    private startSmallRedTimer() {
        this.scheduleOnce(this.onSmallRedTimer, this.time3);
    }
    /**浅红血条缓动到到白色血条位置 */
    private onSmallRedTimer() {
        tween(this.smallRed.getComponent(UITransform)).to(this.time4, { width: this.write.getComponent(UITransform).width }).start();
    }
    /**停止浅红血条计时器 */
    private stopSamllRedTimer() {
        this.unschedule(this.onSmallRedTimer);
        Tween.stopAllByTarget(this.smallRed.getComponent(UITransform));
    }
    /**启动暗红血条计时器 */
    private startBigRedTimer() {
        this.scheduleOnce(this.onBigRedTimer, this.time1);
    }
    /**暗红血条间隔时间到,开始缓动到白色血条位置 */
    private onBigRedTimer() {
        Tween.stopAllByTarget(this.bigRed.getComponent(UITransform));
        tween(this.bigRed.getComponent(UITransform)).to(this.time2, { width: this.write.getComponent(UITransform).width }).call(() => {
            //连击停止
            this.keepHit = false;
        }).start();
    }
    /**停止暗红血条计时器 */
    private stopBigRedTimer() {
        this.unschedule(this.onBigRedTimer);
        Tween.stopAllByTarget(this.bigRed.getComponent(UITransform));
    }
    /**启动白色血条计时器 */
    private startWriteTimer() {
        this.scheduleOnce(this.onWriteTimer, this.time1);
    }
    /**白色血条间隔时间到,开始缓动到绿色血条位置 */
    private onWriteTimer() {
        Tween.stopAllByTarget(this.write.getComponent(UITransform));
        tween(this.write.getComponent(UITransform)).to(this.time2, { width: this.green.getComponent(UITransform).width }).start();
    }
    /**停止白色血条计时器 */
    private stopWriteTimer() {
        this.unschedule(this.onWriteTimer);
        Tween.stopAllByTarget(this.write.getComponent(UITransform));
    }
    /**停止绿色血条tween */
    private stopGreenTween() {
        Tween.stopAllByTarget(this.green.getComponent(UITransform));
    }
}
场景中有如下节点,hpProgress上绑定HpProgress.ts组件

HpProgressDemo.ts:
import { _decorator, Component, Node } from 'cc';
import { HpProgress } from '../../src/framework/component/HpProgress';
const { ccclass, property } = _decorator;
@ccclass('HpProgressDemo')
export class HpProgressDemo extends Component {
    @property({ type: HpProgress, tooltip: "血条" })
    hpProgress: HpProgress = null;
    @property({ type: Node, tooltip: "加血" })
    addBtn: Node = null;
    @property({ type: Node, tooltip: "减血" })
    reduceBtn: Node = null;
    @property({ type: Node, tooltip: "直接设置" })
    setBtn: Node = null;
    private cur: number = 1000;    //当前血量
    private total: number = 1000;  //总血量
    protected onLoad(): void {
        this.addBtn.on(Node.EventType.TOUCH_END, this.onAddBtn, this);
        this.reduceBtn.on(Node.EventType.TOUCH_END, this.onReduceBtn, this);
        this.setBtn.on(Node.EventType.TOUCH_END, this.onSetBtn, this);
    }
    private onAddBtn() {
        let rand: number = Math.round(Math.random() * 100) + 10;
        this.cur = Math.min(this.total, this.cur + rand);
        console.log("加血:", rand);
        this.hpProgress.setHpPro(this.cur / this.total, true);
    }
    private onReduceBtn() {
        let rand: number = Math.round(Math.random() * 100) + 10;
        this.cur = Math.max(0, this.cur - rand);
        console.log("减血:", rand);
        this.hpProgress.setHpPro(this.cur / this.total, true);
    }
    private onSetBtn() {
        this.cur = this.total / 2;
        this.hpProgress.setHpPro(this.cur / this.total, false);
    }
}
演示效果:

                    
                
                
            
        
浙公网安备 33010602011771号