181404010226 před 5 měsíci
rodič
revize
9d3264568f

+ 27 - 13
assets/Scenes/GameLevel.scene

@@ -23,7 +23,7 @@
     "_active": true,
     "_components": [],
     "_prefab": {
-      "__id__": 664
+      "__id__": 665
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -54,7 +54,7 @@
     },
     "autoReleaseAssets": false,
     "_globals": {
-      "__id__": 665
+      "__id__": 666
     },
     "_id": "29694223-a59c-44b3-acb0-80ab92d103f5"
   },
@@ -111,6 +111,9 @@
       },
       {
         "__id__": 663
+      },
+      {
+        "__id__": 664
       }
     ],
     "_prefab": null,
@@ -15456,11 +15459,9 @@
       "__uuid__": "bf1d1e67-5bab-4c32-b912-5fadfb93974a",
       "__expectedType__": "cc.Prefab"
     },
-    "speed": 10,
+    "speed": 5,
     "bulletCooldown": 0.5,
     "maxReflectionRandomness": 0.2,
-    "unstuckForce": 10,
-    "stuckDetectionTime": 0.5,
     "bulletPrefab": {
       "__uuid__": "669f3dcb-acf3-4e72-9593-f6528554cfba",
       "__expectedType__": "cc.Prefab"
@@ -25031,6 +25032,19 @@
     "_target": null,
     "_id": "c9OYM4mrlLk5x/KMLBVvJh"
   },
+  {
+    "__type__": "1f833agYh5DP5bIUFUgT9Nu",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "debugDraw": true,
+    "_id": "ffMig9DF9DQLd2SVeZA893"
+  },
   {
     "__type__": "cc.PrefabInfo",
     "root": null,
@@ -25047,28 +25061,28 @@
   {
     "__type__": "cc.SceneGlobals",
     "ambient": {
-      "__id__": 666
+      "__id__": 667
     },
     "shadows": {
-      "__id__": 667
+      "__id__": 668
     },
     "_skybox": {
-      "__id__": 668
+      "__id__": 669
     },
     "fog": {
-      "__id__": 669
+      "__id__": 670
     },
     "octree": {
-      "__id__": 670
+      "__id__": 671
     },
     "skin": {
-      "__id__": 671
+      "__id__": 672
     },
     "lightProbeInfo": {
-      "__id__": 672
+      "__id__": 673
     },
     "postSettings": {
-      "__id__": 673
+      "__id__": 674
     },
     "bakedWithStationaryMainLight": false,
     "bakedWithHighpLightmap": false

+ 2 - 2
assets/assets/Prefabs/Ball.prefab

@@ -188,8 +188,8 @@
     "_group": 2,
     "_density": 1,
     "_sensor": false,
-    "_friction": 0.8,
-    "_restitution": 0,
+    "_friction": 0,
+    "_restitution": 1,
     "_offset": {
       "__type__": "cc.Vec2",
       "x": 0,

+ 1 - 1
assets/assets/Prefabs/Block001.prefab

@@ -476,7 +476,7 @@
     "tag": 2,
     "_group": 4,
     "_density": 1,
-    "_sensor": false,
+    "_sensor": true,
     "_friction": 0.2,
     "_restitution": 1,
     "_offset": {

+ 22 - 96
assets/assets/Prefabs/Block002.prefab

@@ -25,20 +25,20 @@
     "_active": true,
     "_components": [
       {
-        "__id__": 20
+        "__id__": 16
       },
       {
-        "__id__": 22
+        "__id__": 18
       },
       {
-        "__id__": 24
+        "__id__": 20
       },
       {
-        "__id__": 26
+        "__id__": 22
       }
     ],
     "_prefab": {
-      "__id__": 28
+      "__id__": 24
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -82,20 +82,17 @@
         "__id__": 3
       },
       {
-        "__id__": 9
+        "__id__": 7
       }
     ],
     "_active": true,
     "_components": [
       {
-        "__id__": 15
-      },
-      {
-        "__id__": 17
+        "__id__": 13
       }
     ],
     "_prefab": {
-      "__id__": 19
+      "__id__": 15
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -139,13 +136,10 @@
     "_components": [
       {
         "__id__": 4
-      },
-      {
-        "__id__": 6
       }
     ],
     "_prefab": {
-      "__id__": 8
+      "__id__": 6
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -204,40 +198,6 @@
     "__type__": "cc.CompPrefabInfo",
     "fileId": "6e1GlzlT5LTJf8+0vsixcR"
   },
-  {
-    "__type__": "cc.BoxCollider2D",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 3
-    },
-    "_enabled": true,
-    "__prefab": {
-      "__id__": 7
-    },
-    "tag": 0,
-    "_group": 1,
-    "_density": 1,
-    "_sensor": true,
-    "_friction": 0.2,
-    "_restitution": 0,
-    "_offset": {
-      "__type__": "cc.Vec2",
-      "x": 0,
-      "y": 0
-    },
-    "_size": {
-      "__type__": "cc.Size",
-      "width": 48,
-      "height": 48
-    },
-    "_id": ""
-  },
-  {
-    "__type__": "cc.CompPrefabInfo",
-    "fileId": "d2xsxbGgVLso9qGjSfBNRp"
-  },
   {
     "__type__": "cc.PrefabInfo",
     "root": {
@@ -263,14 +223,14 @@
     "_active": true,
     "_components": [
       {
-        "__id__": 10
+        "__id__": 8
       },
       {
-        "__id__": 12
+        "__id__": 10
       }
     ],
     "_prefab": {
-      "__id__": 14
+      "__id__": 12
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -307,11 +267,11 @@
     "_objFlags": 0,
     "__editorExtras__": {},
     "node": {
-      "__id__": 9
+      "__id__": 7
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 11
+      "__id__": 9
     },
     "_contentSize": {
       "__type__": "cc.Size",
@@ -335,11 +295,11 @@
     "_objFlags": 0,
     "__editorExtras__": {},
     "node": {
-      "__id__": 9
+      "__id__": 7
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 13
+      "__id__": 11
     },
     "_customMaterial": null,
     "_srcBlendFactor": 2,
@@ -397,7 +357,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 16
+      "__id__": 14
     },
     "_contentSize": {
       "__type__": "cc.Size",
@@ -415,40 +375,6 @@
     "__type__": "cc.CompPrefabInfo",
     "fileId": "80/nTAX/xJ67YUaPPgfJdM"
   },
-  {
-    "__type__": "cc.BoxCollider2D",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 2
-    },
-    "_enabled": true,
-    "__prefab": {
-      "__id__": 18
-    },
-    "tag": 0,
-    "_group": 1,
-    "_density": 1,
-    "_sensor": true,
-    "_friction": 0.2,
-    "_restitution": 0,
-    "_offset": {
-      "__type__": "cc.Vec2",
-      "x": 0,
-      "y": 0
-    },
-    "_size": {
-      "__type__": "cc.Size",
-      "width": 48,
-      "height": 48
-    },
-    "_id": ""
-  },
-  {
-    "__type__": "cc.CompPrefabInfo",
-    "fileId": "5dX6lJeqNF27gfZQrzbXN1"
-  },
   {
     "__type__": "cc.PrefabInfo",
     "root": {
@@ -472,7 +398,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 21
+      "__id__": 17
     },
     "_contentSize": {
       "__type__": "cc.Size",
@@ -500,7 +426,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 23
+      "__id__": 19
     },
     "_customMaterial": null,
     "_srcBlendFactor": 2,
@@ -545,12 +471,12 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 25
+      "__id__": 21
     },
     "tag": 2,
     "_group": 4,
     "_density": 1,
-    "_sensor": false,
+    "_sensor": true,
     "_friction": 0.2,
     "_restitution": 1,
     "_offset": {
@@ -616,7 +542,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 27
+      "__id__": 23
     },
     "enabledContactListener": true,
     "bullet": false,

+ 1 - 1
assets/assets/Prefabs/Block003.prefab

@@ -567,7 +567,7 @@
     "tag": 2,
     "_group": 4,
     "_density": 1,
-    "_sensor": false,
+    "_sensor": true,
     "_friction": 0.2,
     "_restitution": 1,
     "_offset": {

+ 1 - 1
assets/assets/Prefabs/Block004.prefab

@@ -658,7 +658,7 @@
     "tag": 2,
     "_group": 4,
     "_density": 1,
-    "_sensor": false,
+    "_sensor": true,
     "_friction": 0.2,
     "_restitution": 1,
     "_offset": {

+ 1 - 1
assets/assets/Prefabs/Block005.prefab

@@ -658,7 +658,7 @@
     "tag": 2,
     "_group": 4,
     "_density": 1,
-    "_sensor": false,
+    "_sensor": true,
     "_friction": 0.2,
     "_restitution": 1,
     "_offset": {

+ 5 - 5
assets/assets/Prefabs/Bullet.prefab

@@ -208,7 +208,7 @@
       "__id__": 8
     },
     "tag": 3,
-    "_group": 8,
+    "_group": 3,
     "_density": 1,
     "_sensor": false,
     "_friction": 1,
@@ -240,7 +240,7 @@
     "enabledContactListener": true,
     "bullet": true,
     "awakeOnLoad": true,
-    "_group": 8,
+    "_group": 3,
     "_type": 2,
     "_allowSleep": false,
     "_gravityScale": 0,
@@ -248,8 +248,8 @@
     "_angularDamping": 0,
     "_linearVelocity": {
       "__type__": "cc.Vec2",
-      "x": 50,
-      "y": 50
+      "x": 0,
+      "y": 0
     },
     "_angularVelocity": 0,
     "_fixedRotation": false,
@@ -354,7 +354,7 @@
     "__prefab": {
       "__id__": 17
     },
-    "speed": 100,
+    "speed": 500,
     "damage": 10,
     "lifetime": 5,
     "_id": ""

+ 9 - 0
assets/resources/Animation/222.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "0140fd30-8816-4520-af97-d79507e90bbb",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 419 - 288
assets/scripts/CombatSystem/BallController.ts

@@ -1,4 +1,4 @@
-import { _decorator, Component, Node, Vec2, Vec3, UITransform, Collider2D, Contact2DType, IPhysics2DContact, RigidBody2D, Prefab, instantiate, find, CircleCollider2D } from 'cc';
+import { _decorator, Component, Node, Vec2, Vec3, UITransform, Collider2D, Contact2DType, IPhysics2DContact, RigidBody2D, Prefab, instantiate, find, CircleCollider2D, PhysicsSystem2D } from 'cc';
 const { ccclass, property } = _decorator;
 
 @ccclass('BallController')
@@ -12,12 +12,8 @@ export class BallController extends Component {
 
     // 球的移动速度
     @property
-    public speed: number = 150;
+    public speed: number = 10;
 
-    // 子弹发射冷却时间(秒)
-    @property
-    public bulletCooldown: number = 0.5;
-    
     // 反弹随机偏移最大角度(弧度)
     @property
     public maxReflectionRandomness: number = 0.2;
@@ -42,12 +38,6 @@ export class BallController extends Component {
     // 是否已初始化
     private initialized: boolean = false;
     
-    // 子弹冷却状态
-    private canFireBullet: boolean = true;
-    
-    // 碰撞的方块ID记录,避免重复发射
-    private collidedBlockIds: Set<string> = new Set();
-
     // 子弹预制体
     @property({
         type: Prefab,
@@ -56,15 +46,30 @@ export class BallController extends Component {
     public bulletPrefab: Prefab = null;
 
     start() {
+        console.log('🎮 === BallController 开始初始化 ===');
+        
         // 计算游戏边界
         this.calculateGameBounds();
         
         // 检查子弹预制体是否已设置
         if (this.bulletPrefab) {
-            console.log('子弹预制体已设置:', this.bulletPrefab.name);
+            console.log('子弹预制体已设置:', this.bulletPrefab.name);
         } else {
-            console.error('子弹预制体未设置!请在编辑器中设置bulletPrefab属性');
+            console.error('❌ 子弹预制体未设置!请在编辑器中设置bulletPrefab属性');
+            console.error('⚠️  这将导致小球碰撞方块时无法发射子弹');
         }
+        
+        // 检查小球预制体是否已设置
+        if (this.ballPrefab) {
+            console.log('✅ 小球预制体已设置:', this.ballPrefab.name);
+        } else {
+            console.error('❌ 小球预制体未设置!请在编辑器中设置ballPrefab属性');
+        }
+        
+        console.log('🎮 === BallController 初始化完成 ===');
+        
+        // 输出碰撞矩阵调试信息
+        this.logCollisionMatrix();
     }
 
     // 计算游戏边界(使用GameArea节点)
@@ -141,6 +146,9 @@ export class BallController extends Component {
         // 初始化方向
         this.initializeDirection();
 
+        // 检查方块碰撞体状态
+        this.checkBlockColliders();
+
         this.initialized = true;
         console.log('小球创建完成:', {
             position: this.activeBall.position,
@@ -149,6 +157,97 @@ export class BallController extends Component {
         });
     }
 
+    // 检查所有已放置方块的碰撞体组件
+    private checkBlockColliders() {
+        console.log('🔍 === 检查方块碰撞体组件 ===');
+        
+        const placedBlocksContainer = find('Canvas/PlacedBlocks');
+        if (!placedBlocksContainer) {
+            console.log('❌ 找不到PlacedBlocks容器');
+            return;
+        }
+        
+        const blocks = [];
+        for (let i = 0; i < placedBlocksContainer.children.length; i++) {
+            const block = placedBlocksContainer.children[i];
+            if (block.name.includes('Block') || block.getChildByName('B1')) {
+                blocks.push(block);
+            }
+        }
+        
+        console.log(`找到 ${blocks.length} 个方块`);
+        
+        let fixedCount = 0;
+        
+        for (let i = 0; i < blocks.length; i++) {
+            const block = blocks[i];
+            console.log(`\n检查方块 ${i + 1}: ${block.name}`);
+            console.log('方块路径:', this.getNodePath(block));
+            
+            // 检查方块本身的碰撞体
+            const blockCollider = block.getComponent(Collider2D);
+            console.log('方块有碰撞体:', !!blockCollider);
+            if (blockCollider) {
+                console.log('碰撞体类型:', blockCollider.constructor.name);
+                console.log('碰撞组:', blockCollider.group);
+                console.log('碰撞标签:', blockCollider.tag);
+                console.log('是否为传感器:', blockCollider.sensor);
+                
+                // 🔧 自动修复碰撞组设置
+                if (blockCollider.group !== 2) {
+                    console.log(`🔧 修复方块碰撞组: ${blockCollider.group} -> 2`);
+                    blockCollider.group = 2; // 设置为Block组
+                    fixedCount++;
+                }
+                
+                // 确保不是传感器
+                if (blockCollider.sensor) {
+                    console.log(`🔧 修复方块传感器设置: true -> false`);
+                    blockCollider.sensor = false;
+                }
+            }
+            
+            // 检查B1子节点的碰撞体
+            const b1Node = block.getChildByName('B1');
+            if (b1Node) {
+                const b1Collider = b1Node.getComponent(Collider2D);
+                console.log('B1子节点有碰撞体:', !!b1Collider);
+                if (b1Collider) {
+                    console.log('B1碰撞体类型:', b1Collider.constructor.name);
+                    console.log('B1碰撞组:', b1Collider.group);
+                    console.log('B1碰撞标签:', b1Collider.tag);
+                    console.log('B1是否为传感器:', b1Collider.sensor);
+                    
+                    // 🔧 修复B1子节点的碰撞设置
+                    if (b1Collider.group !== 2) {
+                        console.log(`🔧 修复B1碰撞组: ${b1Collider.group} -> 2`);
+                        b1Collider.group = 2; // 设置为Block组
+                        fixedCount++;
+                    }
+                    
+                    // 确保B1不是传感器(需要实际碰撞)
+                    if (b1Collider.sensor) {
+                        console.log(`🔧 修复B1传感器设置: true -> false`);
+                        b1Collider.sensor = false;
+                    }
+                }
+            }
+            
+            // 检查Weapon子节点
+            const weaponNode = this.findWeaponNode(block);
+            console.log('方块有Weapon节点:', !!weaponNode);
+            if (weaponNode) {
+                console.log('Weapon节点路径:', this.getNodePath(weaponNode));
+            }
+        }
+        
+        if (fixedCount > 0) {
+            console.log(`✅ 已修复 ${fixedCount} 个碰撞组设置`);
+        }
+        
+        console.log('🔍 === 方块碰撞体检查完成 ===');
+    }
+
     // 随机位置小球
     positionBallRandomly() {
         if (!this.activeBall) return;
@@ -169,21 +268,21 @@ export class BallController extends Component {
             return;
         }
         
-        // 查找GridContainer节点,它包含所有放置的方块
-        const gridContainer = gameArea.getChildByName('GridContainer');
-        if (!gridContainer) {
-            console.log('找不到GridContainer节点,使用默认随机位置');
+        // 查找PlacedBlocks节点,它包含所有放置的方块
+        const placedBlocksContainer = find('Canvas/PlacedBlocks');
+        if (!placedBlocksContainer) {
+            console.log('找不到PlacedBlocks节点,使用默认随机位置');
             this.setRandomPositionDefault(minX, maxX, minY, maxY);
             return;
         }
         
         // 获取所有已放置的方块
         const placedBlocks = [];
-        for (let i = 0; i < gridContainer.children.length; i++) {
-            const cell = gridContainer.children[i];
-            // 检查单元格是否有子节点(放置的方块
-            if (cell.children.length > 0) {
-                placedBlocks.push(cell);
+        for (let i = 0; i < placedBlocksContainer.children.length; i++) {
+            const block = placedBlocksContainer.children[i];
+            // 检查是否是方块节点(通常以Block命名或有特定标识
+            if (block.name.includes('Block') || block.getChildByName('B1')) {
+                placedBlocks.push(block);
             }
         }
         
@@ -285,9 +384,13 @@ export class BallController extends Component {
     setupCollider() {
         if (!this.activeBall) return;
 
+        console.log('⚙️ === 开始设置小球碰撞组件 ===');
+        console.log('小球节点:', this.activeBall.name);
+
         // 确保小球有刚体组件
         let rigidBody = this.activeBall.getComponent(RigidBody2D);
         if (!rigidBody) {
+            console.log('🔧 添加RigidBody2D组件...');
             rigidBody = this.activeBall.addComponent(RigidBody2D);
             rigidBody.type = 2; // Dynamic
             rigidBody.gravityScale = 0; // 不受重力影响
@@ -296,7 +399,9 @@ export class BallController extends Component {
             rigidBody.allowSleep = false; // 不允许休眠
             rigidBody.linearDamping = 0; // 无线性阻尼,保持速度不衰减
             rigidBody.angularDamping = 0; // 无角阻尼
+            console.log('✅ RigidBody2D组件已添加');
         } else {
+            console.log('✅ RigidBody2D组件已存在,更新设置...');
             // 确保已有的刚体组件设置正确
             rigidBody.enabledContactListener = true;
             rigidBody.gravityScale = 0;
@@ -308,23 +413,31 @@ export class BallController extends Component {
         // 确保小球有碰撞组件
         let collider = this.activeBall.getComponent(CircleCollider2D);
         if (!collider) {
+            console.log('🔧 添加CircleCollider2D组件...');
             collider = this.activeBall.addComponent(CircleCollider2D);
             collider.radius = this.radius || 25; // 使用已计算的半径或默认值
             collider.tag = 1; // 小球标签
-            collider.group = 1; // 碰撞组
+            collider.group = 1; // 碰撞组1 - Ball组
             collider.sensor = false; // 非传感器(实际碰撞)
             collider.friction = 0; // 无摩擦
             collider.restitution = 1; // 完全弹性碰撞
+            console.log('✅ CircleCollider2D组件已添加');
         } else {
+            console.log('✅ CircleCollider2D组件已存在,更新设置...');
             // 确保已有的碰撞组件设置正确
             collider.sensor = false;
             collider.restitution = 1;
+            collider.group = 1; // 确保是Ball组
+            collider.tag = 1; // 确保标签正确
         }
 
-        console.log('小球碰撞组件设置完成:', {
+        console.log('🔧 小球碰撞组件设置完成:', {
             hasRigidBody: !!rigidBody,
             hasCollider: !!collider,
-            radius: collider ? collider.radius : 'unknown'
+            radius: collider ? collider.radius : 'unknown',
+            contactListener: rigidBody ? rigidBody.enabledContactListener : false,
+            group: collider ? collider.group : 'unknown',
+            tag: collider ? collider.tag : 'unknown'
         });
 
         // 移除可能存在的事件监听
@@ -333,145 +446,101 @@ export class BallController extends Component {
         this.activeBall.off(Contact2DType.PRE_SOLVE);
         this.activeBall.off(Contact2DType.POST_SOLVE);
         
-        // 注册所有类型的碰撞事件
+        // 注册单个碰撞体的回调函数
         this.activeBall.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
         this.activeBall.on(Contact2DType.END_CONTACT, this.onEndContact, this);
         this.activeBall.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
         this.activeBall.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
         
-        console.log('已注册所有碰撞事件监听器');
+        // 注册全局碰撞回调函数
+        if (PhysicsSystem2D.instance) {
+            // 移除可能存在的全局监听器
+            PhysicsSystem2D.instance.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
+            PhysicsSystem2D.instance.off(Contact2DType.END_CONTACT, this.onEndContact, this);
+            
+            // 注册全局监听器
+            PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
+            PhysicsSystem2D.instance.on(Contact2DType.END_CONTACT, this.onEndContact, this);
+            console.log('✅ 已注册全局碰撞监听器');
+        }
+        
+        console.log('✅ 已注册所有碰撞事件监听器');
+        console.log('⚙️ === 碰撞组件设置完成 ===');
     }
 
-    // 碰撞回调中,只需要更新方向向量,物理引擎会处理实际的反弹
+    // 碰撞回调 - 简化版本用于测试
     onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
-        // 获取碰撞点和法线
-        if (!contact) {
-            console.warn('碰撞事件没有contact对象');
-            return;
-        }
-
-        // 记录碰撞对象信息
-        console.log('碰撞发生:', {
-            selfName: selfCollider.node.name,
-            otherName: otherCollider.node.name,
-            otherPath: this.getNodePath(otherCollider.node)
+        console.log('🎯 碰撞成功...');
+        console.log('碰撞对象:', {
+            self: selfCollider.node.name,
+            other: otherCollider.node.name,
+            otherGroup: otherCollider.group,
+            selfGroup: selfCollider.group
         });
-
-        // Debug: 检查节点名称是否包含Block
-        console.log(`检查节点名称: "${otherCollider.node.name}",是否包含'Block': ${otherCollider.node.name.includes('Block')}`);
-
-        // 获取碰撞点的世界坐标
-        const worldManifold = contact.getWorldManifold();
-        if (!worldManifold) {
-            console.warn('无法获取worldManifold');
-            return;
+        
+        // 判断哪个是小球,哪个是方块
+        let ballNode: Node = null;
+        let blockNode: Node = null;
+        
+        // 检查self是否为小球(组1)
+        if (selfCollider.group === 1) {
+            ballNode = selfCollider.node;
+            blockNode = otherCollider.node;
+        } 
+        // 检查other是否为小球(组1)
+        else if (otherCollider.group === 1) {
+            ballNode = otherCollider.node;
+            blockNode = selfCollider.node;
         }
-
-        // 获取碰撞法线
-        const normal = worldManifold.normal;
-        console.log('碰撞法线:', normal);
-        
-        // 检查是否碰到墙体
-        const nodeName = otherCollider.node.name;
-        const nodePath = this.getNodePath(otherCollider.node);
-        const nodeParent = otherCollider.node.parent ? otherCollider.node.parent.name : 'unknown';
-        
-        console.log(`检查墙体碰撞: ${nodeName}, 路径: ${nodePath}, 父节点: ${nodeParent}`);
-        
-        // 使用多种方式检测墙体碰撞
-        const isWall = 
-            nodeName === 'TopFence' || 
-            nodeName === 'BottomFence' || 
-            nodeName === 'JiguangL' || 
-            nodeName === 'JiguangR' ||
-            nodeName.includes('Fence') || 
-            nodeName.includes('Jiguang') ||
-            nodePath.includes('GameArea/TopFence') ||
-            nodePath.includes('GameArea/BottomFence') ||
-            nodePath.includes('GameArea/JiguangL') ||
-            nodePath.includes('GameArea/JiguangR');
-            
-        if (isWall) {
-            console.log(`球碰到了墙体 ${nodeName},进行反弹,路径: ${nodePath}`);
-            
-            // 更新方向向量
-            this.direction = this.calculateReflection(this.direction, normal);
-            
-            // 确保球有刚体组件
-            const rigidBody = this.activeBall.getComponent(RigidBody2D);
-            if (rigidBody) {
-                // 立即更新速度方向,确保反弹效果
-                rigidBody.linearVelocity = new Vec2(
-                    this.direction.x * this.speed,
-                    this.direction.y * this.speed
-                );
-                console.log('更新后的速度:', rigidBody.linearVelocity);
-            }
+        
+        // 如果没有找到小球,跳过处理
+        if (!ballNode || !blockNode) {
+            console.log('❌ 未检测到小球参与的碰撞');
+            return;
         }
         
-        // 如果碰撞的是方块,发射子弹
-        // 修改检测逻辑,使用更宽松的条件
+        console.log('✅ 检测到小球与方块碰撞:', {
+            ball: ballNode.name,
+            block: blockNode.name
+        });
+        
+        // 检查碰撞对象是否为方块
+        const nodeName = blockNode.name;
+        const nodePath = this.getNodePath(blockNode);
+        
+        // 检查是否有Weapon子节点(判断是否为方块)
+        const hasWeaponChild = blockNode.getChildByName('Weapon') !== null;
         const isBlock = 
             nodeName.includes('Block') || 
             nodePath.includes('Block') ||
-            (otherCollider.node.getChildByName('Weapon') !== null);
+            hasWeaponChild;
             
-        if (isBlock) {
-            console.log(`检测到方块碰撞: ${nodeName}, 路径: ${nodePath}`);
+        console.log('判定为方块:', isBlock);
             
-            // 检查冷却状态和是否已经对这个方块发射过子弹
-            const blockId = otherCollider.node.uuid;
-            if (this.canFireBullet && !this.collidedBlockIds.has(blockId)) {
-            this.fireBullet(otherCollider.node);
-            } else {
-                console.log('子弹冷却中或已对此方块发射过子弹');
-            }
+        if (isBlock) {
+            console.log(`🎯 检测到方块碰撞: ${nodeName}, 路径: ${nodePath}`);
+            console.log('🚀 方块武器被激活,发射子弹攻击敌人...');
+            this.fireBullet(blockNode);
+            console.log('✅ 子弹发射完成');
         }
     }
 
-    // 碰撞结束事件
+    // 碰撞结束事件 - 简化版本
     onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
-        console.log('碰撞结束:', otherCollider.node.name);
+        console.log('🔚 碰撞结束:', {
+            self: selfCollider.node.name,
+            other: otherCollider.node.name
+        });
     }
     
-    // 碰撞预处理事件
+    // 碰撞预处理事件 - 简化版本
     onPreSolve(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
-        console.log('碰撞预处理:', otherCollider.node.name);
+        console.log('⚙️ 碰撞预处理:', otherCollider.node.name);
     }
     
-    // 碰撞后处理事件
+    // 碰撞后处理事件 - 简化版本
     onPostSolve(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
-        console.log('碰撞后处理:', otherCollider.node.name);
-        
-        // 检查是否碰到墙体
-        const nodeName = otherCollider.node.name;
-        if (nodeName === 'TopFence' || nodeName === 'BottomFence' || 
-            nodeName === 'JiguangL' || nodeName === 'JiguangR' ||
-            nodeName.includes('Fence') || nodeName.includes('Jiguang')) {
-            console.log(`球碰到了墙体 ${nodeName},处理反弹`);
-            
-            // 获取碰撞点和法线
-            if (!contact) return;
-            
-            const worldManifold = contact.getWorldManifold();
-            if (!worldManifold) return;
-            
-            // 获取碰撞法线
-            const normal = worldManifold.normal;
-            
-            // 更新方向向量
-            this.direction = this.calculateReflection(this.direction, normal);
-            
-            // 确保球有刚体组件
-            const rigidBody = this.activeBall.getComponent(RigidBody2D);
-            if (rigidBody) {
-                // 立即更新速度方向,确保反弹效果
-                rigidBody.linearVelocity = new Vec2(
-                    this.direction.x * this.speed,
-                    this.direction.y * this.speed
-                );
-            }
-        }
+        console.log('✅ 碰撞后处理:', otherCollider.node.name);
     }
 
     // 计算反射向量
@@ -528,114 +597,114 @@ export class BallController extends Component {
         return randomizedReflection;
     }
 
-    // 发射子弹
+    // 从方块武器发射子弹攻击敌人
     fireBullet(blockNode: Node) {
-        console.log('发射子弹!击中方块:', blockNode.name);
+        console.log('🔫 === 方块武器发射子弹流程 ===');
+        console.log('激活的方块:', blockNode.name);
+        console.log('方块路径:', this.getNodePath(blockNode));
         
-        // 检查冷却状态
-        if (!this.canFireBullet) {
-            console.log('子弹冷却中,无法发射');
-            return;
-        }
-        
-        // 检查是否已经对这个方块发射过子弹
-        const blockId = blockNode.uuid;
-        if (this.collidedBlockIds.has(blockId)) {
-            console.log('已经对此方块发射过子弹');
-            return;
-        }
-        
-        // 记录此方块ID
-        this.collidedBlockIds.add(blockId);
-        
-        // 设置冷却
-        this.canFireBullet = false;
-        this.scheduleOnce(() => {
-            this.canFireBullet = true;
-            // 清理碰撞记录
-            this.collidedBlockIds.clear();
-        }, this.bulletCooldown);
-        
-        // 检查是否有子弹预制体
+        // 检查子弹预制体是否存在
         if (!this.bulletPrefab) {
-            console.error('未设置子弹预制体');
+            console.error('❌ 子弹预制体未设置');
             return;
-        } else {
-            console.log('子弹预制体已设置:', this.bulletPrefab.name);
-        }
-        
-        // 查找Weapon节点 - 递归查找,因为Weapon可能在B1子节点下
-        let weaponNode = this.findWeaponNode(blockNode);
-        
+        }        
+        // 查找方块中的Weapon节点
+        console.log('🔍 开始查找方块中的Weapon节点...');
+        const weaponNode = this.findWeaponNode(blockNode);
         if (!weaponNode) {
-            console.warn(`方块 ${blockNode.name} 没有找到Weapon子节点,创建一个`);
-            // 如果没有找到Weapon节点,在B1节点下创建一个
-            const b1Node = blockNode.getChildByName('B1');
-            if (b1Node) {
-                weaponNode = new Node('Weapon');
-                // 确保Weapon节点有UITransform组件
-                if (!weaponNode.getComponent(UITransform)) {
-                    weaponNode.addComponent(UITransform);
-                }
-                // 将Weapon添加到B1节点中
-                b1Node.addChild(weaponNode);
-                // 放置在B1中心
-                weaponNode.position = new Vec3(0, 0, 0);
-            } else {
-                // 如果连B1节点都没有,直接添加到方块根节点
-                weaponNode = new Node('Weapon');
-                // 确保Weapon节点有UITransform组件
-                if (!weaponNode.getComponent(UITransform)) {
-                    weaponNode.addComponent(UITransform);
-                }
-                // 将Weapon添加到方块中
-                blockNode.addChild(weaponNode);
-                // 放置在方块中心
-                weaponNode.position = new Vec3(0, 0, 0);
-            }
-        } else {
-            console.log(`找到方块 ${blockNode.name} 的Weapon子节点:`, weaponNode.name);
+            console.error('❌ 在方块中找不到Weapon节点:', blockNode.name);
+            console.log('方块结构:');
+            this.logNodeStructure(blockNode, 0);
+            return;
         }
+        console.log('✅ 找到Weapon节点:', weaponNode.name);
+        console.log('Weapon节点路径:', this.getNodePath(weaponNode));
         
         // 实例化子弹
+        console.log('🏗️ 开始创建攻击敌人的子弹...');
         const bullet = instantiate(this.bulletPrefab);
+        console.log('✅ 子弹创建成功:', bullet.name);
         
         // 将子弹添加到GameArea中
         const gameArea = find('Canvas/GameLevelUI/GameArea');
         if (gameArea) {
             gameArea.addChild(bullet);
+            console.log('✅ 子弹已添加到GameArea');
             
-            // 设置子弹初始位置为Weapon节点的位置
-            const weaponWorldPos = weaponNode.worldPosition;
-            bullet.worldPosition = weaponWorldPos;
+            // 设置子弹初始位置 - 简化版本
+            try {
+                // 直接使用方块的位置作为发射起点
+                const blockWorldPos = blockNode.worldPosition;
+                console.log('方块世界坐标:', blockWorldPos);
+                
+                // 延迟设置位置,确保节点已完全添加到场景树
+                this.scheduleOnce(() => {
+                    try {
+                        // 将世界坐标转换为GameArea的本地坐标
+                        const gameAreaTransform = gameArea.getComponent(UITransform);
+                        const localPos = gameAreaTransform.convertToNodeSpaceAR(blockWorldPos);
+                        bullet.position = localPos;
+                        console.log('✅ 子弹位置已设置:', {
+                            blockWorldPos: blockWorldPos,
+                            bulletLocalPos: localPos
+                        });
+                    } catch (error) {
+                        console.error('❌ 设置子弹位置失败:', error);
+                        // 备用方案:设置为GameArea中心
+                        bullet.position = new Vec3(0, 0, 0);
+                        console.log('✅ 使用默认位置设置子弹');
+                    }
+                }, 0.02); // 延迟两帧
+                
+            } catch (error) {
+                console.error('❌ 获取方块坐标失败:', error);
+                // 备用方案:设置为默认位置
+                bullet.position = new Vec3(0, 0, 0);
+            }
             
-            // 子弹已经有BulletController组件,不需要再添加
-            // 让子弹自己找到最近的敌人并攻击
-            console.log('子弹已创建,将自动寻找并攻击最近的敌人');
+            console.log('🎯 子弹已创建,将自动寻找并攻击最近的敌人');
+        } else {
+            console.error('❌ 找不到GameArea节点');
         }
+        console.log('🔫 === 方块武器发射子弹流程结束 ===');
     }
     
     // 递归查找Weapon节点
     private findWeaponNode(node: Node): Node | null {
+        console.log(`🔍 在节点 ${node.name} 中查找Weapon...`);
+        
         // 先检查当前节点是否有Weapon子节点
         const weaponNode = node.getChildByName('Weapon');
         if (weaponNode) {
+            console.log(`✅ 在 ${node.name} 中找到Weapon节点`);
             return weaponNode;
         }
         
         // 如果没有,递归检查所有子节点
         for (let i = 0; i < node.children.length; i++) {
             const child = node.children[i];
+            console.log(`  🔍 检查子节点: ${child.name}`);
             const foundWeapon = this.findWeaponNode(child);
             if (foundWeapon) {
+                console.log(`✅ 在 ${child.name} 的子节点中找到Weapon`);
                 return foundWeapon;
             }
         }
         
         // 如果都没找到,返回null
+        console.log(`❌ 在 ${node.name} 及其子节点中未找到Weapon`);
         return null;
     }
 
+    // 辅助方法:打印节点结构
+    private logNodeStructure(node: Node, depth: number) {
+        const indent = '  '.repeat(depth);
+        console.log(`${indent}${node.name}`);
+        for (let i = 0; i < node.children.length; i++) {
+            this.logNodeStructure(node.children[i], depth + 1);
+        }
+    }
+
     // 获取节点的完整路径
     private getNodePath(node: Node): string {
         let path = node.name;
@@ -667,103 +736,132 @@ export class BallController extends Component {
                 this.direction.y = currentVelocity.y / speed;
             }
             
-            // 手动检测墙体碰撞
-            this.checkWallCollisions();
-        }
-
-        // 手动检测方块碰撞
-        this.checkBlockCollisions();
-    }
-    
-    // 手动检测墙体碰撞
-    checkWallCollisions() {
-        if (!this.activeBall || !this.activeBall.isValid) return;
-        
-        // 获取小球的世界坐标
-        const ballPos = this.activeBall.worldPosition;
-        const ballRadius = this.radius;
-        
-        // 检查是否碰到上下左右边界
-        let collided = false;
-        let normal = new Vec2(0, 0);
-        
-        // 上边界碰撞
-        if (ballPos.y + ballRadius >= this.gameBounds.top) {
-            normal.y = -1;
-            collided = true;
-            console.log('手动检测到上边界碰撞');
-        }
-        // 下边界碰撞
-        else if (ballPos.y - ballRadius <= this.gameBounds.bottom) {
-            normal.y = 1;
-            collided = true;
-            console.log('手动检测到下边界碰撞');
-        }
-        
-        // 左边界碰撞
-        if (ballPos.x - ballRadius <= this.gameBounds.left) {
-            normal.x = 1;
-            collided = true;
-            console.log('手动检测到左边界碰撞');
-        }
-        // 右边界碰撞
-        else if (ballPos.x + ballRadius >= this.gameBounds.right) {
-            normal.x = -1;
-            collided = true;
-            console.log('手动检测到右边界碰撞');
-        }
-        
-        // 如果碰到边界,计算反弹
-        if (collided) {
-            // 标准化法向量
-            if (normal.x !== 0 || normal.y !== 0) {
-                normal.normalize();
-            }
-            
-            // 计算反射方向
-            this.direction = this.calculateReflection(this.direction, normal);
-            
-            // 更新速度
-            const rigidBody = this.activeBall.getComponent(RigidBody2D);
-            if (rigidBody) {
-                // 立即更新速度方向,确保反弹效果
+            // 如果速度过低,重新设置速度以维持恒定运动
+            if (speed < this.speed * 0.9) {
                 rigidBody.linearVelocity = new Vec2(
                     this.direction.x * this.speed,
                     this.direction.y * this.speed
                 );
-                console.log('手动更新速度方向:', this.direction);
             }
+            
+            // 定期检查小球是否接近方块但没有触发碰撞(调试用)
+            this.debugCheckNearBlocks();
         }
     }
-
-    // 手动检测方块碰撞
-    checkBlockCollisions() {
-        if (!this.activeBall) return;
-        
-        // 获取场景中所有方块
-        const placedBlocks = find('Canvas/PlacedBlocks');
-        if (!placedBlocks) return;
+    
+    // 调试方法:检查小球是否接近方块但没有触发物理碰撞
+    private debugCheckCounter = 0;
+    private debugCheckNearBlocks() {
+        this.debugCheckCounter++;
+        // 每60帧(约1秒)检查一次
+        if (this.debugCheckCounter % 60 !== 0) return;
         
         const ballPos = this.activeBall.worldPosition;
-        const ballRadius = this.radius;
+        const placedBlocksContainer = find('Canvas/PlacedBlocks');
+        if (!placedBlocksContainer) return;
+        
+        let nearestDistance = Infinity;
+        let nearestBlock = null;
         
-        // 检查与每个方块的碰撞
-        for (let i = 0; i < placedBlocks.children.length; i++) {
-            const block = placedBlocks.children[i];
-            if (!block.name.includes('Block')) continue;
+        for (let i = 0; i < placedBlocksContainer.children.length; i++) {
+            const block = placedBlocksContainer.children[i];
+            if (block.name.includes('Block') || block.getChildByName('B1')) {
+                const blockPos = block.worldPosition;
+                const distance = Math.sqrt(
+                    Math.pow(ballPos.x - blockPos.x, 2) + 
+                    Math.pow(ballPos.y - blockPos.y, 2)
+                );
+                
+                if (distance < nearestDistance) {
+                    nearestDistance = distance;
+                    nearestBlock = block;
+                }
+            }
+        }
+        
+        if (nearestBlock && nearestDistance < 100) {
+            console.log(`⚠️  小球接近方块但无物理碰撞: 距离=${nearestDistance.toFixed(1)}, 方块=${nearestBlock.name}`);
+            console.log('小球位置:', ballPos);
+            console.log('方块位置:', nearestBlock.worldPosition);
+            
+            // 检查小球的碰撞体状态
+            console.log('=== 小球碰撞体详细检查 ===');
+            const ballCollider = this.activeBall.getComponent(Collider2D);
+            console.log('小球有碰撞体:', !!ballCollider);
+            if (ballCollider) {
+                console.log('小球碰撞体类型:', ballCollider.constructor.name);
+                console.log('小球碰撞组:', ballCollider.group);
+                console.log('小球碰撞标签:', ballCollider.tag);
+                console.log('小球是否为传感器:', ballCollider.sensor);
+                console.log('小球碰撞体是否启用:', ballCollider.enabled);
+                if (ballCollider instanceof CircleCollider2D) {
+                    console.log('小球碰撞半径:', ballCollider.radius);
+                }
+            }
             
-            // 简单距离检测(可以根据实际情况优化)
-            const blockPos = block.worldPosition;
-            const distance = Vec3.distance(ballPos, blockPos);
+            // 检查小球的刚体状态
+            const ballRigidBody = this.activeBall.getComponent(RigidBody2D);
+            console.log('小球有刚体:', !!ballRigidBody);
+            if (ballRigidBody) {
+                console.log('小球刚体类型:', ballRigidBody.type);
+                console.log('小球刚体启用碰撞监听:', ballRigidBody.enabledContactListener);
+                console.log('小球刚体是否启用:', ballRigidBody.enabled);
+            }
             
-            // 如果距离小于某个阈值,认为发生碰撞
-            if (distance < ballRadius + 50) { // 50是一个估计值,根据方块大小调整
-                console.log('手动检测到与方块碰撞:', block.name);
-                this.fireBullet(block);
-                break;
+            // 检查最近的方块碰撞体
+            console.log('=== 方块碰撞体详细检查 ===');
+            const blockCollider = nearestBlock.getComponent(Collider2D);
+            console.log('方块有碰撞体:', !!blockCollider);
+            if (blockCollider) {
+                console.log('方块碰撞体类型:', blockCollider.constructor.name);
+                console.log('方块碰撞组:', blockCollider.group);
+                console.log('方块碰撞标签:', blockCollider.tag);
+                console.log('方块是否为传感器:', blockCollider.sensor);
+                console.log('方块碰撞体是否启用:', blockCollider.enabled);
             }
+            
+            // 检查碰撞矩阵
+            console.log('=== 碰撞矩阵检查 ===');
+            if (ballCollider && blockCollider) {
+                console.log(`小球组${ballCollider.group} 是否能与方块组${blockCollider.group} 碰撞: ${this.checkCollisionMatrix(ballCollider.group, blockCollider.group)}`);
+            }
+            
+            // 检查物理引擎状态
+            console.log('=== 物理引擎状态检查 ===');
+            console.log('物理引擎是否启用:', PhysicsSystem2D.instance.enable);
+            console.log('物理引擎重力:', PhysicsSystem2D.instance.gravity);
         }
     }
+    
+    // 检查碰撞矩阵
+    private checkCollisionMatrix(group1: number, group2: number): boolean {
+        // 根据项目配置检查碰撞矩阵
+        // "collisionMatrix": { "0": 3, "1": 39, "2": 6, "3": 16, "4": 40, "5": 18 }
+        const collisionMatrix: { [key: string]: number } = {
+            "0": 3,
+            "1": 39,
+            "2": 6,
+            "3": 16,
+            "4": 40,
+            "5": 18
+        };
+        
+        const mask1 = collisionMatrix[group1.toString()];
+        const mask2 = collisionMatrix[group2.toString()];
+        
+        console.log(`组${group1}的碰撞掩码: ${mask1} (二进制: ${mask1?.toString(2)})`);
+        console.log(`组${group2}的碰撞掩码: ${mask2} (二进制: ${mask2?.toString(2)})`);
+        
+        // 检查group1是否能与group2碰撞
+        const canCollide1to2 = mask1 && (mask1 & (1 << group2)) !== 0;
+        // 检查group2是否能与group1碰撞
+        const canCollide2to1 = mask2 && (mask2 & (1 << group1)) !== 0;
+        
+        console.log(`组${group1}->组${group2}: ${canCollide1to2}`);
+        console.log(`组${group2}->组${group1}: ${canCollide2to1}`);
+        
+        return canCollide1to2 && canCollide2to1;
+    }
 
     // 初始化方向
     initializeDirection() {
@@ -795,4 +893,37 @@ export class BallController extends Component {
         this.calculateGameBounds();
         this.createBall();
     }
+
+    // 输出碰撞矩阵调试信息
+    private logCollisionMatrix() {
+        // 根据项目配置检查碰撞矩阵
+        // "collisionMatrix": { "0": 3, "1": 39, "2": 6, "3": 16, "4": 40, "5": 18 }
+        const collisionMatrix: { [key: string]: number } = {
+            "0": 3,
+            "1": 39,
+            "2": 6,
+            "3": 16,
+            "4": 40,
+            "5": 18
+        };
+        
+        console.log('🔍 === 碰撞矩阵配置 ===');
+        for (const group in collisionMatrix) {
+            const mask = collisionMatrix[group];
+            console.log(`组 ${group}: 掩码 ${mask} (二进制: ${mask?.toString(2)})`);
+        }
+        
+        // 测试Ball组(1)和Block组(2)是否能碰撞
+        const ballMask = collisionMatrix["1"]; // 39
+        const blockMask = collisionMatrix["2"]; // 6
+        
+        const ballCanCollideWithBlock = (ballMask & (1 << 2)) !== 0; // 检查Ball能否与组2碰撞
+        const blockCanCollideWithBall = (blockMask & (1 << 1)) !== 0; // 检查Block能否与组1碰撞
+        
+        console.log('🎯 碰撞测试结果:');
+        console.log(`Ball组(1) -> Block组(2): ${ballCanCollideWithBlock}`);
+        console.log(`Block组(2) -> Ball组(1): ${blockCanCollideWithBall}`);
+        console.log(`双向碰撞可用: ${ballCanCollideWithBlock && blockCanCollideWithBall}`);
+        console.log('🔍 === 碰撞矩阵分析完成 ===');
+    }
 } 

+ 432 - 32
assets/scripts/CombatSystem/BulletController.ts

@@ -19,12 +19,53 @@ export class BulletController extends Component {
     private direction: Vec3 = null;
 
     start() {
+        console.log('🚀 子弹开始初始化...');
+        
+        // 调试碰撞组信息
+        this.debugCollisionGroups();
+        
         // 获取刚体组件
-        this.rigidBody = this.node.getChildByName('Icon').getComponent(RigidBody2D);
+        this.rigidBody = this.node.getChildByName('Icon')?.getComponent(RigidBody2D);
+        if (!this.rigidBody) {
+            console.error('❌ 子弹找不到Icon子节点的RigidBody2D组件');
+            return;
+        }
+        console.log('✅ 子弹刚体组件获取成功');
+        
+        // 重置刚体的预设速度
+        this.rigidBody.linearVelocity = new Vec2(0, 0);
+        console.log('🔧 已重置刚体预设速度');
+        
+        // 设置刚体参数
+        this.rigidBody.gravityScale = 0; // 不受重力影响
+        this.rigidBody.linearDamping = 0; // 无阻尼
+        this.rigidBody.angularDamping = 0; // 无角阻尼
+        this.rigidBody.allowSleep = false; // 不允许休眠
         
         // 设置子弹生命周期
         this.lifeTimer = this.lifetime;
         
+        // 延迟一帧后再设置方向和速度,确保节点完全初始化
+        this.scheduleOnce(() => {
+            this.initializeBulletDirection();
+        }, 0.02);
+        
+        // 注册碰撞事件
+        const collider = this.node.getChildByName('Icon')?.getComponent(Collider2D);
+        if (collider) {
+            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
+            console.log('✅ 子弹碰撞事件已注册');
+        } else {
+            console.error('❌ 子弹找不到Icon子节点的Collider2D组件');
+        }
+        
+        console.log('🚀 子弹初始化完成');
+    }
+    
+    // 初始化子弹方向
+    private initializeBulletDirection() {
+        console.log('🎯 开始初始化子弹方向...');
+        
         // 如果没有设置目标,寻找最近的敌人
         if (!this.targetEnemy) {
             this.findNearestEnemy();
@@ -32,49 +73,202 @@ export class BulletController extends Component {
         
         // 设置初始方向
         if (this.targetEnemy) {
+            console.log('🎯 设置子弹朝向目标敌人');
             this.setDirectionToTarget();
         } else {
             // 没有敌人目标时,设置随机方向
+            console.log('🎲 没有敌人目标,设置随机发射方向');
             const randomAngle = Math.random() * Math.PI * 2;
             this.direction = new Vec3(Math.cos(randomAngle), Math.sin(randomAngle), 0);
+            console.log('随机方向:', this.direction);
         }
         
         // 设置初始速度
         this.updateVelocity();
         
-        // 注册碰撞事件
-        const collider = this.node.getChildByName('Icon').getComponent(Collider2D);
-        if (collider) {
-            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
-        }
+        // 再次确认速度设置
+        this.scheduleOnce(() => {
+            if (this.rigidBody) {
+                const currentVelocity = this.rigidBody.linearVelocity;
+                console.log('🔍 最终确认子弹速度:', currentVelocity);
+                const speed = Math.sqrt(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y);
+                console.log('🔍 速度大小:', speed);
+                
+                if (speed < 50) {
+                    console.warn('⚠️ 子弹速度过低,重新设置...');
+                    this.updateVelocity();
+                }
+            }
+        }, 0.1);
     }
 
     // 寻找最近的敌人
     private findNearestEnemy() {
-        // 查找敌人容器
-        const enemyContainer = find('Canvas/GameLevelUI/enemyContainer');
+        console.log('🔍 子弹开始寻找最近的敌人...');
+        
+        // 主要路径:Canvas/GameLevelUI/enemyContainer
+        const primaryPath = 'Canvas/GameLevelUI/enemyContainer';
+        let enemyContainer = find(primaryPath);
+        
+        if (enemyContainer) {
+            console.log('✅ 找到主要敌人容器:', primaryPath);
+        } else {
+            console.log('❌ 主要路径未找到,尝试备用路径...');
+            // 备用路径
+            const backupPaths = [
+                'Canvas/enemyContainer', 
+                'Canvas/EnemyContainer',
+                'Canvas/GameLevelUI/EnemyContainer',
+                'Canvas/GameArea/enemyContainer'
+            ];
+            
+            for (const path of backupPaths) {
+                enemyContainer = find(path);
+                if (enemyContainer) {
+                    console.log('✅ 找到备用敌人容器:', path);
+                    break;
+                }
+            }
+        }
+        
         if (!enemyContainer) {
+            console.log('❌ 未找到任何敌人容器,尝试在整个场景中搜索敌人节点...');
+            // 如果找不到容器,尝试直接搜索敌人节点
+            const allEnemies = this.findAllEnemyNodes();
+            if (allEnemies.length > 0) {
+                this.selectNearestFromEnemies(allEnemies);
+            } else {
+                console.log('❌ 场景中没有找到任何敌人,子弹将随机发射');
+            }
             return;
         }
         
-        const enemies = enemyContainer.children.filter(child => child.name === 'Enemy');
+        // 打印容器详细信息
+        console.log('敌人容器详细信息:', {
+            name: enemyContainer.name,
+            childrenCount: enemyContainer.children.length,
+            children: enemyContainer.children.map(child => ({
+                name: child.name,
+                active: child.active,
+                hasEnemyInstance: !!child.getComponent('EnemyInstance'),
+                hasEnemyComponent: !!child.getComponent('EnemyComponent')
+            }))
+        });
+        
+        // 在容器中查找敌人 - 使用更宽泛的匹配条件
+        const enemies = enemyContainer.children.filter(child => {
+            if (!child.active) return false; // 跳过非激活的节点
+            
+            const name = child.name.toLowerCase();
+            const hasEnemyComponent = child.getComponent('EnemyInstance') !== null || 
+                                    child.getComponent('EnemyComponent') !== null;
+            
+            return name === 'enemy' || 
+                   name.includes('enemy') ||
+                   name.includes('敌人') ||
+                   hasEnemyComponent ||
+                   name.startsWith('enemy') ||
+                   name.endsWith('enemy');
+        });
+        
+        console.log(`在容器中找到 ${enemies.length} 个敌人:`, enemies.map(e => ({
+            name: e.name,
+            position: e.worldPosition
+        })));
+        
         if (enemies.length === 0) {
+            console.log('❌ 敌人容器中没有找到敌人,尝试将所有子节点作为潜在目标...');
+            // 如果没有找到明确的敌人,尝试将所有活动的子节点作为目标
+            const allActiveChildren = enemyContainer.children.filter(child => child.active);
+            if (allActiveChildren.length > 0) {
+                console.log(`🔍 将 ${allActiveChildren.length} 个活动子节点作为潜在目标`);
+                this.selectNearestFromEnemies(allActiveChildren);
+            } else {
+                console.log('❌ 容器中没有任何活动节点,子弹将随机发射');
+            }
             return;
         }
         
+        this.selectNearestFromEnemies(enemies);
+    }
+    
+    // 在整个场景中搜索敌人节点
+    private findAllEnemyNodes(): Node[] {
+        const canvas = find('Canvas');
+        if (!canvas) return [];
+        
+        const enemies: Node[] = [];
+        this.searchEnemiesRecursive(canvas, enemies);
+        console.log(`在整个场景中找到 ${enemies.length} 个敌人`);
+        return enemies;
+    }
+    
+    // 递归搜索敌人节点
+    private searchEnemiesRecursive(node: Node, enemies: Node[]) {
+        // 检查当前节点是否为敌人
+        if (node.active) {
+            const name = node.name.toLowerCase();
+            const hasEnemyComponent = node.getComponent('EnemyInstance') !== null || 
+                                    node.getComponent('EnemyComponent') !== null;
+            
+            if (name === 'enemy' || 
+                name.includes('enemy') ||
+                name.includes('敌人') ||
+                hasEnemyComponent ||
+                name.startsWith('enemy') ||
+                name.endsWith('enemy')) {
+                enemies.push(node);
+                console.log(`🎯 找到敌人节点: ${node.name} (路径: ${this.getNodePath(node)})`);
+            }
+        }
+        
+        // 递归搜索子节点
+        for (const child of node.children) {
+            this.searchEnemiesRecursive(child, enemies);
+        }
+    }
+    
+    // 获取节点的完整路径
+    private getNodePath(node: Node): string {
+        let path = node.name;
+        let current = node;
+        
+        while (current.parent) {
+            current = current.parent;
+            path = current.name + '/' + path;
+        }
+        
+        return path;
+    }
+    
+    // 从敌人列表中选择最近的
+    private selectNearestFromEnemies(enemies: Node[]) {
         let nearestEnemy: Node = null;
         let nearestDistance = Infinity;
         
+        const bulletPos = this.node.worldPosition;
+        console.log('子弹当前位置:', bulletPos);
+        
         for (const enemy of enemies) {
-            const distance = Vec3.distance(this.node.worldPosition, enemy.worldPosition);
-            if (distance < nearestDistance) {
-                nearestDistance = distance;
-                nearestEnemy = enemy;
+            try {
+                const enemyPos = enemy.worldPosition;
+                const distance = Vec3.distance(bulletPos, enemyPos);
+                console.log(`敌人 ${enemy.name} 距离: ${distance.toFixed(1)}`);
+                
+                if (distance < nearestDistance) {
+                    nearestDistance = distance;
+                    nearestEnemy = enemy;
+                }
+            } catch (error) {
+                console.error('计算敌人距离时出错:', error);
             }
         }
         
         if (nearestEnemy) {
             this.targetEnemy = nearestEnemy;
+            console.log(`✅ 选定目标敌人: ${nearestEnemy.name}, 距离: ${nearestDistance.toFixed(1)}`);
+        } else {
+            console.log('❌ 无法确定最近敌人,子弹将随机发射');
         }
     }
 
@@ -82,23 +276,71 @@ export class BulletController extends Component {
     private setDirectionToTarget() {
         if (!this.targetEnemy) return;
         
-        const targetPos = this.targetEnemy.worldPosition;
-        const currentPos = this.node.worldPosition;
-        
-        this.direction = targetPos.subtract(currentPos).normalize();
+        try {
+            const targetPos = this.targetEnemy.worldPosition;
+            const currentPos = this.node.worldPosition;
+            
+            console.log('子弹位置:', currentPos);
+            console.log('目标敌人位置:', targetPos);
+            
+            this.direction = targetPos.subtract(currentPos).normalize();
+            console.log('计算出的发射方向:', this.direction);
+        } catch (error) {
+            console.error('❌ 计算子弹方向时出错:', error);
+            // 备用方案:随机方向
+            const randomAngle = Math.random() * Math.PI * 2;
+            this.direction = new Vec3(Math.cos(randomAngle), Math.sin(randomAngle), 0);
+            console.log('使用备用随机方向:', this.direction);
+        }
     }
 
     // 更新子弹速度方向
     updateVelocity() {
-        if (!this.rigidBody) return;
+        if (!this.rigidBody) {
+            console.error('❌ 刚体组件不存在,无法设置速度');
+            return;
+        }
+        
+        if (!this.direction) {
+            console.error('❌ 子弹方向未设置,无法更新速度');
+            return;
+        }
+        
+        // 确保方向向量已归一化
+        const normalizedDirection = this.direction.clone().normalize();
+        
+        // 计算速度向量
+        const velocity = new Vec2(
+            normalizedDirection.x * this.speed,
+            normalizedDirection.y * this.speed
+        );
+        
+        console.log('🎯 设置子弹速度:', {
+            direction: normalizedDirection,
+            speed: this.speed,
+            velocity: velocity
+        });
+        
+        // 强制设置速度
+        this.rigidBody.linearVelocity = velocity;
+        
+        // 立即验证速度是否设置成功
+        const actualVelocity = this.rigidBody.linearVelocity;
+        const actualSpeed = Math.sqrt(actualVelocity.x * actualVelocity.x + actualVelocity.y * actualVelocity.y);
         
-        // 使用初始方向,不追踪敌人
-        if (this.direction) {
-            // 设置速度
-            this.rigidBody.linearVelocity = new Vec2(
-                this.direction.x * this.speed,
-                this.direction.y * this.speed
-            );
+        console.log('✅ 子弹速度验证:', {
+            设置的速度: velocity,
+            实际速度: actualVelocity,
+            速度大小: actualSpeed.toFixed(2)
+        });
+        
+        if (Math.abs(actualSpeed - this.speed) > 10) {
+            console.warn('⚠️ 速度设置可能失败,实际速度与期望不符');
+            // 尝试再次设置
+            this.scheduleOnce(() => {
+                this.rigidBody.linearVelocity = velocity;
+                console.log('🔄 重新设置子弹速度');
+            }, 0.01);
         }
     }
 
@@ -106,17 +348,136 @@ export class BulletController extends Component {
     onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
         const otherNode = otherCollider.node;
         
-        // 检查是否击中敌人
-        if (otherNode.name === 'Enemy') {
-            // 对敌人造成伤害
-            const enemyController = find('Canvas/GameLevelUI/EnemyController')?.getComponent('EnemyController') as any;
-            if (enemyController) {
-                enemyController.damageEnemy(otherNode, this.damage);
-            }
+        console.log('💥 子弹发生碰撞:', {
+            子弹: selfCollider.node.name,
+            碰撞对象: otherNode.name,
+            碰撞对象路径: this.getNodePath(otherNode),
+            碰撞组: otherCollider.group
+        });
+        
+        // 检查是否击中敌人 - 使用更灵活的匹配条件
+        const isEnemy = this.isEnemyNode(otherNode);
+        
+        if (isEnemy) {
+            console.log('🎯 子弹击中敌人:', otherNode.name);
+            
+            // 尝试对敌人造成伤害
+            this.damageEnemy(otherNode);
             
             // 销毁子弹
+            console.log('💥 子弹击中目标,即将销毁');
             this.node.destroy();
+        } else {
+            console.log('🚫 子弹击中非敌人对象:', otherNode.name);
+            // 如果击中墙体或其他障碍物,也销毁子弹
+            if (otherNode.name.includes('Wall') || otherNode.name.includes('wall')) {
+                console.log('🧱 子弹击中墙体,销毁子弹');
+                this.node.destroy();
+            }
+        }
+    }
+    
+    // 判断节点是否为敌人
+    private isEnemyNode(node: Node): boolean {
+        const name = node.name.toLowerCase();
+        const hasEnemyComponent = node.getComponent('EnemyInstance') !== null || 
+                                node.getComponent('EnemyComponent') !== null;
+        
+        const isEnemyByName = name === 'enemy' || 
+                             name.includes('enemy') ||
+                             name.includes('敌人') ||
+                             name.startsWith('enemy') ||
+                             name.endsWith('enemy');
+        
+        console.log('🔍 敌人判定:', {
+            节点名称: node.name,
+            名称匹配: isEnemyByName,
+            组件匹配: hasEnemyComponent,
+            最终判定: isEnemyByName || hasEnemyComponent
+        });
+        
+        return isEnemyByName || hasEnemyComponent;
+    }
+    
+    // 对敌人造成伤害
+    private damageEnemy(enemyNode: Node) {
+        console.log('⚔️ 开始对敌人造成伤害:', enemyNode.name);
+        
+        // 方法1: 尝试通过EnemyController造成伤害
+        const enemyController = find('Canvas/GameLevelUI/EnemyController')?.getComponent('EnemyController') as any;
+        if (enemyController && typeof enemyController.damageEnemy === 'function') {
+            try {
+                enemyController.damageEnemy(enemyNode, this.damage);
+                console.log('✅ 通过EnemyController造成伤害:', this.damage);
+                return;
+            } catch (error) {
+                console.error('❌ EnemyController.damageEnemy调用失败:', error);
+            }
+        }
+        
+        // 方法2: 尝试直接调用敌人组件的受伤方法
+        const enemyInstance = enemyNode.getComponent('EnemyInstance') as any;
+        if (enemyInstance) {
+            if (typeof enemyInstance.takeDamage === 'function') {
+                try {
+                    enemyInstance.takeDamage(this.damage);
+                    console.log('✅ 通过EnemyInstance.takeDamage造成伤害:', this.damage);
+                    return;
+                } catch (error) {
+                    console.error('❌ EnemyInstance.takeDamage调用失败:', error);
+                }
+            }
+            
+            if (typeof enemyInstance.damage === 'function') {
+                try {
+                    enemyInstance.damage(this.damage);
+                    console.log('✅ 通过EnemyInstance.damage造成伤害:', this.damage);
+                    return;
+                } catch (error) {
+                    console.error('❌ EnemyInstance.damage调用失败:', error);
+                }
+            }
+        }
+        
+        // 方法3: 尝试其他可能的敌人组件
+        const enemyComponent = enemyNode.getComponent('EnemyComponent') as any;
+        if (enemyComponent && typeof enemyComponent.takeDamage === 'function') {
+            try {
+                enemyComponent.takeDamage(this.damage);
+                console.log('✅ 通过EnemyComponent.takeDamage造成伤害:', this.damage);
+                return;
+            } catch (error) {
+                console.error('❌ EnemyComponent.takeDamage调用失败:', error);
+            }
+        }
+        
+        // 方法4: 简单的生命值减少(如果敌人有health属性)
+        if (enemyInstance && typeof enemyInstance.health === 'number') {
+            enemyInstance.health -= this.damage;
+            console.log('✅ 直接减少敌人生命值:', {
+                伤害: this.damage,
+                剩余生命: enemyInstance.health
+            });
+            
+            // 如果生命值归零,尝试销毁敌人
+            if (enemyInstance.health <= 0) {
+                console.log('💀 敌人生命值归零,尝试销毁');
+                if (typeof enemyInstance.die === 'function') {
+                    enemyInstance.die();
+                } else {
+                    enemyNode.destroy();
+                }
+            }
+            return;
         }
+        
+        console.warn('⚠️ 无法找到合适的方法对敌人造成伤害');
+        console.log('敌人节点信息:', {
+            name: enemyNode.name,
+            components: enemyNode.components.map(c => c.constructor.name),
+            EnemyInstance: !!enemyNode.getComponent('EnemyInstance'),
+            EnemyComponent: !!enemyNode.getComponent('EnemyComponent')
+        });
     }
 
     update(dt: number) {
@@ -127,6 +488,45 @@ export class BulletController extends Component {
             return;
         }
         
+        // 定期检查速度是否正确(每0.1秒检查一次)
+        if (this.rigidBody && this.direction) {
+            const currentVelocity = this.rigidBody.linearVelocity;
+            const currentSpeed = Math.sqrt(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y);
+            
+            // 如果速度过低,重新设置
+            if (currentSpeed < this.speed * 0.8) {
+                console.log('🔧 检测到子弹速度过低,重新设置...');
+                this.updateVelocity();
+            }
+        }
+        
         // 注意:不再每帧更新速度方向,子弹将沿初始方向直线移动
     }
+
+    // 调试碰撞组信息
+    private debugCollisionGroups() {
+        const iconNode = this.node.getChildByName('Icon');
+        if (iconNode) {
+            const collider = iconNode.getComponent(Collider2D);
+            const rigidBody = iconNode.getComponent(RigidBody2D);
+            
+            console.log('🔧 子弹碰撞组调试信息:', {
+                节点名称: iconNode.name,
+                碰撞体组: collider?.group,
+                刚体组: rigidBody?.group,
+                预期组: 3, // BULLET组
+                组名: 'BULLET'
+            });
+            
+            // 检查碰撞矩阵
+            const bulletGroup = 3; // BULLET
+            const enemyGroup = 4;  // ENEMY
+            
+            console.log('🎯 碰撞组配置:', {
+                子弹组: bulletGroup,
+                敌人组: enemyGroup,
+                提示: '子弹组3应该能与敌人组4碰撞'
+            });
+        }
+    }
 } 

+ 0 - 26
assets/scripts/CombatSystem/EnemyInstance.ts

@@ -215,32 +215,6 @@ export class EnemyInstance extends Component {
         this.node.position = newPos;
     }
 
-    // 检查是否接近墙体
-    private checkNearWalls(): boolean {
-        const currentPos = this.node.worldPosition;
-        
-        // 查找所有墙体节点
-        const gameArea = find('Canvas/GameLevelUI/GameArea');
-        if (!gameArea) return false;
-        
-        for (let i = 0; i < gameArea.children.length; i++) {
-            const wall = gameArea.children[i];
-            if (wall.name.includes('Wall') || wall.name.includes('Fence') || wall.name.includes('Jiguang')) {
-                const wallPos = wall.worldPosition;
-                const distance = Vec3.distance(currentPos, wallPos);
-                
-                // 如果距离墙体很近,切换到攻击状态
-                if (distance < 100) { // 100像素内算接近
-                    this.state = EnemyState.ATTACKING;
-                    this.attackTimer = this.attackInterval; // 重置攻击计时器
-                    return true;
-                }
-            }
-        }
-        
-        return false;
-    }
-
     // 更新攻击逻辑
     private updateAttack(deltaTime: number) {
         this.attackTimer -= deltaTime;

+ 1 - 1
settings/v2/packages/engine.json

@@ -83,7 +83,7 @@
             "_option": "physics-2d-box2d"
           },
           "physics-2d-box2d": {
-            "_value": false
+            "_value": true
           },
           "physics-2d-box2d-wasm": {
             "_value": false,