Cocos Creator 制作仿DNF血条优化版
前言
看本文章前建议先看上一篇《Cocos Creator 制作仿DNF血条》,这样就会明白优化的处理有哪些了。
上一章中,我们的血条它的逻辑是两条血条来回切换,包括颜色,宽度,层级,控制起来其实是非常不方便的, 逻辑也变得复杂了,而且没有考虑到秒杀的情况下血条的处理,所以这次根据同事提供的好主意我重新写了一版。
教程
原理
我们可以将第二条血条作为一个固定的底色来控制,只有当第二条血没有的时候,我们将其设置白色的,这样每次血条width控制其实都在第一条上面。
也就是说,血条的宽度控制其实一直是第一条在循环控制,扣完了马上切换成第二条的颜色,然后宽度设满,第二条的颜色变成第三条,直到没有血条了,第二条变成白色的就行了。
第二条血条宽度一直不变。
所以我们的层级结构就变得更加简单了。
三个子节点就完成了,一个bg底色,两个血条,two同时是血条,也是白色的底色。
代码
代码上就更加简单了,我想了下没必要拆分一个独立脚本来控制血条,直接给他们的父级节点boss_blood
挂载一个脚本即可。
import { _decorator, Component, Node, UITransform, Sprite, math } from "cc";
const { ccclass, property } = _decorator;
@ccclass("BossBlood")
export class BossBlood extends Component {
@property({ type: Node, displayName: "第一条血条" })
private one: Node;
@property({ type: Node, displayName: "第二条血条" })
private two: Node;
private maxWidth: number = 0;
private colors: Array<string> = ["#AB1A22", "#FA8600", "#92C702", "#007CC8"];
private activeColorIndex: number = 0;
private defaultColor: math.Color = math.color("#ffffff");
//计算
private total: number = 0; //总血条数
private rate: number = 1; //比例
private hp: number = 0; //总hp
private activeHp: number = 0; //当前hp
private activeIndex: number = 1; //当前第几条血条
onLoad() {
//获取ui和精灵组件
this.one["_mySprite"] = this.one.getComponent(Sprite);
this.one["_myUITransform"] = this.one.getComponent(UITransform);
this.two["_mySprite"] = this.two.getComponent(Sprite);
this.two["_myUITransform"] = this.two.getComponent(UITransform);
//获取血条宽度
this.maxWidth = this.one["_myUITransform"].width;
this.setBlood(2000, 500);
setInterval(() => {
this.buckleBlood(20);
}, 30);
}
/**
* @description: 设置血条
* @param {number} hp
* @param {number} max
* @Date: 2022-07-31 17:21:20
* @Author: mulingyuer
*/
public setBlood(hp: number, max: number) {
//重置血条
this.resetBlood();
//重置数据
this.total = Math.floor(hp / max);
this.rate = this.maxWidth / max;
this.hp = hp;
this.activeHp = hp;
this.activeColorIndex = 0;
//初次血条颜色
if (this.total === 1) {
this.one["_mySprite"].color = this.getNextColor();
this.one.active = true;
} else {
this.one["_mySprite"].color = this.getNextColor();
this.one.active = true;
this.two["_mySprite"].color = this.getNextColor();
this.two.active = true;
}
}
/**
* @description: 扣血
* @param {number} val
* @Date: 2022-07-31 17:35:28
* @Author: mulingyuer
*/
public buckleBlood(val: number): void {
if (this.activeHp <= 0) return;
//秒杀的情况
if (val >= this.activeHp) {
this.activeHp = 0;
this.activeColorIndex = this.total - 1;
this.activeIndex = this.total;
if (this.total === 1) {
this.one["_myUITransform"].width = 0;
} else {
this.two["_mySprite"].color = this.defaultColor;
this.one["_myUITransform"].width = 0;
this.one["_mySprite"].color = this.getNextColor();
}
return;
}
//指定血条扣除
let remainder: number = this.specBloodBuckle(this.one, val);
while (remainder > 0) {
//一条血不够扣
this.activeIndex += 1;
this.one["_mySprite"].color = this.two["_mySprite"].color;
this.one["_myUITransform"].width = this.maxWidth;
//第二条血颜色变成下一条的颜色或者没有了就变成默认色
if (this.activeIndex >= this.total) {
this.two["_mySprite"].color = this.defaultColor;
} else {
this.two["_mySprite"].color = this.getNextColor();
}
//继续扣第一条血
remainder = this.specBloodBuckle(this.one, remainder, true);
}
}
/** 指定血条扣血 */
private specBloodBuckle(blood: Node, val: number, isRemainder = false): number {
//扣除血量
if (!isRemainder) this.activeHp -= val;
if (this.activeHp < 0) this.activeHp = 0;
//控制血条
const activeWidth = blood["_myUITransform"].width;
const buckleVal = isRemainder ? val : val * this.rate;
const resultVal = activeWidth - buckleVal;
if (this.activeHp <= 0) {
//没血了
blood["_myUITransform"].width = 0;
return 0;
} else if (resultVal < 0) {
//一条血不够扣了
blood["_myUITransform"].width = 0;
return Math.abs(resultVal);
} else {
//正常扣血
blood["_myUITransform"].width = resultVal;
return 0;
}
}
/** 初始化血条 */
private resetBlood() {
const arr = [this.one, this.two];
arr.forEach((node) => {
node["_myUITransform"].width = this.maxWidth;
node["_mySprite"].color = this.defaultColor;
node.active = true;
});
}
/** 获取指定下标的血条颜色 */
private getNextColor(): math.Color {
if (this.activeColorIndex >= this.colors.length) {
this.activeColorIndex = 0;
}
return math.color(this.colors[this.activeColorIndex++]);
}
}
基本上就这样,当我们需要使用血条的时候,只需要通过boss_blood
节点,获取到它挂载的脚本BossBlood
组件,调用即可。
import { BossBlood } from "../blood/BossBlood";
const bossBloodScript = this.bossBlood.getComponent(BossBlood);
bossBloodScript.setBlood(2000, 500);
bossBloodScript.buckleBlood(50); //扣血操作
分类:
Cocos Creator
标签:
Cocos Creator血条dnf血条
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据