feat(map): 优化战斗流程与卡牌系统交互
1. 第一波准备阶段首个英雄召唤后自动开战,移除手动点击开始按钮 2. 重构卡牌交互逻辑,移除上划召唤改为点击召唤 3. 新增英雄卡池显隐切换功能 4. 调整卡牌预制体尺寸与布局 5. 移除特定波次技能卡弹窗逻辑 6. 简化引导流程,不再弹出Guide4
This commit is contained in:
@@ -58,14 +58,14 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 323
|
||||
"__id__": 327
|
||||
},
|
||||
{
|
||||
"__id__": 325
|
||||
"__id__": 329
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 327
|
||||
"__id__": 331
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -515,8 +515,8 @@
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 270
|
||||
"width": 170,
|
||||
"height": 230
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -766,8 +766,8 @@
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 270
|
||||
"width": 170,
|
||||
"height": 230
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -786,8 +786,8 @@
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 400,
|
||||
"height": 540
|
||||
"width": 340,
|
||||
"height": 460
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -806,8 +806,8 @@
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 392,
|
||||
"height": 528
|
||||
"width": 332,
|
||||
"height": 448
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -826,7 +826,7 @@
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 170,
|
||||
"width": 140,
|
||||
"height": 140
|
||||
}
|
||||
},
|
||||
@@ -846,7 +846,7 @@
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 340,
|
||||
"width": 280,
|
||||
"height": 280
|
||||
}
|
||||
},
|
||||
@@ -867,7 +867,7 @@
|
||||
"value": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 50,
|
||||
"y": 30,
|
||||
"z": 0
|
||||
}
|
||||
},
|
||||
@@ -1926,8 +1926,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 270
|
||||
"width": 170,
|
||||
"height": 230
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -2071,7 +2071,7 @@
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 50,
|
||||
"y": 30,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -2247,7 +2247,7 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 170,
|
||||
"width": 140,
|
||||
"height": 140
|
||||
},
|
||||
"_anchorPoint": {
|
||||
@@ -2413,8 +2413,8 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 79,
|
||||
"y": 114,
|
||||
"x": 64,
|
||||
"y": 94,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -3050,8 +3050,8 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -56.79599999999999,
|
||||
"y": -114.26499999999999,
|
||||
"x": -41.79599999999999,
|
||||
"y": -94.265,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -3708,8 +3708,8 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 55.925,
|
||||
"y": -114.26499999999999,
|
||||
"x": 40.925,
|
||||
"y": -94.265,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -4516,7 +4516,7 @@
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": -41.72399999999999,
|
||||
"y": -61.72399999999999,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -4723,8 +4723,8 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -79,
|
||||
"y": 114,
|
||||
"x": -64,
|
||||
"y": 94,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -5683,22 +5683,25 @@
|
||||
"__id__": 308
|
||||
},
|
||||
{
|
||||
"__id__": 314
|
||||
"__id__": 316
|
||||
}
|
||||
],
|
||||
"_active": false,
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 320
|
||||
"__id__": 322
|
||||
},
|
||||
{
|
||||
"__id__": 324
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 322
|
||||
"__id__": 326
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": -23.213,
|
||||
"y": -142.978,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -5740,10 +5743,13 @@
|
||||
},
|
||||
{
|
||||
"__id__": 311
|
||||
},
|
||||
{
|
||||
"__id__": 313
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 313
|
||||
"__id__": 315
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -5760,8 +5766,8 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0.8,
|
||||
"y": 0.8,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
@@ -5788,8 +5794,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 185,
|
||||
"height": 81
|
||||
"width": 340,
|
||||
"height": 100
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -5828,9 +5834,9 @@
|
||||
"__uuid__": "6165ffc9-a838-4a33-b569-bdbaaab0e6b4@b2501",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
"_type": 1,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_sizeMode": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
@@ -5847,6 +5853,42 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "08MkVcRXlJh64uV97FC5zt"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 308
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 314
|
||||
},
|
||||
"_alignFlags": 40,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 340,
|
||||
"_originalHeight": 0,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "e0NAQnwtdBJbK3eTqlXN1t"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -5872,14 +5914,14 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 315
|
||||
"__id__": 317
|
||||
},
|
||||
{
|
||||
"__id__": 317
|
||||
"__id__": 319
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 319
|
||||
"__id__": 321
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -5916,11 +5958,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 314
|
||||
"__id__": 316
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 316
|
||||
"__id__": 318
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -5944,11 +5986,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 314
|
||||
"__id__": 316
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 318
|
||||
"__id__": 320
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -6029,11 +6071,11 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 321
|
||||
"__id__": 323
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 148,
|
||||
"width": 170,
|
||||
"height": 64.8
|
||||
},
|
||||
"_anchorPoint": {
|
||||
@@ -6047,6 +6089,42 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "94GKNoSM1MwIqd0zy183DD"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 307
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 325
|
||||
},
|
||||
"_alignFlags": 40,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 170,
|
||||
"_originalHeight": 0,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "89gxeFO+ZD9q7ucM1+gj9B"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -6070,12 +6148,12 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 324
|
||||
"__id__": 328
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 270
|
||||
"width": 170,
|
||||
"height": 230
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -6098,7 +6176,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 326
|
||||
"__id__": 330
|
||||
},
|
||||
"Lock": null,
|
||||
"unLock": null,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,13 +3,13 @@
|
||||
* @description 单张卡牌槽位组件(UI 视图层)
|
||||
*
|
||||
* 职责:
|
||||
* 1. 管理单个卡牌槽位的 **显示** 和 **交互**(触摸拖拽 / 点击使用 / 锁定切换)。
|
||||
* 1. 管理单个卡牌槽位的 **显示** 和 **交互**(点击选中 / 召唤按钮 / 锁定切换)。
|
||||
* 2. 接收来自 MissionCardComp 分发的 CardConfig 数据,渲染对应卡面(英雄 / 技能 / 特殊卡)。
|
||||
* 3. 在玩家触发"使用卡牌"操作时,执行 **费用扣除 → 动画表现 → 效果分发** 的完整流程。
|
||||
*
|
||||
* 关键设计:
|
||||
* - 槽位可 **锁定**:锁定后刷新卡池不会覆盖旧卡,由 `isLocked` 控制。
|
||||
* - 卡牌使用支持 **上划手势** 与 **点击** 两种触发方式。
|
||||
* - 卡牌使用通过 **点击卡牌 → 显示召唤按钮 → 点击召唤按钮** 触发。
|
||||
* - 英雄卡图标使用 AnimationClip 动态加载 idle 动画;技能 / 特殊卡使用 SpriteAtlas 静态图标。
|
||||
* - 通过 `iconVisualToken` 防止异步加载资源回调与当前显示不一致(竞态保护)。
|
||||
*
|
||||
@@ -109,13 +109,7 @@ export class CardComp extends CCComp {
|
||||
private isLocked: boolean = false;
|
||||
/** 当前槽位承载的卡牌数据,null 表示空槽 */
|
||||
private cardData: CardConfig | null = null;
|
||||
/** 上划使用阈值(像素):拖拽距离 >= 此值视为"使用卡牌" */
|
||||
private readonly dragUseThreshold: number = 70;
|
||||
/** 触摸起始 Y 坐标,用于计算拖拽距离 */
|
||||
private touchStartY: number = 0;
|
||||
/** 触摸起始 X 坐标,用于点击判断 */
|
||||
private touchStartX: number = 0;
|
||||
/** 当前是否正在拖拽 */
|
||||
/** 当前是否正在触摸卡牌(用于阻止 setSlotPosition 等重置位置) */
|
||||
private isDragging: boolean = false;
|
||||
/** 当前是否正在执行"使用"流程(防止重复触发) */
|
||||
private isUsing: boolean = false;
|
||||
@@ -135,8 +129,6 @@ export class CardComp extends CCComp {
|
||||
* 防止快速切卡时旧回调错误覆盖新图标。
|
||||
*/
|
||||
private iconVisualToken: number = 0;
|
||||
/** 视为"点击"的最大位移阈值(像素),小于该值视为点击而非拖拽 */
|
||||
private readonly tapMoveThreshold: number = 10;
|
||||
|
||||
// ======================== 生命周期 ========================
|
||||
|
||||
@@ -491,60 +483,35 @@ export class CardComp extends CCComp {
|
||||
|
||||
// ======================== 触摸交互 ========================
|
||||
|
||||
/** 触摸开始:记录起点坐标,进入拖拽状态 */
|
||||
/**
|
||||
* 触摸开始:标记正在触摸。
|
||||
* 注:已移除上划手势召唤,卡牌不跟随手指移动,仅通过点击显示 call_btn 召唤。
|
||||
*/
|
||||
private onCardTouchStart(event: EventTouch) {
|
||||
if (!this.cardData || this.isUsing) return;
|
||||
this.touchStartY = event.getUILocation().y;
|
||||
this.touchStartX = event.getUILocation().x;
|
||||
this.isDragging = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 触摸移动:跟随手指向上偏移卡牌(仅允许向上拖拽,deltaY < 0 被 clamp 为 0)
|
||||
* 触摸移动:不做任何处理。
|
||||
* 卡牌不跟随手指位移,避免点击选中时产生位移。
|
||||
*/
|
||||
private onCardTouchMove(event: EventTouch) {
|
||||
if (!this.isDragging || !this.cardData || this.isUsing) return;
|
||||
const currentY = event.getUILocation().y;
|
||||
const deltaY = Math.max(0, currentY - this.touchStartY);
|
||||
this.node.setPosition(this.restPosition.x, this.restPosition.y + deltaY, this.restPosition.z);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 触摸结束:
|
||||
* - 上拉距离 >= dragUseThreshold → 视为"使用卡牌"
|
||||
* - 位移很小(点击)→ 触发 onCardTap:显示 call_btn / 打开信息面板 / 通知其他卡牌联动
|
||||
* 触摸结束:视为点击,触发 onCardTap(显示召唤按钮 / 打开信息面板 / 通知其他卡牌联动)。
|
||||
*/
|
||||
private onCardTouchEnd(event: EventTouch) {
|
||||
if (!this.isDragging || !this.cardData || this.isUsing) return;
|
||||
const endY = event.getUILocation().y;
|
||||
const endX = event.getUILocation().x;
|
||||
const deltaY = endY - this.touchStartY;
|
||||
const deltaX = endX - this.touchStartX;
|
||||
this.isDragging = false;
|
||||
|
||||
// 英雄卡保持上划使用
|
||||
if (deltaY >= this.dragUseThreshold) {
|
||||
const used = this.useCard();
|
||||
if (!used) {
|
||||
this.playReboundAnim();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 位移小于阈值视为"点击"
|
||||
if (Math.abs(deltaY) < this.tapMoveThreshold && Math.abs(deltaX) < this.tapMoveThreshold) {
|
||||
this.onCardTap();
|
||||
return;
|
||||
}
|
||||
|
||||
this.playReboundAnim();
|
||||
this.onCardTap();
|
||||
}
|
||||
|
||||
/** 触摸取消:回弹至原位 */
|
||||
/** 触摸取消:仅重置触摸状态 */
|
||||
private onCardTouchCancel() {
|
||||
if (!this.isDragging || this.isUsing) return;
|
||||
this.isDragging = false;
|
||||
this.playReboundAnim();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -552,9 +519,10 @@ export class CardComp extends CCComp {
|
||||
* 1. 显示本卡的召唤按钮 call_btn。
|
||||
* 2. 派发 CardSelected 事件,其他卡牌收到后隐藏各自的 call_btn。
|
||||
* 3. 英雄卡打开 HInfo 信息面板(点击查看,替代原长按)。
|
||||
* 注:不重置位置。applyCardUI 中 widget.updateAlignment() 会让节点脱离 restPosition,
|
||||
* 这里若强制 setPosition(restPosition) 会导致可见的跳位。
|
||||
*/
|
||||
private onCardTap() {
|
||||
this.playReboundAnim();
|
||||
this.showCallBtn();
|
||||
oops.message.dispatchEvent(GameEvent.CardSelected, this);
|
||||
// 英雄卡打开信息面板(点击替代长按)
|
||||
@@ -694,7 +662,8 @@ export class CardComp extends CCComp {
|
||||
// ---- 按卡牌类型渲染具体内容 ----
|
||||
const uiTrans = this.node.getComponent(UITransform);
|
||||
if (uiTrans) {
|
||||
uiTrans.setContentSize(170, 230);
|
||||
// 卡牌尺寸由编辑器场景节点决定,不再硬编码
|
||||
// uiTrans.setContentSize(170, 230);
|
||||
const widget = this.node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
@@ -702,14 +671,14 @@ export class CardComp extends CCComp {
|
||||
if (this.BG_node) {
|
||||
const bgTrans = this.BG_node.getComponent(UITransform);
|
||||
if (bgTrans) {
|
||||
bgTrans.setContentSize(170, 230);
|
||||
// bgTrans.setContentSize(170, 230);
|
||||
const widget = this.BG_node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
this.BG_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) {
|
||||
childTrans.setContentSize(170, 230);
|
||||
// childTrans.setContentSize(170, 230);
|
||||
const widget = child.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
@@ -720,7 +689,7 @@ export class CardComp extends CCComp {
|
||||
if (hbNode) {
|
||||
const hbTrans = hbNode.getComponent(UITransform);
|
||||
if (hbTrans) {
|
||||
hbTrans.setContentSize(170, 230);
|
||||
// hbTrans.setContentSize(170, 230);
|
||||
const widget = hbNode.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
@@ -832,12 +801,15 @@ export class CardComp extends CCComp {
|
||||
.start();
|
||||
}
|
||||
|
||||
/** 回弹动画:从当前位置平滑回到静止位并恢复缩放 */
|
||||
/**
|
||||
* 回弹动画:仅恢复缩放到 1,不改变位置。
|
||||
* Why: applyCardUI 中 widget.updateAlignment() 会让节点脱离 restPosition,
|
||||
* 若强行 setPosition(restPosition) 会产生肉眼可见的跳位(如金币不足时反馈)。
|
||||
*/
|
||||
private playReboundAnim() {
|
||||
Tween.stopAllByTarget(this.node);
|
||||
tween(this.node)
|
||||
.to(0.12, {
|
||||
position: new Vec3(this.restPosition.x, this.restPosition.y, this.restPosition.z),
|
||||
scale: new Vec3(1, 1, 1)
|
||||
})
|
||||
.start();
|
||||
@@ -845,14 +817,15 @@ export class CardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 使用消失动画:
|
||||
* - 节点向上移动 120px 并缩小至 0.8
|
||||
* - 节点从当前位置向上移动 120px(X 轴保持当前值不变,不使用 restPosition.x)
|
||||
* - 同时 UIOpacity 渐隐至 0
|
||||
* - 动画完成后调用 onComplete 回调
|
||||
*
|
||||
* @param onComplete 动画完成后的回调
|
||||
*/
|
||||
private playUseDisappearAnim(onComplete: () => void) {
|
||||
const targetPos = new Vec3(this.restPosition.x, this.restPosition.y + 120, this.restPosition.z);
|
||||
const current = this.node.position;
|
||||
const targetPos = new Vec3(current.x, current.y + 120, current.z);
|
||||
Tween.stopAllByTarget(this.node);
|
||||
if (this.opacityComp) {
|
||||
Tween.stopAllByTarget(this.opacityComp);
|
||||
@@ -863,8 +836,7 @@ export class CardComp extends CCComp {
|
||||
}
|
||||
tween(this.node)
|
||||
.to(0.18, {
|
||||
position: targetPos,
|
||||
scale: new Vec3(0.8, 0.8, 1)
|
||||
position: targetPos
|
||||
})
|
||||
.call(onComplete)
|
||||
.start();
|
||||
@@ -877,21 +849,21 @@ export class CardComp extends CCComp {
|
||||
private applyEmptyUI() {
|
||||
const uiTrans = this.node.getComponent(UITransform);
|
||||
if (uiTrans) {
|
||||
uiTrans.setContentSize(170, 230);
|
||||
// uiTrans.setContentSize(170, 230);
|
||||
const widget = this.node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
if (this.BG_node) {
|
||||
const bgTrans = this.BG_node.getComponent(UITransform);
|
||||
if (bgTrans) {
|
||||
bgTrans.setContentSize(170, 230);
|
||||
// bgTrans.setContentSize(170, 230);
|
||||
const widget = this.BG_node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
this.BG_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) {
|
||||
childTrans.setContentSize(170, 230);
|
||||
// childTrans.setContentSize(170, 230);
|
||||
const widget = child.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
@@ -901,7 +873,7 @@ export class CardComp extends CCComp {
|
||||
if (hbNode) {
|
||||
const hbTrans = hbNode.getComponent(UITransform);
|
||||
if (hbTrans) {
|
||||
hbTrans.setContentSize(170, 230);
|
||||
// hbTrans.setContentSize(170, 230);
|
||||
const widget = hbNode.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { HeroInfo, HType } from "../common/config/heroSet";
|
||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { FacSet, FightSet, SKILL_CARD_WAVES } from "../common/config/GameSet";
|
||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||
import { MissionEconomy } from "./MissionEconomy";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
|
||||
@@ -98,6 +98,10 @@ export class MissionCardComp extends CCComp {
|
||||
/** 抽卡(刷新)按钮节点 */
|
||||
@property(Node)
|
||||
cards_chou: Node = null!
|
||||
|
||||
/** 英雄卡牌池cards_node显示隐藏 */
|
||||
@property(Node)
|
||||
showHeros: Node = null!
|
||||
/** 卡池升级按钮节点(已废弃,保留节点引用防止 editor 报错) */
|
||||
@property(Node)
|
||||
cards_up: Node = null!
|
||||
@@ -147,7 +151,7 @@ export class MissionCardComp extends CCComp {
|
||||
/** 卡牌面板收起态缩放(scale=0 隐藏) */
|
||||
private cardsHideScale: Vec3 = new Vec3(0, 0, 1);
|
||||
/** 卡牌原始定位点 */
|
||||
private cardsPos = [-260, -75, 108, 260]
|
||||
private cardsPos = [-240, 0, 240]
|
||||
|
||||
// ======================== 生命周期 ========================
|
||||
|
||||
@@ -176,6 +180,9 @@ export class MissionCardComp extends CCComp {
|
||||
this.cards_chou.off(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
||||
this.cards_chou.off(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
||||
}
|
||||
if (this.showHeros && this.showHeros.isValid) {
|
||||
this.showHeros.off(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
|
||||
}
|
||||
this.unbindEvents();
|
||||
}
|
||||
|
||||
@@ -218,11 +225,6 @@ export class MissionCardComp extends CCComp {
|
||||
const cards = this.buildDrawCards();
|
||||
this.dispatchCardsToSlots(cards);
|
||||
|
||||
const wave = this.getCurrentWave();
|
||||
if (SKILL_CARD_WAVES.includes(wave)) {
|
||||
this.showSkillCardPopup();
|
||||
}
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "mission start");
|
||||
}
|
||||
|
||||
@@ -281,6 +283,9 @@ export class MissionCardComp extends CCComp {
|
||||
this.cards_chou?.on(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
||||
this.cards_chou?.on(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
||||
|
||||
/** 英雄卡池显示/隐藏切换按钮 */
|
||||
this.showHeros?.on(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
|
||||
|
||||
/** 技能卡刷新按钮 */
|
||||
this.skill_refresh?.on(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||
this.skill_refresh?.on(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
||||
@@ -369,11 +374,6 @@ export class MissionCardComp extends CCComp {
|
||||
this.layoutCardSlots();
|
||||
const cards = this.buildDrawCards();
|
||||
this.dispatchCardsToSlots(cards);
|
||||
|
||||
const wave = this.getCurrentWave();
|
||||
if (SKILL_CARD_WAVES.includes(wave)) {
|
||||
this.showSkillCardPopup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,6 +462,9 @@ export class MissionCardComp extends CCComp {
|
||||
this.cards_chou.off(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
||||
this.cards_chou.off(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
||||
}
|
||||
if (this.showHeros && this.showHeros.isValid) {
|
||||
this.showHeros.off(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
|
||||
}
|
||||
if (this.skill_refresh && this.skill_refresh.isValid) {
|
||||
this.skill_refresh.off(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||
this.skill_refresh.off(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
||||
@@ -490,15 +493,12 @@ export class MissionCardComp extends CCComp {
|
||||
const after = this.getAliveHeroCount();
|
||||
this.updateHeroNumUI(true, after > before);
|
||||
|
||||
// 第一次召唤英雄后,关闭guide3,打开guide4
|
||||
// 第一次召唤英雄后,关闭guide3
|
||||
// 注:首个英雄召唤后战斗自动开始(见 MissionComp),不再需要 Guide4 引导点击开始按钮
|
||||
if (!smc.finish_guides.includes(3)) {
|
||||
smc.finish_guides.push(3);
|
||||
oops.gui.remove(UIID.Guide3);
|
||||
}
|
||||
|
||||
if (!smc.finish_guides.includes(4)) {
|
||||
oops.gui.open(UIID.Guide4);
|
||||
}
|
||||
}
|
||||
|
||||
/** 英雄死亡事件回调:刷新面板列表并更新英雄数量 UI */
|
||||
@@ -582,6 +582,22 @@ export class MissionCardComp extends CCComp {
|
||||
this.playButtonResetAnim(this.cards_chou);
|
||||
}
|
||||
|
||||
/**
|
||||
* 英雄卡池显隐切换按钮回调:
|
||||
* - 切换 cards_node 的 active 状态。
|
||||
* - 显示时激活 showHeros 下的 "active" 子节点,隐藏时关闭该子节点。
|
||||
*/
|
||||
private onShowHerosClick() {
|
||||
if (!this.cards_node || !this.cards_node.isValid) return;
|
||||
oops.audio.playEffect("music/button");
|
||||
const visible = !this.cards_node.active;
|
||||
this.cards_node.active = visible;
|
||||
const activeChild = this.showHeros?.getChildByName("active");
|
||||
if (activeChild) {
|
||||
activeChild.active = visible;
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 技能抽卡按钮回调 ========================
|
||||
private onSkillDrawTouchStart() {
|
||||
this.playButtonPressAnim(this.skill_refresh);
|
||||
|
||||
@@ -186,6 +186,8 @@ export class MissionComp extends CCComp {
|
||||
this.on(GameEvent.NewWave, this.onNewWave, this)
|
||||
this.on(GameEvent.DO_AD_BACK, this.do_ad, this)
|
||||
this.start_btn?.on(NodeEventType.TOUCH_END, this.onStartFightBtnClick, this)
|
||||
// 第一波准备阶段,首个英雄召唤后自动开始战斗(无需玩家点击开始按钮)
|
||||
oops.message.on(GameEvent.MasterCalled, this.onHeroSummoned, this);
|
||||
this.removeMemoryPanel()
|
||||
}
|
||||
|
||||
@@ -207,6 +209,7 @@ export class MissionComp extends CCComp {
|
||||
if (this.start_btn && this.start_btn.isValid) {
|
||||
this.start_btn.off(NodeEventType.TOUCH_END, this.onStartFightBtnClick, this);
|
||||
}
|
||||
oops.message.off(GameEvent.MasterCalled, this.onHeroSummoned, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -699,6 +702,18 @@ export class MissionComp extends CCComp {
|
||||
this.to_fight();
|
||||
}
|
||||
|
||||
/**
|
||||
* 英雄召唤事件回调:
|
||||
* 第一波准备阶段(Prepare)只有第 1 波才会进入,
|
||||
* 此时首个英雄一旦召唤即自动开战,无需玩家点击开始按钮。
|
||||
* 后续波次走 PrepareStart 倒计时自动流转,不会进入 Prepare。
|
||||
*/
|
||||
private onHeroSummoned() {
|
||||
if (this.currentPhase !== MissionPhase.Prepare) return;
|
||||
if (!smc.mission.play || smc.mission.pause) return;
|
||||
this.to_fight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 打开结算弹窗:
|
||||
|
||||
Reference in New Issue
Block a user