重构天赋系统配置,包括: 1. 调整天赋类型枚举和效果枚举 2. 移除旧的天赋配置数据 3. 简化天赋组件实现 4. 更新设计文档中的天赋描述 同时修正地图组件中的英雄位置坐标和缩放值
358 lines
13 KiB
TypeScript
358 lines
13 KiB
TypeScript
import { _decorator, Animation, AnimationClip, Component, instantiate, Label, Node, Prefab, resources, Sprite, SpriteFrame, v3, tween, Vec3, ProgressBar } from 'cc';
|
||
import { oops } from 'db://oops-framework/core/Oops';
|
||
import { getHeroList, getPreAttr, HeroConf, HeroInfo, HType, HTypeName } from '../common/config/heroSet';
|
||
import { smc } from '../common/SingletonModuleComp';
|
||
import { GameEvent } from '../common/config/GameEvent';
|
||
import { CCComp } from 'db://oops-framework/module/common/CCComp';
|
||
import { ecs } from 'db://oops-framework/libs/ecs/ECS';
|
||
const { ccclass, property } = _decorator;
|
||
|
||
@ccclass('HInfoComp')
|
||
@ecs.register('HInfoComp', false)
|
||
export class HInfoComp extends CCComp {
|
||
h_uuid:number=0
|
||
name_node:any=null
|
||
type_node:any=null
|
||
ap_node:any=null
|
||
hp_node:any=null
|
||
def_node:any=null
|
||
mp_node:any=null
|
||
map_node:any=null
|
||
mdef_node:any=null
|
||
// 重新定义节点映射,使名称更清晰
|
||
// 当前显示的英雄节点数组(7个位置)
|
||
heroNodes: (Node | null)[] = [null, null, null, null, null, null, null];
|
||
|
||
// 英雄位置定义
|
||
hero_pos:any={
|
||
0:v3(420,-30,0), // 不在屏幕内
|
||
1:v3(280,-30,0),
|
||
2:v3(160,-30,0),
|
||
3:v3(0,-40,0),
|
||
4:v3(-160,-30,0),
|
||
5:v3(-280,-30,0),
|
||
6:v3(-420,-30,0), // 不在屏幕内
|
||
}
|
||
|
||
// 动画锁定标志:防止快速点击导致的动画冲突
|
||
private isMoving: boolean = false;
|
||
// 保存待处理的setTimeout句柄,用于取消前一个异步操作
|
||
private moveTimeoutId: any = null;
|
||
protected onLoad(): void {
|
||
// this.on(GameEvent.MissionStart,this.mission_start,this)
|
||
}
|
||
// 位置索引常量
|
||
private static center_pos = 3;
|
||
|
||
/**
|
||
* 根据位置索引获取英雄缩放值
|
||
* @param posIndex 位置索引 (0-6)
|
||
* @returns Vec3 缩放向量
|
||
*/
|
||
private getHeroScale(posIndex: number): Vec3 {
|
||
switch(posIndex) {
|
||
case 2:
|
||
case 4:
|
||
return v3(-1.5, 1.5, 1); // 2、4位置:1.5倍缩放
|
||
case 3:
|
||
return v3(-1.8, 1.8, 1); // 3位置(中心):1.5倍缩放
|
||
default:
|
||
return v3(-1.5, 1.5, 1); // 其他位置:1.5倍缩放
|
||
}
|
||
}
|
||
|
||
start() {
|
||
this.name_node=this.node.getChildByName("hname").getChildByName("name")
|
||
this.type_node=this.node.getChildByName("hname").getChildByName("type")
|
||
this.ap_node=this.node.getChildByName("info").getChildByName("base").getChildByName("ap")
|
||
this.hp_node=this.node.getChildByName("info").getChildByName("base").getChildByName("hp")
|
||
this.def_node=this.node.getChildByName("info").getChildByName("base").getChildByName("def")
|
||
this.mdef_node=this.node.getChildByName("info").getChildByName("base").getChildByName("mdef")
|
||
this.map_node=this.node.getChildByName("info").getChildByName("base").getChildByName("map")
|
||
this.mp_node=this.node.getChildByName("info").getChildByName("base").getChildByName("mp")
|
||
this.h_uuid=smc.fight_hero
|
||
this.update_data(this.h_uuid)
|
||
this.load_all_hero(this.h_uuid)
|
||
}
|
||
update(deltaTime: number) {
|
||
|
||
}
|
||
update_data(uuid:number){
|
||
this.h_uuid=uuid
|
||
this.name_node.getComponent(Label).string=HeroInfo[uuid].name
|
||
this.type_node.getComponent(Label).string=HTypeName[HeroInfo[uuid].type]
|
||
this.ap_node.getChildByName("num").getComponent(Label).string=HeroInfo[uuid].ap.toString()
|
||
this.hp_node.getChildByName("num").getComponent(Label).string=HeroInfo[uuid].hp.toString()
|
||
this.def_node.getChildByName("num").getComponent(Label).string=HeroInfo[uuid].def.toString()
|
||
this.mdef_node.getChildByName("num").getComponent(Label).string=HeroInfo[uuid].mdef.toString()
|
||
this.map_node.getChildByName("num").getComponent(Label).string=HeroInfo[uuid].map.toString()
|
||
this.mp_node.getChildByName("num").getComponent(Label).string=HeroInfo[uuid].mp.toString()
|
||
let bar_num=getPreAttr(uuid)
|
||
this.ap_node.getChildByName("bar").getComponent(ProgressBar).progress=bar_num.ap
|
||
this.hp_node.getChildByName("bar").getComponent(ProgressBar).progress=bar_num.hp
|
||
this.def_node.getChildByName("bar").getComponent(ProgressBar).progress=bar_num.def
|
||
this.mdef_node.getChildByName("bar").getComponent(ProgressBar).progress=bar_num.mdef
|
||
this.map_node.getChildByName("bar").getComponent(ProgressBar).progress=bar_num.map
|
||
this.mp_node.getChildByName("bar").getComponent(ProgressBar).progress=bar_num.mp
|
||
}
|
||
load_all_hero(uuid:number){
|
||
// 清除之前的英雄节点
|
||
this.claear_hero();
|
||
|
||
// 获取英雄列表(优先显示拥有的英雄)
|
||
let heros = getHeroList();
|
||
let currentIndex = heros.indexOf(uuid);
|
||
|
||
// 载入7个英雄节点(当前英雄及前后各3个)
|
||
for(let i = 0; i < 7; i++) {
|
||
// 计算索引位置(考虑循环)
|
||
let indexOffset = i - 3; // -3, -2, -1, 0, 1, 2, 3
|
||
let heroIndex = currentIndex + indexOffset;
|
||
|
||
// 处理循环边界
|
||
if(heroIndex < 0) {
|
||
heroIndex = heros.length + heroIndex;
|
||
} else if(heroIndex >= heros.length) {
|
||
heroIndex = heroIndex - heros.length;
|
||
}
|
||
|
||
// 获取英雄UUID
|
||
let heroUuid = heros[heroIndex];
|
||
|
||
// 载入英雄预制体并设置位置
|
||
this.heroNodes[i] = this.load_hui(heroUuid, i);
|
||
|
||
// 添加初始缩放动画,根据位置设置不同的缩放值
|
||
if (this.heroNodes[i]) {
|
||
let targetScale = this.getHeroScale(i);
|
||
tween(this.heroNodes[i])
|
||
.to(0.2, { scale: targetScale })
|
||
.start();
|
||
}
|
||
}
|
||
this.show_lock()
|
||
}
|
||
load_hui(uuid:number, pos_index: number){
|
||
var path = "game/gui/hui";
|
||
var prefab: Prefab = oops.res.get(path, Prefab)!;
|
||
var node = instantiate(prefab);
|
||
// 将节点添加到父节点下
|
||
this.node.getChildByName("hero").addChild(node);
|
||
|
||
// 设置节点位置
|
||
node.setPosition(this.hero_pos[pos_index]);
|
||
// node.setSiblingIndex(0);
|
||
// 根据位置设置不同的缩放值
|
||
node.setScale(this.getHeroScale(pos_index));
|
||
// 加载并播放动画
|
||
let anm_path=HeroInfo[uuid].path;
|
||
resources.load("game/heros/hero/"+anm_path+"/idle", AnimationClip, (err, clip) => {
|
||
if (!err && clip) {
|
||
let animComponent = node.getComponent(Animation);
|
||
if(animComponent) {
|
||
animComponent.addClip(clip);
|
||
animComponent.play("idle");
|
||
}
|
||
} else {
|
||
console.error(`[HInfoComp]: Failed to load animation for hero ${uuid}`, err);
|
||
}
|
||
});
|
||
|
||
return node;
|
||
}
|
||
mission_start(){
|
||
this.claear_hero()
|
||
}
|
||
is_own(){
|
||
return smc.heros.includes(this.h_uuid)
|
||
}
|
||
show_lock(){
|
||
this.node.getChildByName("buy").active=!this.is_own()
|
||
this.node.getChildByName("lock").active=!this.is_own()
|
||
}
|
||
claear_hero(){
|
||
for (let i = 0; i < this.heroNodes.length; i++) {
|
||
if (this.heroNodes[i]) {
|
||
this.heroNodes[i].destroy();
|
||
this.heroNodes[i] = null;
|
||
}
|
||
}
|
||
}
|
||
|
||
next_hero(){
|
||
// 检查是否正在动画中,防止快速点击导致的冲突
|
||
if (this.isMoving) return;
|
||
|
||
// 获取英雄列表(优先显示拥有的英雄)
|
||
let heros = getHeroList();
|
||
let index = heros.indexOf(this.h_uuid);
|
||
index++;
|
||
if(index == heros.length) index = 0;
|
||
let nextHero = heros[index];
|
||
|
||
// 更新数据
|
||
this.h_uuid = nextHero;
|
||
smc.updateFihgtHero(nextHero)
|
||
this.update_data(nextHero);
|
||
// 执行平滑移动动画
|
||
this.moveHeroesRight();
|
||
this.show_lock()
|
||
}
|
||
|
||
prev_hero(){
|
||
// 检查是否正在动画中,防止快速点击导致的冲突
|
||
if (this.isMoving) return;
|
||
|
||
// 获取英雄列表(优先显示拥有的英雄)
|
||
let heros = getHeroList();
|
||
let index = heros.indexOf(this.h_uuid);
|
||
index--;
|
||
if(index == -1) index = heros.length - 1;
|
||
let prevHero = heros[index];
|
||
|
||
// 更新数据
|
||
this.h_uuid = prevHero;
|
||
smc.updateFihgtHero(prevHero)
|
||
this.update_data(prevHero);
|
||
// 执行平滑移动动画
|
||
this.moveHeroesLeft();
|
||
this.show_lock()
|
||
}
|
||
buy_hero(){
|
||
console.info("[HInfoComp]:buy_hero",this.h_uuid)
|
||
if(smc.vmdata.gold < HeroConf.COST) {
|
||
oops.gui.toast("金币不足")
|
||
return
|
||
}
|
||
smc.addHero(this.h_uuid)
|
||
this.load_all_hero(this.h_uuid)
|
||
this.show_lock()
|
||
}
|
||
start_mission() {
|
||
oops.message.dispatchEvent(GameEvent.MissionStart, {})
|
||
this.node.active=false;
|
||
}
|
||
moveHeroesLeft() {
|
||
// 取消前一个待处理的异步操作
|
||
if (this.moveTimeoutId !== null) {
|
||
clearTimeout(this.moveTimeoutId);
|
||
}
|
||
|
||
// 设置动画锁定
|
||
this.isMoving = true;
|
||
|
||
// 在动画开始前,直接销毁hero_pos[6]上的节点
|
||
if (this.heroNodes[6]) {
|
||
this.heroNodes[6].destroy();
|
||
this.heroNodes[6] = null;
|
||
}
|
||
|
||
// 移动所有现有节点向左(除了已销毁的heroNodes[6])
|
||
for (let i = 0; i < 6; i++) {
|
||
if (this.heroNodes[i]) {
|
||
// 计算目标位置:向左移动
|
||
let targetPos = this.hero_pos[i + 1];
|
||
|
||
// 使用Tween执行平滑移动和缩放动画
|
||
let targetScale = this.getHeroScale(i + 1);
|
||
|
||
tween(this.heroNodes[i])
|
||
.to(0.2, { position: targetPos, scale: targetScale })
|
||
.start();
|
||
}
|
||
}
|
||
|
||
// 延迟重排数组和创建新节点,等待动画完成
|
||
this.moveTimeoutId = setTimeout(() => {
|
||
// 移动数组元素(向后平移)
|
||
for (let i = 6; i > 0; i--) {
|
||
this.heroNodes[i] = this.heroNodes[i - 1];
|
||
}
|
||
|
||
// 创建新节点放在hero_pos[0]位置
|
||
let heros = getHeroList();
|
||
let currentIndex = heros.indexOf(this.h_uuid);
|
||
let newIndex = currentIndex - 3; // 新的最左侧英雄索引
|
||
|
||
// 处理循环边界
|
||
if (newIndex < 0) {
|
||
newIndex = heros.length + newIndex;
|
||
}
|
||
|
||
this.heroNodes[0] = this.load_hui(heros[newIndex], 0);
|
||
|
||
// 确保新创建的节点使用正确的缩放值
|
||
if (this.heroNodes[0]) {
|
||
this.heroNodes[0].setScale(this.getHeroScale(0));
|
||
}
|
||
|
||
// 动画完成,解除锁定
|
||
this.isMoving = false;
|
||
this.moveTimeoutId = null;
|
||
}, 200); // 与动画时间保持一致
|
||
}
|
||
|
||
moveHeroesRight() {
|
||
// 取消前一个待处理的异步操作
|
||
if (this.moveTimeoutId !== null) {
|
||
clearTimeout(this.moveTimeoutId);
|
||
}
|
||
|
||
// 设置动画锁定
|
||
this.isMoving = true;
|
||
|
||
// 在动画开始前,直接销毁hero_pos[0]上的节点
|
||
if (this.heroNodes[0]) {
|
||
this.heroNodes[0].destroy();
|
||
this.heroNodes[0] = null;
|
||
}
|
||
|
||
// 移动所有现有节点向右(除了已销毁的heroNodes[0])
|
||
for (let i = 1; i < this.heroNodes.length; i++) {
|
||
if (this.heroNodes[i]) {
|
||
// 计算目标位置:向右移动
|
||
let targetPos = this.hero_pos[i - 1];
|
||
|
||
// 使用Tween执行平滑移动和缩放动画
|
||
let targetScale = this.getHeroScale(i - 1);
|
||
|
||
tween(this.heroNodes[i])
|
||
.to(0.2, { position: targetPos, scale: targetScale })
|
||
.start();
|
||
}
|
||
}
|
||
|
||
// 延迟重排数组和创建新节点,等待动画完成
|
||
this.moveTimeoutId = setTimeout(() => {
|
||
// 移动数组元素(向前平移)
|
||
for (let i = 0; i < 6; i++) {
|
||
this.heroNodes[i] = this.heroNodes[i + 1];
|
||
}
|
||
|
||
// 创建新节点放在hero_pos[6]位置
|
||
let heros = getHeroList();
|
||
let currentIndex = heros.indexOf(this.h_uuid);
|
||
let newIndex = currentIndex + 3; // 新的最右侧英雄索引
|
||
|
||
// 处理循环边界
|
||
if (newIndex >= heros.length) {
|
||
newIndex = newIndex - heros.length;
|
||
}
|
||
|
||
this.heroNodes[6] = this.load_hui(heros[newIndex], 6);
|
||
|
||
// 确保新创建的节点使用正确的缩放值
|
||
if (this.heroNodes[6]) {
|
||
this.heroNodes[6].setScale(this.getHeroScale(6));
|
||
}
|
||
|
||
// 动画完成,解除锁定
|
||
this.isMoving = false;
|
||
this.moveTimeoutId = null;
|
||
}, 200); // 与动画时间保持一致
|
||
}
|
||
|
||
reset() {
|
||
this.node.destroy()
|
||
}
|
||
} |