You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
10 KiB
250 lines
10 KiB
import { _decorator, Component, Label, Node, RichText, sp, Sprite, SpriteFrame, Tween, tween, Vec3, Button } from 'cc';
|
|
import { GBundle, GPath, UIID } from '../../game/ConfigRes';
|
|
import { SpriteLoad } from 'db://assets/mx/components/SpriteLoad';
|
|
import { GEvent } from 'db://assets/mx/module/event/GEvent';
|
|
import { BattleType } from '../../manager/ChapterDataManager';
|
|
import MTools from 'db://assets/mx/tools/MTools';
|
|
import { BattleResLoader } from '../../game/BattleResLoader';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('SkillSelectItem')
|
|
export class SkillSelectItem extends Component {
|
|
|
|
bgAnim: sp.Skeleton = null;
|
|
sicon: Sprite = null;
|
|
typeIcon: Sprite = null;
|
|
lbtag: Label = null;
|
|
lbname: Label = null;
|
|
rtdesc: RichText = null;
|
|
newItem: Node = null;
|
|
rtTNum: Label = null;
|
|
|
|
bg: Sprite = null;
|
|
sbg: Sprite = null;
|
|
wbg: Sprite = null;
|
|
bicon: Sprite = null;
|
|
wicon: Sprite = null;
|
|
|
|
protected onLoad(): void {
|
|
this.bgAnim = this.node.find("bgAnim").getComponent(sp.Skeleton);
|
|
this.sicon = this.node.find("sicon").getComponent(Sprite);
|
|
this.typeIcon = this.node.find("typeIcon").getComponent(Sprite);
|
|
this.lbtag = this.node.find("lbtag").getComponent(Label);
|
|
this.lbname = this.node.find("lbname").getComponent(Label);
|
|
this.rtdesc = this.node.find("rtdesc").getComponent(RichText);
|
|
this.newItem = this.node.find("newItem");
|
|
this.bg = this.node.find("bg").getComponent(Sprite);
|
|
this.sbg = this.node.find("sbg").getComponent(Sprite);
|
|
this.wbg = this.node.find("wbg").getComponent(Sprite);
|
|
this.bicon = this.node.find("bicon").getComponent(Sprite);
|
|
this.wicon = this.node.find("wicon").getComponent(Sprite);
|
|
this.rtTNum = this.node.find("rtTNum").getComponent(Label);
|
|
// 预制体 Button 为 SCALE(0.9),鼠标悬停会与 playFlipRefresh 缩放 tween 冲突导致 item 突然缩小
|
|
const btn = this.node.getComponent(Button);
|
|
if (btn) {
|
|
btn.transition = Button.Transition.NONE;
|
|
}
|
|
// 技能选项统一不吃历史缩放,基准始终为 1,1,1
|
|
this.ensureNormalizedBaseScale();
|
|
}
|
|
|
|
protected onEnable(): void {
|
|
this.node.on(Node.EventType.TOUCH_END, this.onClick, this);
|
|
}
|
|
|
|
protected onDisable(): void {
|
|
this.node.off(Node.EventType.TOUCH_END, this.onClick, this);
|
|
// 面板关闭/节点回收时,避免 tween 中断后残留到中间缩放
|
|
Tween.stopAllByTarget(this.node);
|
|
if (this.node?.isValid) {
|
|
this.node.setScale(this._baseScale.x, this._baseScale.y, this._baseScale.z);
|
|
}
|
|
}
|
|
|
|
Skill: ITableSkill = null;
|
|
Weapon: ITableWeapon2 = null;
|
|
|
|
/**动画品质皮肤 */
|
|
animSkin = ["绿", "蓝", "紫", "黄"];
|
|
|
|
private _baseScaleInited: boolean = false;
|
|
private _baseScale: Vec3 = new Vec3(1, 1, 1);
|
|
private readonly _normalizedScale: Vec3 = new Vec3(1, 1, 1);
|
|
|
|
private ensureNormalizedBaseScale(): void {
|
|
this._baseScale = this._normalizedScale.clone();
|
|
this._baseScaleInited = true;
|
|
if (this.node?.isValid) {
|
|
this.node.setScale(this._baseScale.x, this._baseScale.y, this._baseScale.z);
|
|
}
|
|
}
|
|
|
|
getBaseScale(): Vec3 {
|
|
if (!this._baseScaleInited) this.ensureNormalizedBaseScale();
|
|
return this._baseScale.clone();
|
|
}
|
|
|
|
resetScale(): void {
|
|
if (!this.node?.isValid) return;
|
|
if (!this._baseScaleInited) this.ensureNormalizedBaseScale();
|
|
Tween.stopAllByTarget(this.node);
|
|
this.node.setScale(this._baseScale.x, this._baseScale.y, this._baseScale.z);
|
|
}
|
|
|
|
private _isSkill: boolean = true;
|
|
private _quality: number = 0;
|
|
private _iconId: number | string = 0;
|
|
private _tag: string = "";
|
|
private _itemName: string = "";
|
|
private _desc: string = "";
|
|
private _new: boolean = false;
|
|
private _tetriType: number = 0;
|
|
/** 救救我鸭:对应 jiujiuwoyaWeaponCarriers 下标 */
|
|
private _carrierIndex = -1;
|
|
/** 三选一底部:相对当前面板的 DPS 变化(与主界面秒伤同源公式) */
|
|
private _dpsDelta: number = 0;
|
|
|
|
private playFlipRefresh() {
|
|
if (!this.node?.isValid) return;
|
|
// 复用节点/快速刷新时,确保以基准缩放开始/结束,避免残留到中间值
|
|
this.resetScale();
|
|
|
|
// tween 目标 Vec3 用 clone,避免对象被 tween 内部复用导致基准缩放被污染
|
|
const base = this._baseScale.clone();
|
|
const scale0 = new Vec3(0, base.y, base.z);
|
|
tween(this.node)
|
|
.to(0.3, { scale: scale0 })
|
|
.call(() => this.updateUI())
|
|
.to(0.3, { scale: base }, { easing: "smooth" })
|
|
.call(() => this.node?.isValid && this.node.setScale(this._baseScale.x, this._baseScale.y, this._baseScale.z))
|
|
.start();
|
|
}
|
|
|
|
setSkill(skill: ITableSkill) {
|
|
this.Skill = skill;
|
|
this._isSkill = true;
|
|
this.Weapon = null;
|
|
this._quality = skill.quality - 1;
|
|
this._iconId = skill.icon;
|
|
this._tag = gg.lang.get(skill.icon_desc);
|
|
this._itemName = skill.name;
|
|
this._desc = skill.desc;
|
|
this._new = false;
|
|
this._dpsDelta = gg.game.CurentBattle.getSkillSelectDpsDeltaForSkill(skill);
|
|
this.playFlipRefresh();
|
|
}
|
|
|
|
setWeapon(weapon: ITableWeapon2, tetriTypeOrCarrierIndex: number) {
|
|
this.Weapon = weapon;
|
|
let itemData = gg.data.table.getItemData(weapon.itemID)
|
|
this._isSkill = false;
|
|
this.Skill = null;
|
|
this._quality = weapon.quality - 1;
|
|
this._iconId = itemData.icon;
|
|
this._tag = "";
|
|
this._itemName = weapon.name;
|
|
this._desc = weapon.desc;
|
|
this._new = true;
|
|
const ya = gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya;
|
|
if (ya) {
|
|
this._carrierIndex = tetriTypeOrCarrierIndex;
|
|
const carriers = gg.game.CurentBattle.jiujiuwoyaWeaponCarriers ?? [];
|
|
this._tetriType = carriers[this._carrierIndex]?.getWeapontype() ?? 1;
|
|
} else {
|
|
this._carrierIndex = -1;
|
|
this._tetriType = tetriTypeOrCarrierIndex;
|
|
}
|
|
this._dpsDelta = gg.game.CurentBattle.getSkillSelectDpsDeltaForWeapon(weapon, this._tetriType);
|
|
this.playFlipRefresh();
|
|
}
|
|
|
|
updateUI() {
|
|
this.bgAnim.node.active = false;
|
|
this.sbg.node.active = false;
|
|
this.wbg.node.active = false;
|
|
this.bicon.node.active = false;
|
|
this.wicon.node.active = false;
|
|
this.sicon.node.active = false;
|
|
this.typeIcon.node.active = false;
|
|
this.bg.node.getOrAddComponent(SpriteLoad).setSprite(GPath.texture(`bg_${this._quality + 1}`), GBundle.SkillSelect);
|
|
if (this._quality >= 2) {
|
|
this.bgAnim.node.active = true;
|
|
this.bgAnim.setSkin(this.animSkin[this._quality]);
|
|
//this.bgAnim.setAnimation(0, "play", false);
|
|
//this.bgAnim.setCompleteListener(this.endAnim.bind(this));
|
|
}
|
|
if (this._isSkill) {
|
|
this.sbg.node.active = true;
|
|
this.sicon.node.active = true;
|
|
this.sbg.node.getOrAddComponent(SpriteLoad).setSprite(GPath.texture(`sb_${this._quality + 1}`), GBundle.SkillSelect);
|
|
this.sicon.getComponent(SpriteLoad).setSprite(GPath.SkillItem(this._iconId), GBundle.Items);
|
|
}
|
|
else {
|
|
this.wbg.node.active = true;
|
|
this.wicon.node.active = true;
|
|
this.bicon.node.active = true;
|
|
this.typeIcon.node.active = true;
|
|
this.wbg.node.getOrAddComponent(SpriteLoad).setSprite(GPath.texture(`wb_${this._quality + 1}`), GBundle.SkillSelect);
|
|
this.bicon.node.getOrAddComponent(SpriteLoad).setSprite(GPath.texture(`b_${this._tetriType}`), GBundle.SkillSelect);
|
|
this.wicon.getComponent(SpriteLoad).setSprite(GPath.Item(this._iconId), GBundle.Items);
|
|
this.typeIcon.getComponent(SpriteLoad).setSprite(GPath.WeaponType(`武器属性_${this.Weapon.type}`), GBundle.BattleGameWeapon);
|
|
}
|
|
this.lbtag.string = gg.lang.get(this._tag);
|
|
this.lbname.string = gg.lang.get(this._itemName);
|
|
this.rtdesc.string = gg.lang.get(this._desc);
|
|
this.newItem.active = this._new;
|
|
const d = this._dpsDelta;
|
|
//转为汉字
|
|
|
|
const signStr = (d >= 0 ? '+' : '-') + MTools.formatChineseUnit({ num: Math.abs(d) });;
|
|
|
|
this.rtTNum.string = gg.lang.get(`秒伤{1}`, [signStr]);
|
|
|
|
}
|
|
|
|
onClick() {
|
|
|
|
console.log("点击选择了技能或者武器");
|
|
if (this.Skill) {
|
|
gg.game.CurentBattle.addCurRogueSkillTimes();
|
|
gg.game.CurentBattle.addCurHaveSkillArr([this.Skill]);
|
|
//判断是抽卡副本
|
|
if (gg.game.CurentBattle.BattleType == BattleType.GachaMode) {
|
|
GEvent.Ins.emit(GEvent.AddSkillIcon, [this.Skill]);
|
|
}
|
|
|
|
} else if (this.Weapon) {
|
|
if (gg.game.CurentBattle.BattleType == BattleType.SpeedMode || gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Dan) {
|
|
//首次给武器无法选择
|
|
return
|
|
} else {
|
|
gg.game.CurentBattle.addCurRogueWeaponTimes();
|
|
if (gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya) {
|
|
gg.game.CurentBattle.changeJiujiuwoyaWeapon(this._carrierIndex, this.Weapon.weaponid);
|
|
} else {
|
|
gg.game.CurentBattle.changeTetriWeaponConfig(this._tetriType, this.Weapon.weaponid);
|
|
}
|
|
//判断是抽卡副本
|
|
if (gg.game.CurentBattle.BattleType == BattleType.GachaMode) {
|
|
GEvent.Ins.emit(GEvent.AddWeaponIcon, [this.Weapon.weaponid]);
|
|
}
|
|
// 选中后预热该武器子弹 + hitEffect 爆炸特效
|
|
void BattleResLoader.preloadWeaponCombatAssets(this.Weapon);
|
|
}
|
|
|
|
if (gg.game.CurentBattle.ChapterId == 1 && gg.game.CurentBattle.CurUseWeaponArr.length == 2) {
|
|
gg.sdk.reportDY("inLevel", `章节${gg.game.CurentBattle.getReportDYChapterId()}_${gg.game.CurentBattle.CurentWaveNum}-武器选择成功`)
|
|
}
|
|
}
|
|
gg.ui.closePanel(UIID.SkillSelect, 2);
|
|
}
|
|
|
|
endAnim() {
|
|
this.bgAnim.setAnimation(0, "idle", true);
|
|
this.bgAnim.setCompleteListener(null);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|