Browse Source

武器配置

181404010226 5 months ago
parent
commit
fddb4aabfe

File diff suppressed because it is too large
+ 294 - 119
assets/Scenes/GameLevel.scene


+ 78 - 96
assets/Scenes/TestScene.scene

@@ -52,7 +52,7 @@
     },
     "autoReleaseAssets": false,
     "_globals": {
-      "__id__": 21
+      "__id__": 20
     },
     "_id": "8a125a67-dbc5-4c64-b398-6a616deee4aa"
   },
@@ -75,19 +75,19 @@
         "__id__": 8
       },
       {
-        "__id__": 13
+        "__id__": 10
       }
     ],
     "_active": true,
     "_components": [
       {
-        "__id__": 18
+        "__id__": 17
       },
       {
-        "__id__": 19
+        "__id__": 18
       },
       {
-        "__id__": 20
+        "__id__": 19
       }
     ],
     "_prefab": null,
@@ -306,9 +306,6 @@
     "_components": [
       {
         "__id__": 9
-      },
-      {
-        "__id__": 10
       }
     ],
     "_prefab": null,
@@ -363,58 +360,26 @@
     },
     "_id": "cfovpox/1MQpypNWWd/J2W"
   },
-  {
-    "__type__": "a1dbdMCaOlLT7IfSw8CWYSU",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 8
-    },
-    "_enabled": true,
-    "__prefab": null,
-    "enemySpawner": {
-      "__id__": 11
-    },
-    "_id": "7bOZebTPRGjIytzSqQJ/Lx"
-  },
-  {
-    "__type__": "a2aacTp735IXaXYFWfbU79J",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 12
-    },
-    "_enabled": true,
-    "__prefab": null,
-    "enemyPrefab": {
-      "__uuid__": "b66f02ce-3078-432b-b943-3122a7221095",
-      "__expectedType__": "cc.Prefab"
-    },
-    "enemyContainer": {
-      "__id__": 14
-    },
-    "spawnInterval": 2,
-    "maxEnemies": 10,
-    "_id": "4fP0IhzAhMD5YH126vW0rr"
-  },
   {
     "__type__": "cc.Node",
-    "_name": "EnemySpawner",
+    "_name": "EnemyTest",
     "_objFlags": 0,
     "__editorExtras__": {},
     "_parent": {
-      "__id__": 13
+      "__id__": 2
     },
-    "_children": [],
-    "_active": true,
-    "_components": [
+    "_children": [
       {
-        "__id__": 17
+        "__id__": 11
       },
       {
-        "__id__": 11
+        "__id__": 14
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 16
       }
     ],
     "_prefab": null,
@@ -445,28 +410,24 @@
       "y": 0,
       "z": 0
     },
-    "_id": "8btBfVaMlG4YEWLd16PofE"
+    "_id": "aaEqR4mG1BepRJ//DnLaQ1"
   },
   {
     "__type__": "cc.Node",
-    "_name": "EnemyTest",
+    "_name": "Weapon",
     "_objFlags": 0,
     "__editorExtras__": {},
     "_parent": {
-      "__id__": 2
+      "__id__": 10
     },
-    "_children": [
+    "_children": [],
+    "_active": true,
+    "_components": [
       {
         "__id__": 12
       },
       {
-        "__id__": 14
-      }
-    ],
-    "_active": true,
-    "_components": [
-      {
-        "__id__": 16
+        "__id__": 13
       }
     ],
     "_prefab": null,
@@ -497,15 +458,58 @@
       "y": 0,
       "z": 0
     },
-    "_id": "aaEqR4mG1BepRJ//DnLaQ1"
+    "_id": "8btBfVaMlG4YEWLd16PofE"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 11
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 100
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "8fJ0ObZ6tPgoXdZ4uQqk3K"
+  },
+  {
+    "__type__": "a2aacTp735IXaXYFWfbU79J",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 11
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "enemyPrefab": {
+      "__uuid__": "b66f02ce-3078-432b-b943-3122a7221095",
+      "__expectedType__": "cc.Prefab"
+    },
+    "enemyContainer": {
+      "__id__": 14
+    },
+    "spawnInterval": 2,
+    "maxEnemies": 10,
+    "_id": "19KmKeAU9I+Yx+v9agD69e"
   },
   {
     "__type__": "cc.Node",
-    "_name": "EnemyContainer",
+    "_name": "WeaponContainer",
     "_objFlags": 0,
     "__editorExtras__": {},
     "_parent": {
-      "__id__": 13
+      "__id__": 10
     },
     "_children": [],
     "_active": true,
@@ -572,7 +576,7 @@
     "_objFlags": 0,
     "__editorExtras__": {},
     "node": {
-      "__id__": 13
+      "__id__": 10
     },
     "_enabled": true,
     "__prefab": null,
@@ -588,28 +592,6 @@
     },
     "_id": "ce8uIBet1JdoKaW95g6Cxw"
   },
-  {
-    "__type__": "cc.UITransform",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 12
-    },
-    "_enabled": true,
-    "__prefab": null,
-    "_contentSize": {
-      "__type__": "cc.Size",
-      "width": 100,
-      "height": 100
-    },
-    "_anchorPoint": {
-      "__type__": "cc.Vec2",
-      "x": 0.5,
-      "y": 0.5
-    },
-    "_id": "8fJ0ObZ6tPgoXdZ4uQqk3K"
-  },
   {
     "__type__": "cc.UITransform",
     "_name": "",
@@ -681,28 +663,28 @@
   {
     "__type__": "cc.SceneGlobals",
     "ambient": {
-      "__id__": 22
+      "__id__": 21
     },
     "shadows": {
-      "__id__": 23
+      "__id__": 22
     },
     "_skybox": {
-      "__id__": 24
+      "__id__": 23
     },
     "fog": {
-      "__id__": 25
+      "__id__": 24
     },
     "octree": {
-      "__id__": 26
+      "__id__": 25
     },
     "skin": {
-      "__id__": 27
+      "__id__": 26
     },
     "lightProbeInfo": {
-      "__id__": 28
+      "__id__": 27
     },
     "postSettings": {
-      "__id__": 29
+      "__id__": 28
     },
     "bakedWithStationaryMainLight": false,
     "bakedWithHighpLightmap": false

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

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

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

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

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

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

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

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

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

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

+ 2 - 1
assets/assets/Prefabs/WeaponBlock.prefab

@@ -572,6 +572,7 @@
       "__id__": 0
     },
     "fileId": "2fgmWEQyhIGr02gKDR/YNr",
-    "instance": null
+    "instance": null,
+    "targetOverrides": null
   }
 ]

+ 168 - 45
assets/scripts/CombatSystem/BallController.ts

@@ -1,5 +1,6 @@
 import { _decorator, Component, Node, Vec2, Vec3, UITransform, Collider2D, Contact2DType, IPhysics2DContact, RigidBody2D, Prefab, instantiate, find, CircleCollider2D, PhysicsSystem2D } from 'cc';
 import { BulletController } from './BulletController';
+import { WeaponBlockExample } from './WeaponBlockExample';
 const { ccclass, property } = _decorator;
 
 @ccclass('BallController')
@@ -11,6 +12,13 @@ export class BallController extends Component {
     })
     public ballPrefab: Prefab = null;
 
+    // 已放置方块容器节点
+    @property({
+        type: Node,
+        tooltip: '拖拽PlacedBlocks节点到这里(Canvas/GameLevelUI/PlacedBlocks)'
+    })
+    public placedBlocksContainer: Node = null;
+
     // 球的移动速度
     @property
     public speed: number = 10;
@@ -46,31 +54,26 @@ export class BallController extends Component {
     })
     public bulletPrefab: Prefab = null;
 
+    // 小球是否已开始运动
+    private ballStarted: boolean = false;
+
     start() {
-        console.log('🎮 === BallController 开始初始化 ===');
-        
-        // 计算游戏边界
-        this.calculateGameBounds();
-        
-        // 检查子弹预制体是否已设置
-        if (this.bulletPrefab) {
-            console.log('✅ 子弹预制体已设置:', this.bulletPrefab.name);
-        } else {
-            console.error('❌ 子弹预制体未设置!请在编辑器中设置bulletPrefab属性');
-            console.error('⚠️  这将导致小球碰撞方块时无法发射子弹');
-        }
-        
-        // 检查小球预制体是否已设置
-        if (this.ballPrefab) {
-            console.log('✅ 小球预制体已设置:', this.ballPrefab.name);
-        } else {
-            console.error('❌ 小球预制体未设置!请在编辑器中设置ballPrefab属性');
+        // 如果没有指定placedBlocksContainer,尝试找到它
+        if (!this.placedBlocksContainer) {
+            this.placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks');
+            if (!this.placedBlocksContainer) {
+                console.warn('找不到PlacedBlocks节点,某些功能可能无法正常工作');
+            }
         }
         
-        console.log('🎮 === BallController 初始化完成 ===');
+        // 只进行初始设置,不创建小球
+        console.log('🎮 BallController 已准备就绪,等待确定按钮触发');
+        this.calculateGameBounds();
         
-        // 输出碰撞矩阵调试信息
-        this.logCollisionMatrix();
+        // 延迟执行一些检查方法,但不创建小球
+        this.scheduleOnce(() => {
+            this.logCollisionMatrix();
+        }, 1.0);
     }
 
     // 计算游戏边界(使用GameArea节点)
@@ -144,17 +147,15 @@ export class BallController extends Component {
         // 确保有碰撞组件
         this.setupCollider();
 
-        // 初始化方向
-        this.initializeDirection();
-
-        // 检查方块碰撞体状态
-        this.checkBlockColliders();
+        // 注意:不在这里初始化方向,等待 startBall() 调用
+        console.log('⏸️ 小球已创建但暂未开始运动,等待启动指令');
 
         this.initialized = true;
         console.log('小球创建完成:', {
             position: this.activeBall.position,
             radius: this.radius,
-            initialized: this.initialized
+            initialized: this.initialized,
+            hasMovement: false // 表示尚未开始运动
         });
     }
 
@@ -162,15 +163,19 @@ export class BallController extends Component {
     private checkBlockColliders() {
         console.log('🔍 === 检查方块碰撞体组件 ===');
         
-        const placedBlocksContainer = find('Canvas/PlacedBlocks');
-        if (!placedBlocksContainer) {
-            console.log('❌ 找不到PlacedBlocks容器');
+        if (!this.placedBlocksContainer) {
+            console.log('❌ PlacedBlocks容器未设置');
+            return;
+        }
+        
+        if (!this.placedBlocksContainer.isValid) {
+            console.log('❌ PlacedBlocks容器已失效');
             return;
         }
         
         const blocks = [];
-        for (let i = 0; i < placedBlocksContainer.children.length; i++) {
-            const block = placedBlocksContainer.children[i];
+        for (let i = 0; i < this.placedBlocksContainer.children.length; i++) {
+            const block = this.placedBlocksContainer.children[i];
             if (block.name.includes('Block') || block.getChildByName('B1')) {
                 blocks.push(block);
             }
@@ -270,17 +275,22 @@ export class BallController extends Component {
         }
         
         // 查找PlacedBlocks节点,它包含所有放置的方块
-        const placedBlocksContainer = find('Canvas/PlacedBlocks');
-        if (!placedBlocksContainer) {
+        if (!this.placedBlocksContainer) {
             console.log('找不到PlacedBlocks节点,使用默认随机位置');
             this.setRandomPositionDefault(minX, maxX, minY, maxY);
             return;
         }
         
+        if (!this.placedBlocksContainer.isValid) {
+            console.log('PlacedBlocks容器已失效,使用默认随机位置');
+            this.setRandomPositionDefault(minX, maxX, minY, maxY);
+            return;
+        }
+        
         // 获取所有已放置的方块
         const placedBlocks = [];
-        for (let i = 0; i < placedBlocksContainer.children.length; i++) {
-            const block = placedBlocksContainer.children[i];
+        for (let i = 0; i < this.placedBlocksContainer.children.length; i++) {
+            const block = this.placedBlocksContainer.children[i];
             // 检查是否是方块节点(通常以Block命名或有特定标识)
             if (block.name.includes('Block') || block.getChildByName('B1')) {
                 placedBlocks.push(block);
@@ -521,7 +531,19 @@ export class BallController extends Component {
         if (isBlock) {
             console.log(`🎯 检测到方块碰撞: ${nodeName}, 路径: ${nodePath}`);
             console.log('🚀 方块武器被激活,发射子弹攻击敌人...');
-            this.fireBullet(blockNode);
+            // 计算碰撞世界坐标,默认用接触点
+            let contactPos: Vec3 = null;
+            if (contact && (contact as any).getWorldManifold) {
+                const wm = (contact as any).getWorldManifold();
+                if (wm && wm.points && wm.points.length > 0) {
+                    contactPos = new Vec3(wm.points[0].x, wm.points[0].y, 0);
+                }
+            }
+            if (!contactPos) {
+                contactPos = blockNode.worldPosition.clone();
+            }
+
+            this.fireBulletAt(blockNode, contactPos);
             console.log('✅ 子弹发射完成');
         }
     }
@@ -694,6 +716,13 @@ export class BallController extends Component {
         }
         console.log('✅ 获取到子弹控制器组件');
         
+        // 设置全局子弹速度(如果 WeaponBlockExample 提供)
+        const weaponExampleInstance = WeaponBlockExample.getInstance();
+        if (weaponExampleInstance) {
+            bulletController.speed = weaponExampleInstance.getCurrentBulletSpeed();
+            console.log('⚙️ 应用全局子弹速度:', bulletController.speed);
+        }
+        
         // 设置发射位置
         bulletController.setFirePosition(firePosition);
         
@@ -782,9 +811,10 @@ export class BallController extends Component {
     }
 
     update(dt: number) {
-        // 小球速度保持不变,无需检测速度衰减
-        // 物理引擎通过刚体组件的零阻尼设置来维持恒定速度
-        if (!this.initialized || !this.activeBall || !this.activeBall.isValid) return;
+        // 只有当小球已启动时才执行运动逻辑
+        if (!this.ballStarted || !this.initialized || !this.activeBall || !this.activeBall.isValid) {
+            return;
+        }
         
         // 使用刚体组件控制小球移动,而不是直接设置位置
         const rigidBody = this.activeBall.getComponent(RigidBody2D);
@@ -820,14 +850,13 @@ export class BallController extends Component {
         if (this.debugCheckCounter % 60 !== 0) return;
         
         const ballPos = this.activeBall.worldPosition;
-        const placedBlocksContainer = find('Canvas/PlacedBlocks');
-        if (!placedBlocksContainer) return;
+        if (!this.placedBlocksContainer || !this.placedBlocksContainer.isValid) return;
         
         let nearestDistance = Infinity;
         let nearestBlock = null;
         
-        for (let i = 0; i < placedBlocksContainer.children.length; i++) {
-            const block = placedBlocksContainer.children[i];
+        for (let i = 0; i < this.placedBlocksContainer.children.length; i++) {
+            const block = this.placedBlocksContainer.children[i];
             if (block.name.includes('Block') || block.getChildByName('B1')) {
                 const blockPos = block.worldPosition;
                 const distance = Math.sqrt(
@@ -952,9 +981,48 @@ export class BallController extends Component {
     }
 
     // 初始化球的参数 - 公开方法,供GameManager调用
-    initialize() {
+    public initialize() {
+        console.log('🎮 === BallController 初始化 ===');
         this.calculateGameBounds();
         this.createBall();
+        
+        // 检查方块碰撞体(延迟执行,确保方块已放置)
+        this.scheduleOnce(() => {
+            this.checkBlockColliders();
+        }, 0.5);
+        
+        console.log('🎮 === BallController 初始化完成 ===');
+    }
+    
+    // 启动小球 - 公开方法,在确定按钮点击后调用
+    public startBall() {
+        console.log('🚀 === 启动小球系统 ===');
+        
+        // 如果还没有初始化,先初始化
+        if (!this.initialized) {
+            this.initialize();
+        }
+        
+        // 确保小球存在且有效
+        if (!this.activeBall || !this.activeBall.isValid) {
+            console.log('⚠️ 小球不存在,重新创建...');
+            this.createBall();
+        }
+        
+        // 重新定位小球,避免与方块重叠
+        console.log('📍 重新定位小球位置...');
+        this.positionBallRandomly();
+        
+        // 确保物理组件设置正确
+        this.setupCollider();
+        
+        // 初始化运动方向并开始运动
+        this.initializeDirection();
+        
+        // 设置运动状态
+        this.ballStarted = true;
+        
+        console.log('🚀 === 小球系统启动完成,开始运动 ===');
     }
 
     // 输出碰撞矩阵调试信息
@@ -989,4 +1057,59 @@ export class BallController extends Component {
         console.log(`双向碰撞可用: ${ballCanCollideWithBlock && blockCanCollideWithBall}`);
         console.log('🔍 === 碰撞矩阵分析完成 ===');
     }
+
+    /**
+     * 从给定世界坐标发射子弹
+     */
+    private fireBulletAt(blockNode: Node, fireWorldPos: Vec3) {
+        console.log('🔫 === 方块武器发射子弹流程 ===');
+        console.log('激活的方块:', blockNode.name);
+        console.log('方块路径:', this.getNodePath(blockNode));
+        
+        // 检查子弹预制体是否存在
+        if (!this.bulletPrefab) {
+            console.error('❌ 子弹预制体未设置');
+            return;
+        }        
+        
+        // 查找方块中的Weapon节点
+        console.log('🔍 开始查找方块中的Weapon节点...');
+        const weaponNode = this.findWeaponNode(blockNode);
+        if (!weaponNode) {
+            console.error('❌ 在方块中找不到Weapon节点:', blockNode.name);
+            console.log('方块结构:');
+            this.logNodeStructure(blockNode, 0);
+            
+            // 如果找不到Weapon节点,使用方块本身的位置作为发射位置
+            console.log('🔧 使用方块本身作为发射位置');
+            console.log('方块世界坐标:', fireWorldPos);
+            
+            // 直接创建子弹并设置位置
+            this.createAndFireBullet(fireWorldPos);
+            
+            console.log('🔫 === 方块武器发射子弹流程结束 ===');
+            return;
+        }
+        
+        console.log('✅ 找到Weapon节点:', weaponNode.name);
+        console.log('Weapon节点路径:', this.getNodePath(weaponNode));
+        
+        // 获取武器的世界坐标作为发射位置
+        let firePosition: Vec3;
+        try {
+            firePosition = weaponNode.worldPosition;
+            console.log('武器世界坐标:', firePosition);
+        } catch (error) {
+            console.error('❌ 获取武器坐标失败:', error);
+            // 备用方案:使用方块坐标
+            firePosition = fireWorldPos;
+            console.log('使用方块坐标作为备用:', firePosition);
+        }
+        
+        // 创建并发射子弹
+        console.log('🚀 创建子弹...');
+        this.createAndFireBullet(firePosition);
+        
+        console.log('🔫 === 方块武器发射子弹流程结束 ===');
+    }
 } 

+ 253 - 24
assets/scripts/CombatSystem/BlockManager.ts

@@ -1,4 +1,5 @@
-import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Vec2, UITransform, find, Rect, Label, Color, Size } from 'cc';
+import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Vec2, UITransform, find, Rect, Label, Color, Size, Sprite, SpriteFrame, resources } from 'cc';
+import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
 const { ccclass, property } = _decorator;
 
 @ccclass('BlockManager')
@@ -28,6 +29,13 @@ export class BlockManager extends Component {
     })
     public coinLabelNode: Node = null;
     
+    // 已放置方块容器节点
+    @property({
+        type: Node,
+        tooltip: '拖拽PlacedBlocks节点到这里(Canvas/GameLevelUI/PlacedBlocks)'
+    })
+    public placedBlocksContainer: Node = null;
+    
     // 游戏是否已开始
     public gameStarted: boolean = false;
     
@@ -75,6 +83,12 @@ export class BlockManager extends Component {
     private blockCooldowns: Map<Node, number> = new Map(); // 存储每个方块的冷却结束时间
     private globalCooldownEndTime: number = 0; // 全局冷却结束时间
     
+    // 配置管理器
+    private configManager: ConfigManager = null;
+    
+    // 方块武器配置映射
+    private blockWeaponConfigs: Map<Node, WeaponConfig> = new Map();
+    
     // 检查方块是否可以移动(冷却检查)
     private canMoveBlock(block: Node): boolean {
         if (!this.gameStarted) {
@@ -114,6 +128,12 @@ export class BlockManager extends Component {
     }
 
     start() {
+        // 获取配置管理器
+        this.configManager = ConfigManager.getInstance();
+        if (!this.configManager) {
+            console.error('无法获取ConfigManager实例');
+        }
+
         // 如果没有指定GridContainer,尝试找到它
         if (!this.gridContainer) {
             this.gridContainer = find('Canvas/GameLevelUI/GameArea/GridContainer');
@@ -141,6 +161,14 @@ export class BlockManager extends Component {
             }
         }
         
+        // 如果没有指定placedBlocksContainer,尝试找到它
+        if (!this.placedBlocksContainer) {
+            this.placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks');
+            if (!this.placedBlocksContainer) {
+                console.warn('找不到PlacedBlocks节点,将尝试创建');
+            }
+        }
+        
         // 确保有PlacedBlocks节点用于存放已放置的方块
         this.ensurePlacedBlocksNode();
         
@@ -153,27 +181,39 @@ export class BlockManager extends Component {
         // 初始化网格占用情况
         this.initGridOccupationMap();
         
-        // 在kuang下随机生成三个方块
-        this.generateRandomBlocksInKuang();
+        // 等待配置加载完成后生成方块
+        this.scheduleOnce(() => {
+            this.generateRandomBlocksInKuang();
+        }, 0.5);
     }
     
     // 确保有PlacedBlocks节点
     ensurePlacedBlocksNode() {
-        const canvas = find('Canvas');
-        if (!canvas) {
-            console.error('找不到Canvas节点');
+        // 如果已经通过拖拽设置了节点,直接使用
+        if (this.placedBlocksContainer && this.placedBlocksContainer.isValid) {
             return;
         }
         
-        let placedBlocksNode = find('Canvas/PlacedBlocks');
-        if (!placedBlocksNode) {
-            placedBlocksNode = new Node('PlacedBlocks');
-            canvas.addChild(placedBlocksNode);
-            if (!placedBlocksNode.getComponent(UITransform)) {
-                placedBlocksNode.addComponent(UITransform);
-            }
-            console.log('已创建PlacedBlocks节点');
+        // 尝试查找节点
+        this.placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks');
+        if (this.placedBlocksContainer) {
+            console.log('找到已存在的PlacedBlocks节点');
+            return;
+        }
+        
+        // 如果找不到,创建新节点
+        const gameLevelUI = find('Canvas/GameLevelUI');
+        if (!gameLevelUI) {
+            console.error('找不到GameLevelUI节点,无法创建PlacedBlocks');
+            return;
+        }
+        
+        this.placedBlocksContainer = new Node('PlacedBlocks');
+        gameLevelUI.addChild(this.placedBlocksContainer);
+        if (!this.placedBlocksContainer.getComponent(UITransform)) {
+            this.placedBlocksContainer.addComponent(UITransform);
         }
+        console.log('已在GameLevelUI下创建PlacedBlocks节点');
     }
     
     // 初始化网格信息
@@ -227,6 +267,15 @@ export class BlockManager extends Component {
     private generateRandomBlocksInKuang() {
         this.clearBlocks();
         
+        // 检查配置管理器是否可用
+        if (!this.configManager || !this.configManager.isConfigLoaded()) {
+            console.warn('配置管理器未初始化或配置未加载完成,延迟生成方块');
+            this.scheduleOnce(() => {
+                this.generateRandomBlocksInKuang();
+            }, 1.0);
+            return;
+        }
+        
         if (this.blockPrefabs.length === 0) {
             console.error('没有可用的预制体');
             return;
@@ -250,14 +299,20 @@ export class BlockManager extends Component {
             kuangNode.getChildByName('db03')
         ];
         
-        console.log('开始在kuang容器中生成随机方块');
+        console.log('开始在kuang容器中生成随机武器方块');
         
         for (let i = 0; i < 3; i++) {
-            const randomIndex = Math.floor(Math.random() * this.blockPrefabs.length);
-            const prefab = this.blockPrefabs[randomIndex];
+            // 获取随机武器配置
+            const weaponConfig = this.configManager.getRandomWeapon();
+            if (!weaponConfig) {
+                console.error(`无法获取第 ${i + 1} 个武器配置`);
+                continue;
+            }
             
+            // 基于武器配置选择合适的预制体
+            const prefab = this.selectPrefabForWeapon(weaponConfig);
             if (!prefab) {
-                console.error(`方块预制体索引 ${randomIndex} 无效`);
+                console.error(`无法为武器 ${weaponConfig.name} 选择合适的预制体`);
                 continue;
             }
             
@@ -266,6 +321,14 @@ export class BlockManager extends Component {
             
             block.position = offsets[i];
             
+            // 设置方块名称
+            block.name = `WeaponBlock_${weaponConfig.id}`;
+            
+            // 保存武器配置到方块
+            this.blockWeaponConfigs.set(block, weaponConfig);
+            block['weaponConfig'] = weaponConfig;
+            block['weaponId'] = weaponConfig.id;
+            
             this.originalPositions.set(block, offsets[i].clone());
             this.blockLocations.set(block, 'kuang');
             this.blocks.push(block);
@@ -275,17 +338,23 @@ export class BlockManager extends Component {
                 if (priceNode) {
                     this.blockPriceMap.set(block, priceNode);
                     priceNode.active = true;
+                    
+                    // 根据武器稀有度设置价格
+                    this.setBlockPriceByRarity(priceNode, weaponConfig.rarity);
                 }
                 
                 this.associateDbNodeWithBlock(block, dbNodes[i]);
             }
             
+            // 设置方块的武器外观
+            this.setupBlockWeaponVisual(block, weaponConfig);
+            
             this.setupDragEvents(block);
             
-            console.log(`生成方块 ${i + 1}/3: ${prefab.name} 在位置 (${offsets[i].x.toFixed(2)}, ${offsets[i].y.toFixed(2)})`);
+            console.log(`✅ 生成武器方块 ${i + 1}/3: ${weaponConfig.name} (${weaponConfig.rarity}) 在位置 (${offsets[i].x.toFixed(2)}, ${offsets[i].y.toFixed(2)})`);
         }
         
-        console.log(`成功在kuang容器中生成了 ${this.blocks.length} 个方块`);
+        console.log(`🎉 成功在kuang容器中生成了 ${this.blocks.length} 个武器方块`);
         this.updateCoinDisplay();
     }
     
@@ -851,6 +920,8 @@ export class BlockManager extends Component {
             this.originalPositions.delete(block);
             this.blockLocations.delete(block);
             this.blockPriceMap.delete(block);
+            // 清理武器配置映射
+            this.blockWeaponConfigs.delete(block);
             
             block.destroy();
         }
@@ -903,9 +974,13 @@ export class BlockManager extends Component {
     
     // 将方块移动到PlacedBlocks节点下
     moveBlockToPlacedBlocks(block: Node) {
-        const placedBlocksNode = find('Canvas/PlacedBlocks');
-        if (!placedBlocksNode) {
-            console.error('找不到PlacedBlocks节点');
+        if (!this.placedBlocksContainer) {
+            console.error('PlacedBlocks容器未设置');
+            return;
+        }
+        
+        if (!this.placedBlocksContainer.isValid) {
+            console.error('PlacedBlocks容器已失效');
             return;
         }
         
@@ -913,8 +988,162 @@ export class BlockManager extends Component {
         block.getWorldPosition(worldPosition);
         
         block.removeFromParent();
-        placedBlocksNode.addChild(block);
+        this.placedBlocksContainer.addChild(block);
         block.setWorldPosition(worldPosition);
+    }
+    
+    // 根据武器配置选择合适的预制体
+    private selectPrefabForWeapon(weaponConfig: WeaponConfig): Prefab | null {
+        if (this.blockPrefabs.length === 0) {
+            return null;
+        }
+        
+        // 根据武器类型或稀有度选择预制体
+        // 这里可以根据实际需求来选择不同的预制体
+        // 目前简单地随机选择一个预制体
+        const randomIndex = Math.floor(Math.random() * this.blockPrefabs.length);
+        return this.blockPrefabs[randomIndex];
+    }
+    
+    // 根据稀有度设置方块价格
+    private setBlockPriceByRarity(priceNode: Node, rarity: string) {
+        const label = priceNode.getComponent(Label);
+        if (!label) {
+            return;
+        }
         
+        let price: number;
+        switch (rarity) {
+            case 'common':
+                price = 50;
+                break;
+            case 'uncommon':
+                price = 100;
+                break;
+            case 'rare':
+                price = 200;
+                break;
+            case 'epic':
+                price = 350;
+                break;
+            case 'legendary':
+                price = 500;
+                break;
+            default:
+                price = 50;
+        }
+        
+        label.string = price.toString();
+    }
+    
+    // 设置方块的武器外观
+    private setupBlockWeaponVisual(block: Node, weaponConfig: WeaponConfig) {
+        // 设置方块的稀有度颜色
+        this.setBlockRarityColor(block, weaponConfig.rarity);
+        
+        // 加载武器图标
+        this.loadWeaponIcon(block, weaponConfig);
+    }
+    
+    // 设置方块稀有度颜色
+    private setBlockRarityColor(block: Node, rarity: string) {
+        const sprite = block.getComponent(Sprite);
+        if (!sprite) {
+            return;
+        }
+        
+        // 根据稀有度设置颜色
+        let color: Color;
+        switch (rarity) {
+            case 'common':
+                color = new Color(255, 255, 255); // 白色
+                break;
+            case 'uncommon':
+                color = new Color(0, 255, 0); // 绿色
+                break;
+            case 'rare':
+                color = new Color(0, 100, 255); // 蓝色
+                break;
+            case 'epic':
+                color = new Color(160, 32, 240); // 紫色
+                break;
+            case 'legendary':
+                color = new Color(255, 165, 0); // 橙色
+                break;
+            default:
+                color = new Color(255, 255, 255); // 默认白色
+        }
+        
+        sprite.color = color;
+    }
+    
+    // 加载武器图标
+    private loadWeaponIcon(block: Node, weaponConfig: WeaponConfig) {
+        // 根据预制体结构:WeaponBlock -> B1 -> Weapon
+        const b1Node = block.getChildByName('B1');
+        if (!b1Node) {
+            console.warn('找不到B1节点');
+            return;
+        }
+        
+        const weaponNode = b1Node.getChildByName('Weapon');
+        if (!weaponNode) {
+            console.warn('找不到Weapon节点');
+            return;
+        }
+        
+        const weaponSprite = weaponNode.getComponent(Sprite);
+        if (!weaponSprite) {
+            console.warn('Weapon节点上没有Sprite组件');
+            return;
+        }
+        
+        // 获取武器配置中的图片路径
+        const spriteConfig = weaponConfig.visualConfig?.weaponSprites;
+        if (!spriteConfig) {
+            console.warn(`武器 ${weaponConfig.name} 没有配置图片信息`);
+            return;
+        }
+        
+        // 选择合适的图片路径(这里默认使用1x1)
+        const spritePath = spriteConfig['1x1'] || spriteConfig['1x2'] || spriteConfig['2x1'] || spriteConfig['2x2'];
+        if (!spritePath) {
+            console.warn(`武器 ${weaponConfig.name} 没有可用的图片路径`);
+            return;
+        }
+        
+        // 正确的SpriteFrame子资源路径
+        const spriteFramePath = `${spritePath}/spriteFrame`;
+        console.log(`正在加载武器图片: ${spriteFramePath}`);
+        
+        // 加载SpriteFrame子资源
+        resources.load(spriteFramePath, SpriteFrame, (err, spriteFrame) => {
+            if (err) {
+                console.warn(`加载武器图片失败: ${spriteFramePath}`, err);
+                return;
+            }
+            
+            if (weaponSprite && spriteFrame) {
+                weaponSprite.spriteFrame = spriteFrame;
+                console.log(`✅ 武器图片加载成功: ${weaponConfig.name} -> ${spriteFramePath}`);
+            }
+        });
+    }
+    
+    // 根据方块获取武器配置
+    public getBlockWeaponConfig(block: Node): WeaponConfig | null {
+        return this.blockWeaponConfigs.get(block) || block['weaponConfig'] || null;
+    }
+    
+    // 获取方块的武器ID
+    public getBlockWeaponId(block: Node): string | null {
+        const weaponConfig = this.getBlockWeaponConfig(block);
+        return weaponConfig ? weaponConfig.id : null;
+    }
+    
+    // 刷新方块 - 重新生成三个新的武器方块
+    public refreshBlocks() {
+        console.log('刷新方块,生成新的武器方块');
+        this.generateRandomBlocksInKuang();
     }
 }

+ 35 - 6
assets/scripts/CombatSystem/EnemyController.ts

@@ -26,6 +26,13 @@ export class EnemyController extends Component {
     })
     public enemyPrefab: Prefab = null;
 
+    // 敌人容器节点
+    @property({
+        type: Node,
+        tooltip: '拖拽enemyContainer节点到这里(Canvas/GameLevelUI/enemyContainer)'
+    })
+    public enemyContainer: Node = null;
+
     // 敌人生成参数
     @property({
         tooltip: '敌人生成间隔(秒)'
@@ -78,10 +85,17 @@ export class EnemyController extends Component {
     private wallNodes: Node[] = [];
 
     // 私有属性
-    private enemyContainer: Node = null;
     private gameManager: any = null;
 
     start() {
+        // 如果没有指定enemyContainer,尝试找到它
+        if (!this.enemyContainer) {
+            this.enemyContainer = find('Canvas/GameLevelUI/enemyContainer');
+            if (!this.enemyContainer) {
+                console.warn('找不到enemyContainer节点,将尝试创建');
+            }
+        }
+        
         // 获取游戏区域边界
         this.calculateGameBounds();
         
@@ -165,16 +179,31 @@ export class EnemyController extends Component {
 
     // 确保enemyContainer节点存在
     ensureEnemyContainer() {
+        // 如果已经通过拖拽设置了节点,直接使用
+        if (this.enemyContainer && this.enemyContainer.isValid) {
+            return;
+        }
+        
+        // 尝试查找节点
+        this.enemyContainer = find('Canvas/GameLevelUI/enemyContainer');
+        if (this.enemyContainer) {
+            console.log('找到已存在的enemyContainer节点');
+            return;
+        }
+        
+        // 如果找不到,创建新节点
         const gameLevelUI = find('Canvas/GameLevelUI');
         if (!gameLevelUI) {
+            console.error('找不到GameLevelUI节点,无法创建enemyContainer');
             return;
         }
-
-        this.enemyContainer = gameLevelUI.getChildByName('enemyContainer');
-        if (!this.enemyContainer) {
-            this.enemyContainer = new Node('enemyContainer');
-            gameLevelUI.addChild(this.enemyContainer);
+        
+        this.enemyContainer = new Node('enemyContainer');
+        gameLevelUI.addChild(this.enemyContainer);
+        if (!this.enemyContainer.getComponent(UITransform)) {
+            this.enemyContainer.addComponent(UITransform);
         }
+        console.log('已在GameLevelUI下创建enemyContainer节点');
     }
 
     // 游戏开始

+ 300 - 1
assets/scripts/CombatSystem/GameStateSetupGuide.md

@@ -138,4 +138,303 @@ A: 确保EnemyController的getCurrentEnemyCount方法正常工作
 A: 检查LevelManager和ShopManager是否正确初始化为单例
 
 **Q: 找不到GameManager脚本?**
-A: 确保使用的是 `LevelSystem/GameManager.ts` 中的增强版GameManager 
+A: 确保使用的是 `LevelSystem/GameManager.ts` 中的增强版GameManager 
+
+# 武器方块系统集成指南
+
+## 概述
+
+BlockManager 现在已经集成了武器系统,可以根据武器配置生成带有不同武器属性的方块。每个方块都关联一个武器配置,包含武器的视觉效果、属性和战斗参数。
+
+## 主要特性
+
+### 1. 基于武器配置的方块生成
+- 不再随机选择预制体,而是基于武器配置生成方块
+- 每个方块都关联一个随机的武器配置
+- 支持不同稀有度的武器(common, uncommon, rare, epic, legendary)
+
+### 2. 动态价格系统
+- 方块价格根据武器稀有度自动设置
+- 稀有度越高,价格越贵
+- 价格映射:
+  - common: 50 金币
+  - uncommon: 100 金币
+  - rare: 200 金币
+  - epic: 350 金币
+  - legendary: 500 金币
+
+### 3. 视觉效果
+- 方块根据武器稀有度显示不同颜色
+- 自动加载武器图标到方块的 Weapon 子节点
+- 支持多种尺寸的武器图标 (1x1, 1x2, 2x1, 2x2)
+
+### 4. 武器配置访问
+- 每个方块保存完整的武器配置信息
+- 提供公共接口获取方块的武器配置
+- 支持通过武器ID获取配置信息
+
+## 使用方法
+
+### 1. 场景设置
+确保场景中包含以下节点:
+- ConfigManager 实例(自动获取单例)
+- BlockManager 的所有必要引用(GridContainer, kuangContainer, coinLabelNode)
+- 方块预制体数组已正确设置
+
+### 2. 获取方块武器配置
+```typescript
+// 获取方块的武器配置
+const weaponConfig = blockManager.getBlockWeaponConfig(blockNode);
+if (weaponConfig) {
+    console.log(`武器名称: ${weaponConfig.name}`);
+    console.log(`武器类型: ${weaponConfig.type}`);
+    console.log(`武器稀有度: ${weaponConfig.rarity}`);
+    console.log(`武器伤害: ${weaponConfig.stats.damage}`);
+}
+
+// 获取方块的武器ID
+const weaponId = blockManager.getBlockWeaponId(blockNode);
+```
+
+### 3. 刷新方块
+```typescript
+// 重新生成三个新的武器方块
+blockManager.refreshBlocks();
+```
+
+## 方块结构要求
+
+方块预制体应该包含以下结构:
+```
+WeaponBlock (根节点)
+├── B1 (主要方块节点)
+│   └── Weapon (武器图标节点,需要 Sprite 组件)
+└── Price (价格标签节点,可选)
+```
+
+## 武器配置要求
+
+武器配置文件需要包含以下信息:
+- 基本信息:id, name, type, rarity, weight
+- 属性信息:stats (damage, fireRate, range 等)
+- 视觉配置:visualConfig.weaponSprites (包含不同尺寸的图片路径)
+
+## 注意事项
+
+1. **配置加载时机**:方块生成会等待 ConfigManager 加载完成
+2. **预制体兼容性**:确保方块预制体结构符合要求
+3. **资源路径**:武器图标路径应该指向正确的 SpriteFrame 资源
+4. **内存管理**:方块销毁时会自动清理武器配置映射
+
+## 扩展功能
+
+### 1. 自定义预制体选择
+可以修改 `selectPrefabForWeapon` 方法来根据武器类型选择不同的预制体:
+
+```typescript
+private selectPrefabForWeapon(weaponConfig: WeaponConfig): Prefab | null {
+    // 根据武器类型选择预制体
+    switch (weaponConfig.type) {
+        case 'rifle':
+            return this.riflePrefab;
+        case 'pistol':
+            return this.pistolPrefab;
+        default:
+            return this.blockPrefabs[0];
+    }
+}
+```
+
+### 2. 战斗效果集成
+方块放置后,可以通过武器配置来设置战斗效果:
+
+```typescript
+// 在方块放置成功后
+const weaponConfig = this.getBlockWeaponConfig(block);
+if (weaponConfig) {
+    // 设置攻击属性
+    block['attackDamage'] = weaponConfig.stats.damage;
+    block['attackRange'] = weaponConfig.stats.range;
+    block['fireRate'] = weaponConfig.stats.fireRate;
+}
+```
+
+## 调试信息
+
+系统会输出详细的调试信息:
+- 武器方块生成日志
+- 武器图标加载状态
+- 配置加载状态
+- 价格设置信息
+
+---
+
+# 节点路径更改和拖拽属性设置指南
+
+## 📝 重要更新
+
+### PlacedBlocks 节点位置更改
+- **旧路径**: `Canvas/PlacedBlocks`
+- **新路径**: `Canvas/GameLevelUI/PlacedBlocks`
+
+### 新增拖拽属性配置
+
+为了提高系统的灵活性和避免硬编码路径问题,现在所有关键节点都支持通过编辑器拖拽设置:
+
+#### 1. BlockManager 组件设置
+在 `Canvas/GameLevelUI/BlockController` 节点上的 BlockManager 脚本中设置:
+
+**属性设置:**
+- **Grid Container**: 拖拽 `Canvas/GameLevelUI/GameArea/GridContainer` 节点
+- **Kuang Container**: 拖拽 `Canvas/GameLevelUI/BlockSelectionUI/diban/kuang` 节点  
+- **Coin Label Node**: 拖拽 `Canvas/GameLevelUI/CoinNode/CoinLabel` 节点
+- **Placed Blocks Container**: 拖拽 `Canvas/GameLevelUI/PlacedBlocks` 节点 ✨**新增**
+
+#### 2. EnemyController 组件设置
+在 `Canvas/GameLevelUI/EnemyController` 节点上的 EnemyController 脚本中设置:
+
+**属性设置:**
+- **Enemy Prefab**: 拖拽敌人预制体
+- **Enemy Container**: 拖拽 `Canvas/GameLevelUI/enemyContainer` 节点 ✨**新增**
+- **Wall Health Node**: 拖拽墙体血量显示节点
+
+#### 3. BallController 组件设置
+在球控制器脚本中设置:
+
+**属性设置:**
+- **Ball Prefab**: 拖拽小球预制体
+- **Bullet Prefab**: 拖拽子弹预制体
+- **Placed Blocks Container**: 拖拽 `Canvas/GameLevelUI/PlacedBlocks` 节点 ✨**新增**
+
+## 🔧 自动兜底机制
+
+如果未通过拖拽设置节点,系统会自动尝试查找:
+
+### BlockManager 自动查找路径:
+- `placedBlocksContainer`: `Canvas/GameLevelUI/PlacedBlocks`
+
+### EnemyController 自动查找路径:
+- `enemyContainer`: `Canvas/GameLevelUI/enemyContainer`
+
+### BallController 自动查找路径:
+- `placedBlocksContainer`: `Canvas/GameLevelUI/PlacedBlocks`
+
+## ✅ 优势
+
+1. **灵活性**: 可以随时更改节点位置而不需要修改代码
+2. **可维护性**: 避免硬编码路径,降低维护成本
+3. **错误处理**: 提供自动查找机制作为备用方案
+4. **可视化**: 编辑器中可以直观看到组件间的引用关系
+
+## ⚠️ 注意事项
+
+1. **优先级**: 拖拽设置的节点优先于自动查找
+2. **有效性检查**: 系统会检查节点是否有效,失效时会显示警告
+3. **场景设置**: 确保在场景中正确创建了相应的节点结构
+4. **兼容性**: 旧的硬编码路径仍可作为备用方案
+
+## 🛠️ 升级步骤
+
+1. 确保场景中 PlacedBlocks 节点位于 `Canvas/GameLevelUI/` 下
+2. 在各个管理器组件上设置对应的拖拽属性
+3. 测试确保所有功能正常工作
+4. 可选:移除不再需要的节点路径硬编码
+
+---
+
+# 小球启动流程配置指南
+
+## 🎮 新增功能:延迟小球启动
+
+### 功能说明
+现在小球不会在游戏开始时自动出现和运动,而是等待玩家点击确定按钮后才开始:
+
+1. **游戏加载时**: BallController 只进行初始设置,不创建小球
+2. **放置方块阶段**: 玩家可以自由拖拽和放置方块
+3. **点击确定按钮**: 小球才开始创建并开始运动,且避免与已放置方块重叠
+
+### 🔄 工作流程
+
+#### 1. 游戏启动阶段
+```
+GameLevel 场景加载
+     ↓
+BallController.start() 执行
+     ↓
+只进行基础设置(calculateGameBounds, logCollisionMatrix)
+     ↓
+等待确定按钮点击...
+```
+
+#### 2. 确定按钮点击后
+```
+用户点击 confirm 按钮
+     ↓
+GameManager.onConfirmButtonClicked() 执行
+     ↓
+GameManager.startGame() 执行
+     ↓
+GameManager.spawnBall() 执行
+     ↓
+BallController.startBall() 执行
+     ↓
+小球创建、定位(避开方块)、开始运动
+```
+
+### 🎯 关键组件方法
+
+#### BallController 新增方法:
+- **`startBall()`**: 启动小球系统的主要方法
+  - 检查初始化状态
+  - 创建小球(如果需要)
+  - 重新定位避开方块
+  - 设置物理组件
+  - 开始运动
+  - 设置运动状态标志
+
+#### GameManager 修改的方法:
+- **`spawnBall()`**: 现在调用 `startBall()` 而不是 `initialize()`
+
+### 🔧 技术实现
+
+#### 状态管理:
+- `initialized`: 是否已初始化(创建小球但未运动)
+- `ballStarted`: 是否已开始运动
+
+#### 避免重叠机制:
+- 小球创建时会调用 `positionBallRandomly()`
+- 自动检测已放置的方块位置
+- 智能选择不重叠的生成位置
+- 如果找不到合适位置,使用安全的默认位置
+
+### ⚙️ 配置要求
+
+确保以下组件正确设置:
+
+#### GameManager 组件
+- **Ball Controller**: 拖拽包含 BallController 脚本的节点
+
+#### 确定按钮设置
+- 按钮路径: `Canvas/GameLevelUI/BlockSelectionUI/diban/confirm`
+- 点击事件已绑定到 `GameManager.onConfirmButtonClicked()`
+
+### 🎮 用户体验
+
+1. **直观的游戏流程**: 玩家先放置方块,确定后小球才出现
+2. **避免干扰**: 小球不会在方块放置阶段造成视觉干扰
+3. **智能定位**: 小球自动避开已放置的方块
+4. **即时反馈**: 点击确定按钮后立即看到小球开始运动
+
+### 🐛 故障排除
+
+**Q: 点击确定按钮后小球没有出现?**
+A: 检查 GameManager 的 Ball Controller 属性是否正确设置
+
+**Q: 小球出现但不运动?**
+A: 检查 BallController 的物理组件设置和碰撞矩阵配置
+
+**Q: 小球与方块重叠?**
+A: 检查 PlacedBlocks 容器路径是否正确,确保方块已正确放置到容器中
+
+**Q: 确定按钮点击无响应?**
+A: 检查按钮的点击事件绑定和 GameManager 组件设置 

+ 14 - 226
assets/scripts/CombatSystem/WeaponBlockExample.ts

@@ -1,5 +1,4 @@
-import { _decorator, Component, Node, Prefab, instantiate, Vec3, Sprite, SpriteFrame, resources, Texture2D, Vec2, Size, Rect, Color } from 'cc';
-import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
+import { _decorator, Component } from 'cc';
 const { ccclass, property } = _decorator;
 
 /**
@@ -8,238 +7,27 @@ const { ccclass, property } = _decorator;
  */
 @ccclass('WeaponBlockExample')
 export class WeaponBlockExample extends Component {
-    
-    @property({
-        type: Prefab,
-        tooltip: '基础方块预制体'
-    })
-    public blockPrefab: Prefab = null;
+    private static _instance: WeaponBlockExample = null;
 
-    @property({
-        type: Node,
-        tooltip: '方块容器节点'
-    })
-    public blockContainer: Node = null;
+    // 全局子弹速度(BulletController 会读取)
+    @property({ tooltip: '全局子弹速度(覆盖子弹预制体上的默认值)' })
+    public bulletSpeed: number = 300;
 
-    private configManager: ConfigManager = null;
-
-    start() {
-        console.log('WeaponBlockExample start()');
-        
-        // 获取配置管理器
-        this.configManager = ConfigManager.getInstance();
-        if (!this.configManager) {
-            return;
-        }
-        
-        // 等待配置加载完成后创建方块
-        this.scheduleOnce(() => {
-            this.initializeBlocks();
-        }, 0.5);
-    }
-
-    private initializeBlocks() {
-        // 检查配置管理器是否已初始化
-        if (!this.configManager) {
-            return;
-        }
-        
-        // 检查配置是否已加载完成
-        if (!this.configManager.isConfigLoaded()) {
-            // 如果配置尚未加载完成,延迟创建
-            this.scheduleOnce(() => {
-                this.initializeBlocks();
-            }, 1.0);
-            return;
-        }
-        
-        // 检查方块预制体是否已设置
-        if (!this.blockPrefab) {
-            return;
-        }
-        
-        // 创建5个不同稀有度的武器方块
-        this.createWeaponBlock('common');
-        this.createWeaponBlock('uncommon');
-        this.createWeaponBlock('rare');
-        this.createWeaponBlock('epic');
-        this.createRandomWeaponBlock();
-    }
-
-    private createWeaponBlock(rarity: string) {
-        // 获取指定稀有度的武器
-        const weapons = this.configManager.getWeaponsByRarity(rarity);
-        if (weapons.length === 0) {
-            return;
-        }
-        
-        // 随机选择一个武器
-        const weapon = weapons[Math.floor(Math.random() * weapons.length)];
-        this.createBlockWithWeapon(weapon);
-    }
-
-    private createRandomWeaponBlock() {
-        // 获取随机武器
-        const weapon = this.configManager.getRandomWeapon();
-        if (!weapon) {
-            return;
-        }
-        
-        this.createBlockWithWeapon(weapon);
-    }
-
-    private createBlockWithWeapon(weaponConfig: any) {
-        // 检查方块预制体
-        if (!this.blockPrefab) {
-            return;
-        }
-        
-        // 实例化方块
-        const blockNode = instantiate(this.blockPrefab);
-        if (!blockNode) {
-            return;
-        }
-        
-        // 设置方块名称
-        blockNode.name = `WeaponBlock_${weaponConfig.id}`;
-        
-        // 添加到场景中
-        this.node.addChild(blockNode);
-        
-        // 设置方块位置(简单的网格布局)
-        const index = this.node.children.length - 1;
-        const x = (index % 5) * 120 - 240; // 5列布局,间距120
-        const y = Math.floor(index / 5) * 120; // 行间距120
-        blockNode.position = new Vec3(x, y, 0);
-        
-        // 设置武器配置到方块
-        this.setupBlockWeapon(blockNode, weaponConfig);
-        
-        console.log(`生成武器方块: ${weaponConfig.name} (${weaponConfig.rarity})`);
-    }
-
-    // 设置方块的武器配置
-    private setupBlockWeapon(blockNode: Node, weaponConfig: WeaponConfig) {
-        // 设置方块的武器ID
-        blockNode['weaponId'] = weaponConfig.id;
-        
-        // 设置方块的稀有度颜色
-        this.setBlockRarityColor(blockNode, weaponConfig.rarity);
-        
-        // 加载武器图标
-        this.loadWeaponIcon(blockNode, weaponConfig);
+    onLoad() {
+        WeaponBlockExample._instance = this;
     }
 
-    // 设置方块稀有度颜色
-    private setBlockRarityColor(blockNode: Node, rarity: string) {
-        const sprite = blockNode.getComponent(Sprite);
-        if (!sprite) {
-            return;
+    onDestroy() {
+        if (WeaponBlockExample._instance === this) {
+            WeaponBlockExample._instance = null;
         }
-        
-        // 根据稀有度设置颜色
-        let color: Color;
-        switch (rarity) {
-            case 'common':
-                color = new Color(255, 255, 255); // 白色
-                break;
-            case 'uncommon':
-                color = new Color(0, 255, 0); // 绿色
-                break;
-            case 'rare':
-                color = new Color(0, 100, 255); // 蓝色
-                break;
-            case 'epic':
-                color = new Color(160, 32, 240); // 紫色
-                break;
-            case 'legendary':
-                color = new Color(255, 165, 0); // 橙色
-                break;
-            default:
-                color = new Color(255, 255, 255); // 默认白色
-        }
-        
-        sprite.color = color;
-    }
-
-    // 加载武器图标
-    private loadWeaponIcon(blockNode: Node, weaponConfig: WeaponConfig) {
-        // 这里应该根据weaponConfig加载对应的武器图标
-        // 由于没有实际的图标资源,这里只是示例代码
-        
-        // 寻找方块中的图标节点
-        const iconNode = blockNode.getChildByName('Icon');
-        if (!iconNode) {
-            return;
-        }
-        
-        const iconSprite = iconNode.getComponent(Sprite);
-        if (!iconSprite) {
-            return;
-        }
-        
-        // 根据武器类型加载不同的图标
-        // 这里需要根据实际的资源路径来加载
-        const iconPath = `images/PlantsSprite/${weaponConfig.id}`;
-        
-        resources.load(iconPath, SpriteFrame, (err, spriteFrame) => {
-            if (err) {
-                // 如果加载失败,使用默认图标或保持原样
-                return;
-            }
-            
-            if (iconSprite && spriteFrame) {
-                iconSprite.spriteFrame = spriteFrame;
-            }
-        });
     }
 
-    // 根据武器ID获取武器配置
-    public getWeaponConfigById(weaponId: string): WeaponConfig | null {
-        if (!this.configManager) {
-            return null;
-        }
-        
-        const weaponConfig = this.configManager.getWeaponById(weaponId);
-        if (!weaponConfig) {
-            return null;
-        }
-        
-        return weaponConfig;
+    public static getInstance(): WeaponBlockExample {
+        return WeaponBlockExample._instance;
     }
 
-    // 获取方块的武器配置(供其他脚本调用)
-    public static getBlockWeaponConfig(blockNode: Node): WeaponConfig | null {
-        return (blockNode as any).weaponConfig || null;
-    }
-
-    // 创建指定ID的武器方块
-    public createWeaponBlockById(weaponId: string, position: Vec3): Node | null {
-        const weaponConfig = this.configManager.getWeaponById(weaponId);
-        if (!weaponConfig) {
-            console.warn(`找不到ID为 ${weaponId} 的武器配置`);
-            return null;
-        }
-
-        this.createBlockWithWeapon(weaponConfig);
-        return null; // 实际项目中应该返回创建的节点
-    }
-
-    // 获取所有可用的武器ID列表
-    public getAvailableWeaponIds(): string[] {
-        if (!this.configManager || !this.configManager.isConfigLoaded()) {
-            return [];
-        }
-
-        return this.configManager.getAllWeapons().map(weapon => weapon.id);
-    }
-
-    // 获取指定稀有度的武器数量
-    public getWeaponCountByRarity(rarity: string): number {
-        if (!this.configManager || !this.configManager.isConfigLoaded()) {
-            return 0;
-        }
-
-        return this.configManager.getWeaponsByRarity(rarity).length;
+    public getCurrentBulletSpeed(): number {
+        return this.bulletSpeed;
     }
 } 

+ 0 - 84
assets/scripts/CombatSystem/WeaponComponent.ts

@@ -1,84 +0,0 @@
-import { _decorator, Component } from 'cc';
-import { WeaponConfig } from '../Core/ConfigManager';
-const { ccclass } = _decorator;
-
-/**
- * 武器组件
- * 用于存储方块的武器配置信息
- */
-@ccclass('WeaponComponent')
-export class WeaponComponent extends Component {
-    public weaponConfig: WeaponConfig = null;
-
-    // 获取武器伤害
-    public getDamage(): number {
-        return this.weaponConfig?.stats?.damage || 0;
-    }
-
-    // 获取武器射速
-    public getFireRate(): number {
-        return this.weaponConfig?.stats?.fireRate || 1.0;
-    }
-
-    // 获取武器射程
-    public getRange(): number {
-        return this.weaponConfig?.stats?.range || 100;
-    }
-
-    // 获取子弹速度
-    public getBulletSpeed(): number {
-        return this.weaponConfig?.stats?.bulletSpeed || 50;
-    }
-
-    // 获取穿透数量
-    public getPenetration(): number {
-        return this.weaponConfig?.stats?.penetration || 1;
-    }
-
-    // 获取精准度
-    public getAccuracy(): number {
-        return this.weaponConfig?.stats?.accuracy || 1.0;
-    }
-
-    // 获取子弹预制体路径
-    public getBulletPrefab(): string {
-        return this.weaponConfig?.bulletConfig?.bulletPrefab || '';
-    }
-
-    // 获取攻击模式
-    public getAttackPattern(): any {
-        return this.weaponConfig?.attackPattern || null;
-    }
-
-    // 检查是否有特殊能力
-    public hasSpecialAbility(abilityType: string): boolean {
-        if (!this.weaponConfig) return false;
-        
-        switch (abilityType) {
-            case 'explosive':
-                return this.weaponConfig.type === 'explosive';
-            case 'piercing':
-                return this.weaponConfig.type === 'piercing';
-            case 'ricochet':
-                return this.weaponConfig.type === 'ricochet_piercing';
-            case 'homing':
-                return this.weaponConfig.type === 'homing_missile';
-            case 'area_burn':
-                return this.weaponConfig.type === 'area_burn';
-            default:
-                return false;
-        }
-    }
-
-    // 获取武器信息文本
-    public getWeaponInfo(): string {
-        if (!this.weaponConfig) return '未知武器';
-        
-        return `${this.weaponConfig.name}\n` +
-               `类型: ${this.weaponConfig.type}\n` +
-               `稀有度: ${this.weaponConfig.rarity}\n` +
-               `伤害: ${this.weaponConfig.stats.damage}\n` +
-               `射速: ${this.weaponConfig.stats.fireRate}\n` +
-               `射程: ${this.weaponConfig.stats.range}`;
-    }
-} 

+ 0 - 9
assets/scripts/CombatSystem/WeaponComponent.ts.meta

@@ -1,9 +0,0 @@
-{
-  "ver": "4.0.24",
-  "importer": "typescript",
-  "imported": true,
-  "uuid": "04b7cef6-7a1c-4c67-bf94-c9d2ccc4a33c",
-  "files": [],
-  "subMetas": {},
-  "userData": {}
-}

+ 12 - 2
assets/scripts/LevelSystem/GameManager.ts

@@ -676,15 +676,25 @@ export class GameManager extends Component {
     }
 
     private spawnBall() {
+        console.log('🎯 === GameManager: 启动小球 ===');
+        
         if (!this.ballController) {
+            console.error('❌ BallController 节点未设置');
             return;
         }
 
-        // 注意:BallController可能需要导入,这里先使用any类型
+        // 获取BallController组件
         const ballControllerComp = this.ballController.getComponent('BallController') as any;
         if (ballControllerComp) {
-            ballControllerComp.initialize();
+            console.log('✅ 找到BallController组件,启动小球...');
+            // 调用startBall方法而不是initialize,确保小球在确定按钮点击后才开始运动
+            ballControllerComp.startBall();
+            console.log('🚀 小球启动完成');
+        } else {
+            console.error('❌ 找不到BallController组件');
         }
+        
+        console.log('🎯 === GameManager: 小球启动流程完成 ===');
     }
 
     public gameOver() {

Some files were not shown because too many files changed in this diff