181404010226 3 месяцев назад
Родитель
Сommit
2c154cd7c9

+ 83 - 0
assets/scripts/CombatSystem/BallController.ts

@@ -100,6 +100,9 @@ export class BallController extends Component {
     })
     public bulletContainerPrefab: Prefab = null;
 
+    // 正在被拖拽的方块集合
+    private draggingBlocks: Set<Node> = new Set();
+
     start() {
         // 如果没有指定placedBlocksContainer,尝试找到它
         if (!this.placedBlocksContainer) {
@@ -253,6 +256,12 @@ export class BallController extends Component {
         
         // 监听子弹发射检查事件
         eventBus.on(GameEvents.BALL_FIRE_BULLET, this.onBallFireBulletEvent, this);
+        
+        // 监听方块拖拽开始事件
+        eventBus.on(GameEvents.BLOCK_DRAG_START, this.onBlockDragStartEvent, this);
+        
+        // 监听方块拖拽结束事件
+        eventBus.on(GameEvents.BLOCK_DRAG_END, this.onBlockDragEndEvent, this);
     }
 
     /**
@@ -316,6 +325,38 @@ export class BallController extends Component {
         // 如果游戏未暂停,则继续执行子弹发射逻辑
         this.fireBulletAt(blockNode, fireWorldPos);
     }
+    
+    /**
+     * 处理方块拖拽开始事件
+     */
+    private onBlockDragStartEvent(data: { block: Node }) {
+        if (data && data.block) {
+            console.log('[BallController] 方块开始拖拽:', data.block.name, '路径:', this.getNodePath(data.block));
+            this.draggingBlocks.add(data.block);
+            console.log('[BallController] 当前拖拽方块数量:', this.draggingBlocks.size);
+        }
+    }
+    
+    /**
+     * 处理方块拖拽结束事件
+     */
+    private onBlockDragEndEvent(data: { block: Node }) {
+        if (data && data.block) {
+            console.log('[BallController] 方块结束拖拽:', data.block.name, '路径:', this.getNodePath(data.block));
+            const wasDeleted = this.draggingBlocks.delete(data.block);
+            console.log('[BallController] 删除成功:', wasDeleted, '当前拖拽方块数量:', this.draggingBlocks.size);
+        }
+    }
+    
+    /**
+     * 调试方法:显示当前拖拽的方块
+     */
+    private debugDraggingBlocks() {
+        console.log('[BallController] 当前拖拽方块列表:');
+        this.draggingBlocks.forEach((block, index) => {
+           // console.log(`  ${index + 1}. ${block.name} - 路径: ${this.getNodePath(block)} - 有效: ${block.isValid}`);
+        });
+    }
 
     // 计算游戏边界(使用GameArea节点)
     calculateGameBounds() {
@@ -778,6 +819,29 @@ export class BallController extends Component {
 
         // 如果是方块碰撞,检查防围困机制
         if (isBlock) {
+            // 检查方块是否正在被拖拽,如果是则忽略碰撞
+            // 需要检查碰撞节点本身或其父节点是否在拖拽列表中
+            let isDragging = false;
+            let currentNode = otherNode;
+            
+            // 向上遍历节点树,检查是否有父节点在拖拽列表中
+            while (currentNode && !isDragging) {
+                if (this.draggingBlocks.has(currentNode)) {
+                    isDragging = true;
+                    console.log('[BallController] 发现拖拽方块,忽略碰撞:', currentNode.name, '碰撞节点:', otherNode.name, '路径:', nodePath);
+                    break;
+                }
+                currentNode = currentNode.parent;
+            }
+            
+            if (isDragging) {
+                console.log('[BallController] 当前拖拽方块数量:', this.draggingBlocks.size);
+                if (contact) {
+                    contact.disabled = true;
+                }
+                return;
+            }
+            
             const ballId = ballNode.uuid;
             const currentTime = performance.now() / 1000; // 转换为秒
 
@@ -1276,6 +1340,8 @@ export class BallController extends Component {
         return path;
     }
 
+    private debugDragCounter = 0;
+    
     update(dt: number) {
         // 只有当小球已启动时才执行运动逻辑
         if (!this.ballStarted || !this.initialized) {
@@ -1292,6 +1358,14 @@ export class BallController extends Component {
         if (this.activeBall && this.activeBall.isValid) {
             this.debugCheckNearBlocks();
         }
+        
+        // 定期调试拖拽状态(每5秒一次)
+        this.debugDragCounter += dt;
+        if (this.debugDragCounter >= 5.0 && this.draggingBlocks.size > 0) {
+            console.log('[BallController] 定期调试 - 当前拖拽状态:');
+            this.debugDraggingBlocks();
+            this.debugDragCounter = 0;
+        }
     }
     
     /**
@@ -1590,6 +1664,9 @@ export class BallController extends Component {
         this.ballPhaseThrough.clear();
         this.ballDeflectionAttempts.clear();
         
+        // 清理拖拽方块集合
+        this.draggingBlocks.clear();
+        
         // 重置球速
         this.updateBallSpeed();
         
@@ -1638,6 +1715,12 @@ export class BallController extends Component {
         eventBus.off(GameEvents.GAME_PAUSE, this.onGamePauseEvent, this);
         eventBus.off(GameEvents.GAME_RESUME, this.onGameResumeEvent, this);
         eventBus.off(GameEvents.RESET_BALL_CONTROLLER, this.onResetBallControllerEvent, this);
+        eventBus.off(GameEvents.BALL_CREATE, this.onBallCreateEvent, this);
+        eventBus.off(GameEvents.BALL_START, this.onBallStartEvent, this);
+        eventBus.off(GameEvents.BALL_CREATE_ADDITIONAL, this.onBallCreateAdditionalEvent, this);
+        eventBus.off(GameEvents.BALL_FIRE_BULLET, this.onBallFireBulletEvent, this);
+        eventBus.off(GameEvents.BLOCK_DRAG_START, this.onBlockDragStartEvent, this);
+        eventBus.off(GameEvents.BLOCK_DRAG_END, this.onBlockDragEndEvent, this);
         
         // 清理物理事件监听器
         const physics = PhysicsManager.getInstance()?.getSystem();

+ 26 - 1
assets/scripts/CombatSystem/BlockSelection/GameBlockSelection.ts

@@ -590,6 +590,9 @@ export class GameBlockSelection extends Component {
             // 拖拽开始时禁用碰撞体
             const collider = block.getComponent(Collider2D);
             if (collider) collider.enabled = false;
+            
+            // 通知BallController有方块开始拖拽
+            EventBus.getInstance().emit(GameEvents.BLOCK_DRAG_START, { block: block });
         }, this);
         
         block.on(Node.EventType.TOUCH_MOVE, (event: EventTouch) => {
@@ -643,6 +646,9 @@ export class GameBlockSelection extends Component {
                 // 拖拽结束时恢复碰撞体
                 const collider = block.getComponent(Collider2D);
                 if (collider) collider.enabled = true;
+                
+                // 通知BallController方块拖拽结束
+                EventBus.getInstance().emit(GameEvents.BLOCK_DRAG_END, { block: block });
             }
         }, this);
         
@@ -658,7 +664,8 @@ export class GameBlockSelection extends Component {
                 const collider = block.getComponent(Collider2D);
                 if (collider) collider.enabled = true;
                 
-
+                // 通知BallController方块拖拽结束
+                EventBus.getInstance().emit(GameEvents.BLOCK_DRAG_END, { block: block });
             }
         }, this);
     }
@@ -697,7 +704,25 @@ export class GameBlockSelection extends Component {
             // 发生错误时,将方块返回原位置
             this.returnBlockToOriginalPosition();
             throw error; // 重新抛出错误,让上层处理
+        } finally {
+            // 无论成功还是失败,都要清理拖拽状态
+            if (this.currentDragBlock && this.currentDragBlock.isValid) {
+                // 重新启用碰撞器
+                const collider = this.currentDragBlock.getComponent(Collider2D);
+                if (collider) {
+                    collider.enabled = true;
+                    console.log('[GameBlockSelection] 拖拽结束,重新启用碰撞器:', this.currentDragBlock.name);
+                }
+                
+                // 发射拖拽结束事件
+                console.log('[GameBlockSelection] 发射 BLOCK_DRAG_END 事件:', this.currentDragBlock.name);
+                EventBus.getInstance().emit(GameEvents.BLOCK_DRAG_END, { block: this.currentDragBlock });
+            }
+            
+            // 清理拖拽状态
+            this.currentDragBlock = null;
         }
+        
         // 刷新方块占用情况
         this.refreshGridOccupation();
     }

+ 42 - 2
assets/scripts/CombatSystem/EnemyInstance.ts

@@ -516,8 +516,8 @@ export class EnemyInstance extends Component {
         // 播放攻击音效
         EnemyAudio.playAttackSound(this.enemyConfig);
         
-        // 对墙体造成伤害
-        this.controller.damageWall(this.attackPower);
+        // 播放攻击动画,动画结束后造成伤害
+        this.playAttackAnimationWithDamage();
     }
 
     // 播放行走动画
@@ -550,6 +550,46 @@ export class EnemyInstance extends Component {
         }
     }
 
+    // 播放攻击动画并在动画结束时造成伤害
+    private playAttackAnimationWithDamage() {
+        if (!this.skeleton) {
+            // 如果没有骨骼动画,直接造成伤害
+            this.dealDamageToWall();
+            return;
+        }
+        
+        const enemyComp = this.getComponent('EnemyComponent') as any;
+        const anims = enemyComp?.getAnimations ? enemyComp.getAnimations() : {};
+        const attackName = anims.attack ?? 'attack';
+
+        const animation = this.skeleton.findAnimation(attackName);
+        if (animation) {
+            // 播放攻击动画(不循环)
+            this.skeleton.setAnimation(0, attackName, false);
+            
+            // 获取动画时长并在动画结束时造成伤害
+            const animationDuration = animation.duration;
+            console.log(`[EnemyInstance] 攻击动画时长: ${animationDuration}秒`);
+            
+            // 使用定时器在动画结束时造成伤害
+            this.scheduleOnce(() => {
+                this.dealDamageToWall();
+                // 动画完成后切换回行走动画
+                this.playWalkAnimation();
+            }, animationDuration);
+        } else {
+            // 如果找不到攻击动画,直接造成伤害
+            this.dealDamageToWall();
+        }
+    }
+
+    // 对墙体造成伤害
+    private dealDamageToWall() {
+        if (this.controller) {
+            this.controller.damageWall(this.attackPower);
+        }
+    }
+
     private playDeathAnimationAndDestroy() {
         console.log(`[EnemyInstance] 开始播放死亡动画并销毁`);
         

+ 4 - 0
assets/scripts/Core/EventBus.ts

@@ -85,6 +85,10 @@ export enum GameEvents {
     BULLET_CREATE_REQUEST = 'BULLET_CREATE_REQUEST',
     BULLET_HIT_ENEMY = 'BULLET_HIT_ENEMY',
     
+    // 方块拖拽事件
+    BLOCK_DRAG_START = 'BLOCK_DRAG_START',
+    BLOCK_DRAG_END = 'BLOCK_DRAG_END',
+    
     // Toast提示事件
     SHOW_TOAST = 'SHOW_TOAST',
     HIDE_TOAST = 'HIDE_TOAST'