feat(card): 添加长按放大功能并调整卡牌布局
- 在 CardComp 中实现长按触发卡牌放大,优化触摸交互逻辑 - 调整 MissionCardComp 中卡牌位置数组顺序,修复布局错位 - 修改 card.prefab 中多个 UI 元素的坐标和对齐方式,优化视觉呈现 - 移除卡牌种类标识的显示逻辑,简化卡牌 UI
This commit is contained in:
@@ -123,6 +123,12 @@ export class CardComp extends CCComp {
|
||||
private iconVisualToken: number = 0;
|
||||
/** 是否处于放大状态 */
|
||||
private isEnlarged: boolean = false;
|
||||
/** 长按定时器标记 */
|
||||
private longPressTimer: any = null;
|
||||
/** 是否触发了长按 */
|
||||
private isLongPressed: boolean = false;
|
||||
/** 长按触发时间(秒) */
|
||||
private readonly LONG_PRESS_DURATION: number = 0.5;
|
||||
|
||||
// ======================== 生命周期 ========================
|
||||
|
||||
@@ -502,6 +508,20 @@ export class CardComp extends CCComp {
|
||||
if (!this.cardData || this.isUsing) return;
|
||||
this.touchStartY = event.getUILocation().y;
|
||||
this.isDragging = true;
|
||||
this.isLongPressed = false;
|
||||
|
||||
// 开启长按定时器
|
||||
this.unschedule(this.onLongPress);
|
||||
this.scheduleOnce(this.onLongPress, this.LONG_PRESS_DURATION);
|
||||
}
|
||||
|
||||
/** 长按触发逻辑 */
|
||||
private onLongPress() {
|
||||
if (!this.isDragging || this.isUsing) return;
|
||||
this.isLongPressed = true;
|
||||
this.isEnlarged = true;
|
||||
this.applyCardUI();
|
||||
this.playReboundAnim();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -512,6 +532,15 @@ export class CardComp extends CCComp {
|
||||
const currentY = event.getUILocation().y;
|
||||
const deltaY = Math.max(0, currentY - this.touchStartY);
|
||||
|
||||
// 拖拽距离超过一定阈值,取消长按
|
||||
if (deltaY > 10) {
|
||||
this.unschedule(this.onLongPress);
|
||||
if (this.isLongPressed && !this.isEnlarged) {
|
||||
// 如果已经触发了长按但想取消放大(比如拖拽时恢复),视情况处理
|
||||
// 这里我们认为一旦拖动就取消未触发的长按,如果已经触发放大则保持放大直到松手
|
||||
}
|
||||
}
|
||||
|
||||
let baseX = this.restPosition.x;
|
||||
let baseY = this.restPosition.y;
|
||||
if (this.isEnlarged) {
|
||||
@@ -529,31 +558,45 @@ export class CardComp extends CCComp {
|
||||
/**
|
||||
* 触摸结束:
|
||||
* - 上拉距离 >= dragUseThreshold → 视为"使用卡牌"
|
||||
* - 否则视为"点击",切换放大缩小状态并回弹
|
||||
* - 否则视为"点击"或者"长按结束"
|
||||
*/
|
||||
private onCardTouchEnd(event: EventTouch) {
|
||||
this.unschedule(this.onLongPress);
|
||||
if (!this.isDragging || !this.cardData || this.isUsing) return;
|
||||
const endY = event.getUILocation().y;
|
||||
const deltaY = endY - this.touchStartY;
|
||||
this.isDragging = false;
|
||||
|
||||
if (deltaY >= this.dragUseThreshold) {
|
||||
this.useCard();
|
||||
// 使用卡牌后恢复非放大状态
|
||||
this.isEnlarged = false;
|
||||
this.isLongPressed = false;
|
||||
return;
|
||||
}
|
||||
this.toggleEnlarge();
|
||||
|
||||
// 无论是点击还是长按松手,都恢复正常大小
|
||||
if (this.isEnlarged) {
|
||||
this.isEnlarged = false;
|
||||
this.applyCardUI();
|
||||
}
|
||||
|
||||
this.isLongPressed = false;
|
||||
this.playReboundAnim();
|
||||
}
|
||||
|
||||
/** 切换卡牌的放大/缩小状态 */
|
||||
private toggleEnlarge() {
|
||||
this.isEnlarged = !this.isEnlarged;
|
||||
this.applyCardUI();
|
||||
}
|
||||
|
||||
/** 触摸取消:回弹至原位 */
|
||||
private onCardTouchCancel() {
|
||||
this.unschedule(this.onLongPress);
|
||||
if (!this.isDragging || this.isUsing) return;
|
||||
this.isDragging = false;
|
||||
|
||||
if (this.isEnlarged) {
|
||||
this.isEnlarged = false;
|
||||
this.applyCardUI();
|
||||
}
|
||||
|
||||
this.isLongPressed = false;
|
||||
this.playReboundAnim();
|
||||
}
|
||||
|
||||
@@ -619,12 +662,12 @@ export class CardComp extends CCComp {
|
||||
this.node.setPosition(targetX, targetY, this.restPosition.z);
|
||||
|
||||
// ---- 卡牌种类标识(近战 / 远程 / 辅助等) ----
|
||||
if (this.Ckind_node) {
|
||||
const kindName = CKind[this.cardData.kind];
|
||||
this.Ckind_node.children.forEach(child => {
|
||||
child.active = (child.name === kindName);
|
||||
});
|
||||
}
|
||||
// if (this.Ckind_node) {
|
||||
// const kindName = CKind[this.cardData.kind];
|
||||
// this.Ckind_node.children.forEach(child => {
|
||||
// child.active = (child.name === kindName);
|
||||
// });
|
||||
// }
|
||||
|
||||
// ---- 背景底框(按卡池等级显示对应子节点) ----
|
||||
const cardLvStr = `lv${this.cardData.pool_lv}`;
|
||||
@@ -653,6 +696,40 @@ export class CardComp extends CCComp {
|
||||
if (uiTrans) {
|
||||
uiTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
}
|
||||
|
||||
// 同时修改背景节点和边框节点的尺寸
|
||||
if (this.BG_node) {
|
||||
const bgTrans = this.BG_node.getComponent(UITransform);
|
||||
if (bgTrans) bgTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
this.BG_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) childTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.HF_node) {
|
||||
const hfTrans = this.HF_node.getComponent(UITransform);
|
||||
if (hfTrans) hfTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
this.HF_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) childTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.NF_node) {
|
||||
const nfTrans = this.NF_node.getComponent(UITransform);
|
||||
if (nfTrans) nfTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
this.NF_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) childTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
});
|
||||
}
|
||||
|
||||
const hbNode = this.node.getChildByName("HB");
|
||||
if (hbNode) {
|
||||
const hbTrans = hbNode.getComponent(UITransform);
|
||||
if (hbTrans) hbTrans.setContentSize(this.isEnlarged ? 230 : 170, this.isEnlarged ? 300 : 230);
|
||||
}
|
||||
|
||||
if(this.card_type===CardType.Hero){
|
||||
// 英雄卡:显示英雄名 + 星级 + AP/HP
|
||||
@@ -801,16 +878,45 @@ export class CardComp extends CCComp {
|
||||
if (uiTrans) {
|
||||
uiTrans.setContentSize(170, 230);
|
||||
}
|
||||
if (this.BG_node) {
|
||||
const bgTrans = this.BG_node.getComponent(UITransform);
|
||||
if (bgTrans) bgTrans.setContentSize(170, 230);
|
||||
this.BG_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) childTrans.setContentSize(170, 230);
|
||||
});
|
||||
}
|
||||
if (this.HF_node) {
|
||||
const hfTrans = this.HF_node.getComponent(UITransform);
|
||||
if (hfTrans) hfTrans.setContentSize(170, 230);
|
||||
this.HF_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) childTrans.setContentSize(170, 230);
|
||||
});
|
||||
}
|
||||
if (this.NF_node) {
|
||||
const nfTrans = this.NF_node.getComponent(UITransform);
|
||||
if (nfTrans) nfTrans.setContentSize(170, 230);
|
||||
this.NF_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) childTrans.setContentSize(170, 230);
|
||||
});
|
||||
}
|
||||
const hbNode = this.node.getChildByName("HB");
|
||||
if (hbNode) {
|
||||
const hbTrans = hbNode.getComponent(UITransform);
|
||||
if (hbTrans) hbTrans.setContentSize(170, 230);
|
||||
}
|
||||
this.iconVisualToken += 1;
|
||||
this.setLabel(this.name_node, "");
|
||||
this.setLabel(this.cost_node, "");
|
||||
if (this.info_node) this.info_node.active = false;
|
||||
if (this.oinfo_node) this.oinfo_node.active = false;
|
||||
if (this.Ckind_node) {
|
||||
this.Ckind_node.children.forEach(child => {
|
||||
child.active = false;
|
||||
});
|
||||
}
|
||||
// if (this.Ckind_node) {
|
||||
// this.Ckind_node.children.forEach(child => {
|
||||
// child.active = false;
|
||||
// });
|
||||
// }
|
||||
if (this.BG_node) {
|
||||
this.BG_node.children.forEach(child => child.active = false);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ export class MissionCardComp extends CCComp {
|
||||
/** 卡牌面板收起态缩放(scale=0 隐藏) */
|
||||
private cardsHideScale: Vec3 = new Vec3(0, 0, 1);
|
||||
/** 卡牌原始定位点 */
|
||||
private cardsPos = [-260,86,-86,260]
|
||||
private cardsPos = [-260,-86,86,260]
|
||||
/**
|
||||
* 英雄信息面板映射:EID → { node, model, comp }
|
||||
* 用于追踪每个出战英雄的面板实例和数据引用
|
||||
|
||||
Reference in New Issue
Block a user