Files
pixelheros/assets/script/game/map/HInfoComp.ts
walkpan 2e24e1fc64 refactor(map): 优化英雄节点左右移动逻辑
- 调整moveHeroesLeft方法,动画开始前销毁第6个英雄节点,避免重复渲染
- 实现英雄节点向左平滑移动,使用Tween过渡动画
- 延迟重排英雄节点数组,确保动画完成后数组正确更新
- 调整moveHeroesRight方法,动画开始前销毁第0个英雄节点,避免重复渲染
- 实现英雄节点向右平滑移动,使用Tween过渡动画
- 延迟重排英雄节点数组,确保动画完成后数组正确更新
- 移除close方法中无用的节点移除逻辑,改用reset方法销毁节点
- 更新prefab中部分控件位置和尺寸,微调界面布局样式
2025-10-20 20:58:42 +08:00

235 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { _decorator, Animation, AnimationClip, Component, instantiate, Label, Node, Prefab, resources, Sprite, SpriteFrame, v3, tween, Vec3 } from 'cc';
import { oops } from 'db://oops-framework/core/Oops';
import { getHeroList, HeroInfo, HType, HTypeName } from '../common/config/heroSet';
import { smc } from '../common/SingletonModuleComp';
const { ccclass, property } = _decorator;
@ccclass('HInfoComp')
export class HInfoComp extends Component {
h_uuid:number=0
name_node:any=null
type_node:any=null
ap_node:any=null
hp_node:any=null
def_node:any=null
// 重新定义节点映射,使名称更清晰
// 当前显示的英雄节点数组7个位置
heroNodes: (Node | null)[] = [null, null, null, null, null, null, null];
// 英雄位置定义
hero_pos:any={
0:v3(420,-109,0), // 不在屏幕内
1:v3(280,-109,0),
2:v3(140,-109,0),
3:v3(0,-109,0),
4:v3(-140,-109,0),
5:v3(-280,-109,0),
6:v3(-420,-109,0), // 不在屏幕内
}
// 位置索引常量
private static center_pos = 3;
start() {
this.name_node=this.node.getChildByName("hero").getChildByName("hname").getChildByName("name")
this.type_node=this.node.getChildByName("hero").getChildByName("hname").getChildByName("type")
this.ap_node=this.node.getChildByName("info").getChildByName("base").getChildByName("ap").getChildByName("num")
this.hp_node=this.node.getChildByName("info").getChildByName("base").getChildByName("hp").getChildByName("num")
this.def_node=this.node.getChildByName("info").getChildByName("base").getChildByName("def").getChildByName("num")
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.getComponent(Label).string=HeroInfo[uuid].ap.toString()
this.hp_node.getComponent(Label).string=HeroInfo[uuid].hp.toString()
this.def_node.getComponent(Label).string=HeroInfo[uuid].def.toString()
}
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);
}
}
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]);
// 加载并播放动画
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;
}
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(){
// 获取英雄列表
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;
this.update_data(nextHero);
// 执行平滑移动动画
this.moveHeroesRight();
}
prev_hero(){
// 获取英雄列表
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;
this.update_data(prevHero);
// 执行平滑移动动画
this.moveHeroesLeft();
}
moveHeroesLeft() {
// 在动画开始前直接销毁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执行平滑移动
tween(this.heroNodes[i])
.to(0.3, { position: targetPos })
.start();
}
}
// 延迟重排数组和创建新节点,等待动画完成
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);
}, 300); // 与动画时间保持一致
}
moveHeroesRight() {
// 在动画开始前直接销毁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执行平滑移动
tween(this.heroNodes[i])
.to(0.3, { position: targetPos })
.start();
}
}
// 延迟重排数组和创建新节点,等待动画完成
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);
}, 300); // 与动画时间保持一致
}
reset() {
this.node.destroy()
}
}