Browse Source

整理脚本

181404010226 5 months ago
parent
commit
c59cad8da8
39 changed files with 881 additions and 285 deletions
  1. 0 0
      assets/scripts/CombatSystem/BallController.ts
  2. 0 0
      assets/scripts/CombatSystem/BallController.ts.meta
  3. 0 0
      assets/scripts/CombatSystem/BlockManager.ts
  4. 0 0
      assets/scripts/CombatSystem/BlockManager.ts.meta
  5. 0 0
      assets/scripts/CombatSystem/BulletController.ts
  6. 0 0
      assets/scripts/CombatSystem/BulletController.ts.meta
  7. 120 0
      assets/scripts/CombatSystem/EnemyComponent.ts
  8. 0 0
      assets/scripts/CombatSystem/EnemyComponent.ts.meta
  9. 0 0
      assets/scripts/CombatSystem/EnemyController.ts
  10. 0 0
      assets/scripts/CombatSystem/EnemyController.ts.meta
  11. 0 0
      assets/scripts/CombatSystem/EnemyInstance.ts
  12. 0 0
      assets/scripts/CombatSystem/EnemyInstance.ts.meta
  13. 1 1
      assets/scripts/CombatSystem/EnemySpawnerExample.ts
  14. 0 0
      assets/scripts/CombatSystem/EnemySpawnerExample.ts.meta
  15. 2 2
      assets/scripts/CombatSystem/EnemySpawnerTestScene.ts
  16. 0 0
      assets/scripts/CombatSystem/EnemySpawnerTestScene.ts.meta
  17. 1 1
      assets/scripts/CombatSystem/WeaponBlockExample.ts
  18. 0 0
      assets/scripts/CombatSystem/WeaponBlockExample.ts.meta
  19. 1 1
      assets/scripts/CombatSystem/WeaponBlockTestScene.ts
  20. 0 0
      assets/scripts/CombatSystem/WeaponBlockTestScene.ts.meta
  21. 1 1
      assets/scripts/CombatSystem/WeaponComponent.ts
  22. 0 0
      assets/scripts/CombatSystem/WeaponComponent.ts.meta
  23. 9 0
      assets/scripts/Core.meta
  24. 0 0
      assets/scripts/Core/ConfigManager.ts
  25. 0 0
      assets/scripts/Core/ConfigManager.ts.meta
  26. 0 0
      assets/scripts/Core/GameManager.ts
  27. 0 0
      assets/scripts/Core/GameManager.ts.meta
  28. 0 0
      assets/scripts/Core/GameStartup.ts
  29. 0 0
      assets/scripts/Core/GameStartup.ts.meta
  30. 0 0
      assets/scripts/Core/PhysicsManager.ts
  31. 0 0
      assets/scripts/Core/PhysicsManager.ts.meta
  32. 65 0
      assets/scripts/Core/README.md
  33. 11 0
      assets/scripts/Core/README.md.meta
  34. 0 211
      assets/scripts/EnemyComponent.ts
  35. 172 0
      assets/scripts/LevelSystem/LevelManager.ts
  36. 3 3
      assets/scripts/LevelSystem/LevelManager.ts.meta
  37. 126 65
      assets/scripts/README.md
  38. 360 0
      assets/scripts/ShopSystem/ShopManager.ts
  39. 9 0
      assets/scripts/ShopSystem/ShopManager.ts.meta

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


+ 0 - 0
assets/scripts/BallController.ts.meta → assets/scripts/CombatSystem/BallController.ts.meta


+ 0 - 0
assets/scripts/BlockManager.ts → assets/scripts/CombatSystem/BlockManager.ts


+ 0 - 0
assets/scripts/BlockManager.ts.meta → assets/scripts/CombatSystem/BlockManager.ts.meta


+ 0 - 0
assets/scripts/BulletController.ts → assets/scripts/CombatSystem/BulletController.ts


+ 0 - 0
assets/scripts/BulletController.ts.meta → assets/scripts/CombatSystem/BulletController.ts.meta


+ 120 - 0
assets/scripts/CombatSystem/EnemyComponent.ts

@@ -0,0 +1,120 @@
+import { _decorator, Component } from 'cc';
+import { ConfigManager, EnemyConfig } from '../Core/ConfigManager';
+const { ccclass, property } = _decorator;
+
+/**
+ * 敌人组件
+ * 用于存储敌人的配置信息和基础属性
+ */
+@ccclass('EnemyComponent')
+export class EnemyComponent extends Component {
+    public enemyConfig: EnemyConfig = null;
+    public spawner: any = null; // 对生成器的引用
+
+    // 获取敌人生命值
+    public getHealth(): number {
+        return this.enemyConfig?.stats?.health || 100;
+    }
+
+    // 获取敌人速度
+    public getSpeed(): number {
+        return this.enemyConfig?.stats?.speed || 50;
+    }
+
+    // 获取敌人伤害
+    public getDamage(): number {
+        return this.enemyConfig?.stats?.damage || 20;
+    }
+
+    // 获取敌人攻击范围
+    public getAttackRange(): number {
+        return this.enemyConfig?.stats?.attackRange || 30;
+    }
+
+    // 获取敌人攻击速度
+    public getAttackSpeed(): number {
+        return this.enemyConfig?.stats?.attackSpeed || 1.0;
+    }
+
+    // 获取敌人防御力
+    public getDefense(): number {
+        return this.enemyConfig?.stats?.defense || 0;
+    }
+
+    // 获取击杀奖励
+    public getCoinReward(): number {
+        return this.enemyConfig?.stats?.coinReward || 10;
+    }
+
+    // 获取移动类型
+    public getMovementType(): string {
+        return this.enemyConfig?.movement?.type || 'straight';
+    }
+
+    // 获取移动模式
+    public getMovementPattern(): string {
+        return this.enemyConfig?.movement?.pattern || 'walk_forward';
+    }
+
+    // 获取攻击类型
+    public getAttackType(): string {
+        return this.enemyConfig?.combat?.attackType || 'melee';
+    }
+
+    // 获取动画配置
+    public getAnimations(): any {
+        return this.enemyConfig?.visualConfig?.animations || {};
+    }
+
+    // 获取音频配置
+    public getAudioConfig(): any {
+        return this.enemyConfig?.audioConfig || {};
+    }
+
+    // 检查是否有特殊能力
+    public hasSpecialAbility(abilityType: string): boolean {
+        if (!this.enemyConfig || !this.enemyConfig.specialAbilities) return false;
+        return this.enemyConfig.specialAbilities.indexOf(abilityType) !== -1;
+    }
+
+    // 获取特殊配置
+    public getStealthConfig(): any {
+        return this.enemyConfig?.stealthConfig || null;
+    }
+
+    public getArmorConfig(): any {
+        return this.enemyConfig?.armorConfig || null;
+    }
+
+    public getExplosionConfig(): any {
+        return this.enemyConfig?.explosionConfig || null;
+    }
+
+    public getBossConfig(): any {
+        return this.enemyConfig?.bossConfig || null;
+    }
+
+    public getProjectileConfig(): any {
+        return this.enemyConfig?.projectileConfig || null;
+    }
+
+    // 获取敌人信息文本
+    public getEnemyInfo(): string {
+        if (!this.enemyConfig) return '未知敌人';
+        
+        return `${this.enemyConfig.name}\n` +
+               `类型: ${this.enemyConfig.type}\n` +
+               `稀有度: ${this.enemyConfig.rarity}\n` +
+               `生命值: ${this.enemyConfig.stats.health}\n` +
+               `速度: ${this.enemyConfig.stats.speed}\n` +
+               `伤害: ${this.enemyConfig.stats.damage}\n` +
+               `攻击范围: ${this.enemyConfig.stats.attackRange}`;
+    }
+
+    // 死亡时调用
+    public onDeath() {
+        if (this.spawner && this.spawner.onEnemyDeath) {
+            this.spawner.onEnemyDeath(this.node);
+        }
+    }
+} 

+ 0 - 0
assets/scripts/EnemyComponent.ts.meta → assets/scripts/CombatSystem/EnemyComponent.ts.meta


+ 0 - 0
assets/scripts/EnemyController.ts → assets/scripts/CombatSystem/EnemyController.ts


+ 0 - 0
assets/scripts/EnemyController.ts.meta → assets/scripts/CombatSystem/EnemyController.ts.meta


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


+ 0 - 0
assets/scripts/EnemyInstance.ts.meta → assets/scripts/CombatSystem/EnemyInstance.ts.meta


+ 1 - 1
assets/scripts/EnemySpawnerExample.ts → assets/scripts/CombatSystem/EnemySpawnerExample.ts

@@ -1,6 +1,6 @@
 import { _decorator, Component, Node, Prefab, instantiate, Vec3, Vec2, Sprite, SpriteFrame, resources, RigidBody2D, CCFloat, CCInteger } from 'cc';
 import { sp } from 'cc';
-import { ConfigManager, EnemyConfig } from './ConfigManager';
+import { ConfigManager, EnemyConfig } from '../Core/ConfigManager';
 import { EnemyComponent } from './EnemyComponent';
 const { ccclass, property } = _decorator;
 

+ 0 - 0
assets/scripts/EnemySpawnerExample.ts.meta → assets/scripts/CombatSystem/EnemySpawnerExample.ts.meta


+ 2 - 2
assets/scripts/EnemySpawnerTestScene.ts → assets/scripts/CombatSystem/EnemySpawnerTestScene.ts

@@ -1,6 +1,6 @@
-import { _decorator, Component, Node, Prefab, Vec3, input, Input, EventKeyboard, KeyCode } from 'cc';
+import { _decorator, Component, Node, Prefab, Canvas, UITransform, Vec3, input, Input, EventKeyboard, KeyCode, director } from 'cc';
 import { EnemySpawnerExample } from './EnemySpawnerExample';
-import { ConfigManager } from './ConfigManager';
+import { ConfigManager } from '../Core/ConfigManager';
 const { ccclass, property } = _decorator;
 
 /**

+ 0 - 0
assets/scripts/EnemySpawnerTestScene.ts.meta → assets/scripts/CombatSystem/EnemySpawnerTestScene.ts.meta


+ 1 - 1
assets/scripts/WeaponBlockExample.ts → assets/scripts/CombatSystem/WeaponBlockExample.ts

@@ -1,5 +1,5 @@
 import { _decorator, Component, Node, Prefab, instantiate, Vec3, Sprite, SpriteFrame, resources, Texture2D, Vec2, Size, Rect } from 'cc';
-import { ConfigManager, WeaponConfig } from './ConfigManager';
+import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
 const { ccclass, property } = _decorator;
 
 /**

+ 0 - 0
assets/scripts/WeaponBlockExample.ts.meta → assets/scripts/CombatSystem/WeaponBlockExample.ts.meta


+ 1 - 1
assets/scripts/WeaponBlockTestScene.ts → assets/scripts/CombatSystem/WeaponBlockTestScene.ts

@@ -1,5 +1,5 @@
 import { _decorator, Component, Node, Prefab, Canvas, UITransform, Vec3, director } from 'cc';
-import { ConfigManager } from './ConfigManager';
+import { ConfigManager } from '../Core/ConfigManager';
 const { ccclass, property } = _decorator;
 
 /**

+ 0 - 0
assets/scripts/WeaponBlockTestScene.ts.meta → assets/scripts/CombatSystem/WeaponBlockTestScene.ts.meta


+ 1 - 1
assets/scripts/WeaponComponent.ts → assets/scripts/CombatSystem/WeaponComponent.ts

@@ -1,5 +1,5 @@
 import { _decorator, Component } from 'cc';
-import { WeaponConfig } from './ConfigManager';
+import { WeaponConfig } from '../Core/ConfigManager';
 const { ccclass } = _decorator;
 
 /**

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


+ 9 - 0
assets/scripts/Core.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "20689e10-d4eb-424b-85e8-79b93b2195cb",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 0 - 0
assets/scripts/ConfigManager.ts → assets/scripts/Core/ConfigManager.ts


+ 0 - 0
assets/scripts/ConfigManager.ts.meta → assets/scripts/Core/ConfigManager.ts.meta


+ 0 - 0
assets/scripts/GameManager.ts → assets/scripts/Core/GameManager.ts


+ 0 - 0
assets/scripts/GameManager.ts.meta → assets/scripts/Core/GameManager.ts.meta


+ 0 - 0
assets/scripts/GameStartup.ts → assets/scripts/Core/GameStartup.ts


+ 0 - 0
assets/scripts/GameStartup.ts.meta → assets/scripts/Core/GameStartup.ts.meta


+ 0 - 0
assets/scripts/PhysicsManager.ts → assets/scripts/Core/PhysicsManager.ts


+ 0 - 0
assets/scripts/PhysicsManager.ts.meta → assets/scripts/Core/PhysicsManager.ts.meta


+ 65 - 0
assets/scripts/Core/README.md

@@ -0,0 +1,65 @@
+# 弹球游戏实现说明
+
+## 脚本概述
+
+1. **GameManager.ts**
+   - 游戏主控制器
+   - 负责游戏流程控制、生成小球、管理游戏状态
+
+2. **BallController.ts**
+   - 小球控制器
+   - 控制小球的移动、碰撞检测和反弹逻辑
+
+3. **PhysicsManager.ts**
+   - 物理系统管理器
+   - 初始化和配置物理系统
+
+4. **SceneSetup.ts**
+   - 场景初始化脚本
+   - 自动添加必要的组件和设置引用
+
+5. **BallSetup.ts**
+   - 小球预制体初始化脚本
+   - 确保小球预制体有必要的组件
+
+## 使用方法
+
+### 1. 场景设置
+
+1. 在场景根节点(Canvas)上添加 `SceneSetup` 组件
+
+### 2. 预制体设置
+
+1. 确保 Ball 预制体位于 `assets/assets/Prefabs/Ball.prefab`
+2. 在 Ball 预制体上添加 `BallSetup` 组件
+
+### 3. UI设置
+
+1. 确保场景中有以下节点结构:
+   - Canvas
+     - GameLevelUI
+       - BlockSelectionUI
+         - diban
+           - confirm (按钮)
+           - kuang
+             - db01
+             - db02
+             - db03
+       - GameArea (用于放置游戏元素)
+       - CoinNode
+         - CoinLabel
+
+## 游戏流程
+
+1. 点击 `confirm` 按钮后,会隐藏 BlockSelectionUI 并开始游戏
+2. 游戏开始时,会在 GameArea 内随机位置生成一个小球,并赋予随机初始方向
+3. 小球会按照弹球游戏的规则运动:
+   - 碰到屏幕边界会反弹
+   - 碰到方块也会反弹
+   - 碰到方块时会模拟发射子弹(目前只是在控制台输出)
+
+## 注意事项
+
+1. 确保方块有正确的碰撞组件设置
+2. 确保 GameArea 节点的大小正确设置,以便正确计算游戏边界
+3. 如果需要显示物理调试信息,可以在 PhysicsManager 组件中勾选 debugDraw 选项 

+ 11 - 0
assets/scripts/Core/README.md.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "1.0.1",
+  "importer": "text",
+  "imported": true,
+  "uuid": "e3e4b559-15b9-4495-add6-beefea105d49",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 0 - 211
assets/scripts/EnemyComponent.ts

@@ -1,211 +0,0 @@
-import { _decorator, Component, Node, Vec2, RigidBody2D } from 'cc';
-import { ConfigManager, EnemyConfig } from './ConfigManager';
-import { EnemySpawnerExample } from './EnemySpawnerExample';
-
-const { ccclass, property } = _decorator;
-
-/**
- * 敌人组件
- * 用于存储敌人的配置信息和行为逻辑
- */
-@ccclass('EnemyComponent')
-export class EnemyComponent extends Component {
-    public enemyConfig: EnemyConfig = null;
-    public spawner: EnemySpawnerExample = null;
-    
-    private currentHealth: number = 0;
-    private moveTimer: number = 0;
-    private attackTimer: number = 0;
-    private isAlive: boolean = true;
-
-    start() {
-        if (this.enemyConfig) {
-            this.currentHealth = this.enemyConfig.stats.health;
-            this.setupMovement();
-        }
-    }
-
-    update(deltaTime: number) {
-        if (!this.isAlive || !this.enemyConfig) return;
-
-        this.updateMovement(deltaTime);
-        this.updateAttack(deltaTime);
-        this.checkBounds();
-    }
-
-    // 设置移动行为
-    private setupMovement() {
-        const rigidBody = this.node.getComponent(RigidBody2D);
-        if (rigidBody && this.enemyConfig) {
-            const movement = this.enemyConfig.movement;
-            const speed = this.enemyConfig.stats.speed;
-            
-            switch (movement.type) {
-                case 'straight':
-                    rigidBody.linearVelocity = new Vec2(-speed, 0);
-                    break;
-                case 'sway':
-                    rigidBody.linearVelocity = new Vec2(-speed, 0);
-                    break;
-                default:
-                    rigidBody.linearVelocity = new Vec2(-speed, 0);
-                    break;
-            }
-        }
-    }
-
-    // 更新移动
-    private updateMovement(deltaTime: number) {
-        if (!this.enemyConfig) return;
-        
-        const movement = this.enemyConfig.movement;
-        
-        if (movement.type === 'sway') {
-            this.moveTimer += deltaTime;
-            const rigidBody = this.node.getComponent(RigidBody2D);
-            
-            if (rigidBody) {
-                const speed = this.enemyConfig.stats.speed;
-                const swayAmplitude = movement.swayAmplitude || 20;
-                const swayFrequency = movement.swayFrequency || 2.0;
-                
-                const yVelocity = Math.sin(this.moveTimer * swayFrequency) * swayAmplitude;
-                rigidBody.linearVelocity = new Vec2(-speed, yVelocity);
-            }
-        }
-    }
-
-    // 更新攻击
-    private updateAttack(deltaTime: number) {
-        if (!this.enemyConfig) return;
-        
-        this.attackTimer += deltaTime;
-        
-        if (this.attackTimer >= this.enemyConfig.combat.attackCooldown) {
-            this.performAttack();
-            this.attackTimer = 0;
-        }
-    }
-
-    // 执行攻击
-    private performAttack() {
-        if (!this.enemyConfig) return;
-        
-        const combat = this.enemyConfig.combat;
-        
-        switch (combat.attackType) {
-            case 'magic_projectile':
-            case 'arrow_projectile':
-                this.fireProjectile();
-                break;
-            case 'melee':
-            case 'heavy_melee':
-                this.performMeleeAttack();
-                break;
-            default:
-                break;
-        }
-    }
-
-    // 发射投射物
-    private fireProjectile() {
-        console.log(`${this.enemyConfig.name} 发射投射物`);
-        // 这里应该创建子弹并发射
-    }
-
-    // 执行近战攻击
-    private performMeleeAttack() {
-        console.log(`${this.enemyConfig.name} 执行近战攻击`);
-        // 这里应该检测攻击范围内的目标
-    }
-
-    // 检查边界
-    private checkBounds() {
-        const position = this.node.getPosition();
-        
-        // 如果敌人移动到屏幕左侧外,销毁它
-        if (position.x < -900) {
-            this.die();
-        }
-    }
-
-    // 受到伤害
-    public takeDamage(damage: number) {
-        if (!this.isAlive) return;
-        
-        this.currentHealth -= damage;
-        console.log(`${this.enemyConfig.name} 受到 ${damage} 点伤害,剩余血量: ${this.currentHealth}`);
-        
-        if (this.currentHealth <= 0) {
-            this.die();
-        }
-    }
-
-    // 死亡
-    private die() {
-        if (!this.isAlive) return;
-        
-        this.isAlive = false;
-        console.log(`${this.enemyConfig.name} 死亡`);
-        
-        // 处理爆炸类型敌人的死亡爆炸
-        if (this.enemyConfig.type === 'explosive') {
-            this.explode();
-        }
-        
-        // 通知生成器
-        if (this.spawner) {
-            this.spawner.onEnemyDeath(this.node);
-        }
-    }
-
-    // 爆炸
-    private explode() {
-        console.log(`${this.enemyConfig.name} 爆炸!`);
-        // 这里应该创建爆炸效果和伤害判定
-    }
-
-    // 获取敌人信息
-    public getEnemyInfo(): string {
-        if (!this.enemyConfig) return '未知敌人';
-        
-        return `${this.enemyConfig.name}\n` +
-               `类型: ${this.enemyConfig.type}\n` +
-               `血量: ${this.currentHealth}/${this.enemyConfig.stats.health}\n` +
-               `速度: ${this.enemyConfig.stats.speed}\n` +
-               `伤害: ${this.enemyConfig.stats.damage}`;
-    }
-
-    // 获取当前血量
-    public getCurrentHealth(): number {
-        return this.currentHealth;
-    }
-
-    // 获取最大血量
-    public getMaxHealth(): number {
-        return this.enemyConfig?.stats?.health || 100;
-    }
-
-    // 获取移动速度
-    public getSpeed(): number {
-        return this.enemyConfig?.stats?.speed || 50;
-    }
-
-    // 获取攻击力
-    public getDamage(): number {
-        return this.enemyConfig?.stats?.damage || 20;
-    }
-
-    // 检查是否有特殊能力
-    public hasSpecialAbility(ability: string): boolean {
-        if (!this.enemyConfig || !this.enemyConfig.specialAbilities) return false;
-        
-        // 使用循环代替includes方法
-        for (let i = 0; i < this.enemyConfig.specialAbilities.length; i++) {
-            if (this.enemyConfig.specialAbilities[i] === ability) {
-                return true;
-            }
-        }
-        return false;
-    }
-} 

+ 172 - 0
assets/scripts/LevelSystem/LevelManager.ts

@@ -0,0 +1,172 @@
+import { _decorator, Component, sys } from 'cc';
+const { ccclass, property } = _decorator;
+
+/**
+ * 关卡管理器
+ * 负责关卡数据的保存、加载和切换
+ */
+@ccclass('LevelManager')
+export class LevelManager extends Component {
+    private static instance: LevelManager = null;
+    
+    private currentLevel: number = 1;
+    private maxUnlockedLevel: number = 1;
+    private levelData: any = {};
+
+    onLoad() {
+        if (LevelManager.instance === null) {
+            LevelManager.instance = this;
+            this.loadLevelData();
+        } else if (LevelManager.instance !== this) {
+            this.destroy();
+            return;
+        }
+    }
+
+    onDestroy() {
+        if (LevelManager.instance === this) {
+            LevelManager.instance = null;
+        }
+    }
+
+    public static getInstance(): LevelManager {
+        return LevelManager.instance;
+    }
+
+    // 加载关卡数据
+    private loadLevelData() {
+        const savedData = sys.localStorage.getItem('levelData');
+        if (savedData) {
+            try {
+                const data = JSON.parse(savedData);
+                this.currentLevel = data.currentLevel || 1;
+                this.maxUnlockedLevel = data.maxUnlockedLevel || 1;
+                this.levelData = data.levelData || {};
+                console.log('关卡数据加载成功');
+            } catch (error) {
+                console.error('关卡数据解析失败:', error);
+                this.resetLevelData();
+            }
+        } else {
+            this.resetLevelData();
+        }
+    }
+
+    // 保存关卡数据
+    private saveLevelData() {
+        const data = {
+            currentLevel: this.currentLevel,
+            maxUnlockedLevel: this.maxUnlockedLevel,
+            levelData: this.levelData
+        };
+        
+        try {
+            sys.localStorage.setItem('levelData', JSON.stringify(data));
+            console.log('关卡数据保存成功');
+        } catch (error) {
+            console.error('关卡数据保存失败:', error);
+        }
+    }
+
+    // 重置关卡数据
+    private resetLevelData() {
+        this.currentLevel = 1;
+        this.maxUnlockedLevel = 1;
+        this.levelData = {};
+        this.saveLevelData();
+    }
+
+    // 获取当前关卡
+    public getCurrentLevel(): number {
+        return this.currentLevel;
+    }
+
+    // 获取最大解锁关卡
+    public getMaxUnlockedLevel(): number {
+        return this.maxUnlockedLevel;
+    }
+
+    // 设置当前关卡
+    public setCurrentLevel(level: number) {
+        if (level <= this.maxUnlockedLevel && level >= 1) {
+            this.currentLevel = level;
+            this.saveLevelData();
+            console.log(`切换到关卡 ${level}`);
+        } else {
+            console.warn(`关卡 ${level} 未解锁或无效`);
+        }
+    }
+
+    // 完成关卡
+    public completeLevel(level: number, score: number = 0, stars: number = 1) {
+        // 解锁下一关
+        if (level === this.maxUnlockedLevel) {
+            this.maxUnlockedLevel = level + 1;
+        }
+
+        // 保存关卡成绩
+        if (!this.levelData[level]) {
+            this.levelData[level] = {};
+        }
+
+        const currentData = this.levelData[level];
+        if (!currentData.bestScore || score > currentData.bestScore) {
+            currentData.bestScore = score;
+        }
+
+        if (!currentData.bestStars || stars > currentData.bestStars) {
+            currentData.bestStars = stars;
+        }
+
+        currentData.completed = true;
+        currentData.completionTime = Date.now();
+
+        this.saveLevelData();
+        console.log(`关卡 ${level} 完成,得分: ${score},星级: ${stars}`);
+    }
+
+    // 获取关卡数据
+    public getLevelData(level: number): any {
+        return this.levelData[level] || {
+            completed: false,
+            bestScore: 0,
+            bestStars: 0
+        };
+    }
+
+    // 检查关卡是否已解锁
+    public isLevelUnlocked(level: number): boolean {
+        return level <= this.maxUnlockedLevel;
+    }
+
+    // 检查关卡是否已完成
+    public isLevelCompleted(level: number): boolean {
+        const data = this.getLevelData(level);
+        return data.completed || false;
+    }
+
+    // 获取关卡最佳成绩
+    public getLevelBestScore(level: number): number {
+        const data = this.getLevelData(level);
+        return data.bestScore || 0;
+    }
+
+    // 获取关卡最佳星级
+    public getLevelBestStars(level: number): number {
+        const data = this.getLevelData(level);
+        return data.bestStars || 0;
+    }
+
+    // 重置所有关卡进度
+    public resetAllProgress() {
+        this.resetLevelData();
+        console.log('所有关卡进度已重置');
+    }
+
+    // 解锁所有关卡(调试用)
+    public unlockAllLevels(maxLevel: number = 100) {
+        this.maxUnlockedLevel = maxLevel;
+        this.saveLevelData();
+        console.log(`已解锁所有关卡(最大关卡: ${maxLevel})`);
+    }
+} 

+ 3 - 3
assets/scripts/BlockManager.meta → assets/scripts/LevelSystem/LevelManager.ts.meta

@@ -1,9 +1,9 @@
 {
-  "ver": "4.0.23",
+  "ver": "4.0.24",
   "importer": "typescript",
   "imported": true,
-  "uuid": "5a5e9c24-5b81-4f65-9e8c-a9b484a5d6d8",
+  "uuid": "c2c56d9f-11a8-4fda-b7e1-51b7ca8feae3",
   "files": [],
   "subMetas": {},
   "userData": {}
-} 
+}

+ 126 - 65
assets/scripts/README.md

@@ -1,65 +1,126 @@
-# 弹球游戏实现说明
-
-## 脚本概述
-
-1. **GameManager.ts**
-   - 游戏主控制器
-   - 负责游戏流程控制、生成小球、管理游戏状态
-
-2. **BallController.ts**
-   - 小球控制器
-   - 控制小球的移动、碰撞检测和反弹逻辑
-
-3. **PhysicsManager.ts**
-   - 物理系统管理器
-   - 初始化和配置物理系统
-
-4. **SceneSetup.ts**
-   - 场景初始化脚本
-   - 自动添加必要的组件和设置引用
-
-5. **BallSetup.ts**
-   - 小球预制体初始化脚本
-   - 确保小球预制体有必要的组件
-
-## 使用方法
-
-### 1. 场景设置
-
-1. 在场景根节点(Canvas)上添加 `SceneSetup` 组件
-
-### 2. 预制体设置
-
-1. 确保 Ball 预制体位于 `assets/assets/Prefabs/Ball.prefab`
-2. 在 Ball 预制体上添加 `BallSetup` 组件
-
-### 3. UI设置
-
-1. 确保场景中有以下节点结构:
-   - Canvas
-     - GameLevelUI
-       - BlockSelectionUI
-         - diban
-           - confirm (按钮)
-           - kuang
-             - db01
-             - db02
-             - db03
-       - GameArea (用于放置游戏元素)
-       - CoinNode
-         - CoinLabel
-
-## 游戏流程
-
-1. 点击 `confirm` 按钮后,会隐藏 BlockSelectionUI 并开始游戏
-2. 游戏开始时,会在 GameArea 内随机位置生成一个小球,并赋予随机初始方向
-3. 小球会按照弹球游戏的规则运动:
-   - 碰到屏幕边界会反弹
-   - 碰到方块也会反弹
-   - 碰到方块时会模拟发射子弹(目前只是在控制台输出)
-
-## 注意事项
-
-1. 确保方块有正确的碰撞组件设置
-2. 确保 GameArea 节点的大小正确设置,以便正确计算游戏边界
-3. 如果需要显示物理调试信息,可以在 PhysicsManager 组件中勾选 debugDraw 选项 
+# 脚本文件夹结构说明
+
+本项目的脚本已经按照功能模块重新组织,结构如下:
+
+## 📁 文件夹结构
+
+### 🎯 CombatSystem (战斗系统)
+负责游戏中的战斗相关功能,包括武器、敌人、子弹等
+- `BallController.ts` - 球体控制器
+- `BlockManager.ts` - 方块管理器
+- `BulletController.ts` - 子弹控制器
+- `EnemyController.ts` - 敌人控制器
+- `EnemyInstance.ts` - 敌人实例
+- `EnemyComponent.ts` - 敌人组件
+- `EnemySpawnerExample.ts` - 敌人生成器示例
+- `EnemySpawnerTestScene.ts` - 敌人生成器测试场景
+- `WeaponComponent.ts` - 武器组件
+- `WeaponBlockExample.ts` - 武器方块示例
+- `WeaponBlockTestScene.ts` - 武器方块测试场景
+
+### 🏢 Core (核心系统)
+包含所有模块共用的核心脚本
+- `ConfigManager.ts` - 配置管理器(武器、敌人配置)
+- `GameManager.ts` - 游戏管理器
+- `GameStartup.ts` - 游戏启动器
+- `PhysicsManager.ts` - 物理管理器
+- `README.md` - 核心系统说明
+
+### 🎮 LevelSystem (关卡系统)
+负责关卡切换和数据保存
+- `LevelManager.ts` - 关卡管理器
+
+### 🛒 ShopSystem (商店系统)
+负责物品购买,影响战斗武器
+- `ShopManager.ts` - 商店管理器
+
+## 🔗 模块间依赖关系
+
+```
+Core (核心)
+├── ConfigManager - 为其他系统提供配置数据
+├── GameManager - 协调各个系统
+└── GameStartup - 初始化所有系统
+
+CombatSystem (战斗)
+├── 依赖 Core/ConfigManager 获取武器和敌人配置
+└── 可被 LevelSystem 调用来管理战斗状态
+
+LevelSystem (关卡)
+├── 依赖 Core/GameManager 进行场景切换
+└── 调用 CombatSystem 管理战斗进程
+
+ShopSystem (商店)
+├── 依赖 Core/ConfigManager 获取武器信息
+└── 影响 CombatSystem 的武器可用性
+```
+
+## 📋 import 路径规范
+
+### CombatSystem 中的 import
+```typescript
+import { ConfigManager } from '../Core/ConfigManager';
+import { GameManager } from '../Core/GameManager';
+```
+
+### LevelSystem 中的 import
+```typescript
+import { GameManager } from '../Core/GameManager';
+import { ConfigManager } from '../Core/ConfigManager';
+```
+
+### ShopSystem 中的 import
+```typescript
+import { ConfigManager } from '../Core/ConfigManager';
+```
+
+### Core 系统内部 import
+```typescript
+// Core 系统内部可以直接相对引用
+import { ConfigManager } from './ConfigManager';
+```
+
+## 🚀 系统功能说明
+
+### CombatSystem 功能
+- ✅ 武器系统:支持多种武器类型和配置
+- ✅ 敌人系统:支持不同类型敌人和Spine动画
+- ✅ 战斗机制:子弹、碰撞、伤害计算
+- ✅ 方块管理:游戏场景中的方块控制
+
+### Core 功能
+- ✅ 配置管理:武器和敌人的JSON配置加载
+- ✅ 游戏管理:场景切换、游戏状态管理
+- ✅ 物理管理:物理系统初始化
+
+### LevelSystem 功能
+- ✅ 关卡进度:保存/加载关卡完成状态
+- ✅ 星级系统:记录最佳成绩和星级
+- ✅ 解锁机制:关卡解锁逻辑
+
+### ShopSystem 功能
+- ✅ 货币系统:金币和宝石管理
+- ✅ 物品购买:武器、升级、消耗品
+- ✅ 购买限制:次数限制和价格检查
+- ✅ 数据持久化:购买记录保存
+
+## 🔧 使用说明
+
+1. **Core系统** - 在游戏启动时首先初始化
+2. **CombatSystem** - 在游戏场景中使用,处理战斗逻辑
+3. **LevelSystem** - 在关卡选择和完成时使用
+4. **ShopSystem** - 在商店界面中使用
+
+## 📝 开发注意事项
+
+1. 所有系统都应该通过 Core 系统进行通信
+2. 避免跨系统的直接依赖(除了对Core的依赖)
+3. 新增功能时,请按照模块划分添加到对应文件夹
+4. 保持 import 路径的一致性和正确性
+
+## 🎯 下一步开发计划
+
+- [ ] 完善 LevelSystem 的关卡配置和管理
+- [ ] 扩展 ShopSystem 的物品类型和效果
+- [ ] 优化 CombatSystem 的性能和特效
+- [ ] 添加音频系统到 Core 模块 

+ 360 - 0
assets/scripts/ShopSystem/ShopManager.ts

@@ -0,0 +1,360 @@
+import { _decorator, Component, sys } from 'cc';
+import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
+const { ccclass, property } = _decorator;
+
+/**
+ * 商店物品接口
+ */
+export interface ShopItem {
+    id: string;
+    name: string;
+    type: 'weapon' | 'upgrade' | 'consumable';
+    price: number;
+    currency: 'coin' | 'gem';
+    weaponId?: string; // 如果是武器类型
+    description: string;
+    icon: string;
+    available: boolean;
+    purchased: boolean;
+    maxPurchases?: number; // 最大购买次数,-1为无限
+    currentPurchases?: number; // 当前购买次数
+}
+
+/**
+ * 商店管理器
+ * 负责物品购买、货币管理等功能
+ */
+@ccclass('ShopManager')
+export class ShopManager extends Component {
+    private static instance: ShopManager = null;
+    
+    private coins: number = 100; // 初始金币
+    private gems: number = 10;   // 初始宝石
+    private shopItems: ShopItem[] = [];
+    private purchasedItems: string[] = [];
+
+    onLoad() {
+        if (ShopManager.instance === null) {
+            ShopManager.instance = this;
+            this.loadShopData();
+            this.initializeShopItems();
+        } else if (ShopManager.instance !== this) {
+            this.destroy();
+            return;
+        }
+    }
+
+    onDestroy() {
+        if (ShopManager.instance === this) {
+            ShopManager.instance = null;
+        }
+    }
+
+    public static getInstance(): ShopManager {
+        return ShopManager.instance;
+    }
+
+    // 初始化商店物品
+    private initializeShopItems() {
+        // 基础武器商店物品
+        this.shopItems = [
+            {
+                id: 'weapon_basic_gun',
+                name: '基础手枪',
+                type: 'weapon',
+                price: 50,
+                currency: 'coin',
+                weaponId: 'basic_gun',
+                description: '基础的射击武器,伤害适中',
+                icon: 'shop/weapon_basic_gun',
+                available: true,
+                purchased: false,
+                maxPurchases: 1,
+                currentPurchases: 0
+            },
+            {
+                id: 'weapon_sniper',
+                name: '狙击枪',
+                type: 'weapon',
+                price: 150,
+                currency: 'coin',
+                weaponId: 'sniper_rifle',
+                description: '高伤害远程武器',
+                icon: 'shop/weapon_sniper',
+                available: true,
+                purchased: false,
+                maxPurchases: 1,
+                currentPurchases: 0
+            },
+            {
+                id: 'weapon_rocket',
+                name: '火箭筒',
+                type: 'weapon',
+                price: 5,
+                currency: 'gem',
+                weaponId: 'rocket_launcher',
+                description: '范围爆炸伤害武器',
+                icon: 'shop/weapon_rocket',
+                available: true,
+                purchased: false,
+                maxPurchases: 1,
+                currentPurchases: 0
+            },
+            {
+                id: 'upgrade_damage',
+                name: '伤害提升',
+                type: 'upgrade',
+                price: 100,
+                currency: 'coin',
+                description: '永久增加所有武器10%伤害',
+                icon: 'shop/upgrade_damage',
+                available: true,
+                purchased: false,
+                maxPurchases: 5,
+                currentPurchases: 0
+            },
+            {
+                id: 'consumable_health_potion',
+                name: '生命药水',
+                type: 'consumable',
+                price: 20,
+                currency: 'coin',
+                description: '恢复50点生命值',
+                icon: 'shop/health_potion',
+                available: true,
+                purchased: false,
+                maxPurchases: -1, // 无限购买
+                currentPurchases: 0
+            }
+        ];
+    }
+
+    // 加载商店数据
+    private loadShopData() {
+        const savedData = sys.localStorage.getItem('shopData');
+        if (savedData) {
+            try {
+                const data = JSON.parse(savedData);
+                this.coins = data.coins || 100;
+                this.gems = data.gems || 10;
+                this.purchasedItems = data.purchasedItems || [];
+                console.log('商店数据加载成功');
+            } catch (error) {
+                console.error('商店数据解析失败:', error);
+                this.resetShopData();
+            }
+        }
+    }
+
+    // 保存商店数据
+    private saveShopData() {
+        const data = {
+            coins: this.coins,
+            gems: this.gems,
+            purchasedItems: this.purchasedItems,
+            shopItems: this.shopItems.map(item => ({
+                id: item.id,
+                purchased: item.purchased,
+                currentPurchases: item.currentPurchases
+            }))
+        };
+        
+        try {
+            sys.localStorage.setItem('shopData', JSON.stringify(data));
+            console.log('商店数据保存成功');
+        } catch (error) {
+            console.error('商店数据保存失败:', error);
+        }
+    }
+
+    // 重置商店数据
+    private resetShopData() {
+        this.coins = 100;
+        this.gems = 10;
+        this.purchasedItems = [];
+        this.saveShopData();
+    }
+
+    // 获取金币数量
+    public getCoins(): number {
+        return this.coins;
+    }
+
+    // 获取宝石数量
+    public getGems(): number {
+        return this.gems;
+    }
+
+    // 添加金币
+    public addCoins(amount: number) {
+        this.coins += amount;
+        this.saveShopData();
+        console.log(`获得 ${amount} 金币,总计: ${this.coins}`);
+    }
+
+    // 添加宝石
+    public addGems(amount: number) {
+        this.gems += amount;
+        this.saveShopData();
+        console.log(`获得 ${amount} 宝石,总计: ${this.gems}`);
+    }
+
+    // 消费金币
+    public spendCoins(amount: number): boolean {
+        if (this.coins >= amount) {
+            this.coins -= amount;
+            this.saveShopData();
+            console.log(`消费 ${amount} 金币,剩余: ${this.coins}`);
+            return true;
+        }
+        console.warn(`金币不足,需要 ${amount},当前 ${this.coins}`);
+        return false;
+    }
+
+    // 消费宝石
+    public spendGems(amount: number): boolean {
+        if (this.gems >= amount) {
+            this.gems -= amount;
+            this.saveShopData();
+            console.log(`消费 ${amount} 宝石,剩余: ${this.gems}`);
+            return true;
+        }
+        console.warn(`宝石不足,需要 ${amount},当前 ${this.gems}`);
+        return false;
+    }
+
+    // 获取所有商店物品
+    public getShopItems(): ShopItem[] {
+        return this.shopItems.filter(item => item.available);
+    }
+
+    // 获取特定类型的商店物品
+    public getShopItemsByType(type: 'weapon' | 'upgrade' | 'consumable'): ShopItem[] {
+        return this.shopItems.filter(item => item.type === type && item.available);
+    }
+
+    // 获取单个商店物品
+    public getShopItem(itemId: string): ShopItem | null {
+        return this.shopItems.find(item => item.id === itemId) || null;
+    }
+
+    // 检查是否可以购买物品
+    public canPurchaseItem(itemId: string): boolean {
+        const item = this.getShopItem(itemId);
+        if (!item || !item.available) return false;
+
+        // 检查购买次数限制
+        if (item.maxPurchases !== -1 && item.currentPurchases >= item.maxPurchases) {
+            return false;
+        }
+
+        // 检查货币是否足够
+        if (item.currency === 'coin') {
+            return this.coins >= item.price;
+        } else if (item.currency === 'gem') {
+            return this.gems >= item.price;
+        }
+
+        return false;
+    }
+
+    // 购买物品
+    public purchaseItem(itemId: string): boolean {
+        const item = this.getShopItem(itemId);
+        if (!item || !this.canPurchaseItem(itemId)) {
+            console.warn(`无法购买物品: ${itemId}`);
+            return false;
+        }
+
+        // 消费货币
+        let success = false;
+        if (item.currency === 'coin') {
+            success = this.spendCoins(item.price);
+        } else if (item.currency === 'gem') {
+            success = this.spendGems(item.price);
+        }
+
+        if (success) {
+            // 更新购买状态
+            item.currentPurchases = (item.currentPurchases || 0) + 1;
+            
+            if (item.maxPurchases !== -1 && item.currentPurchases >= item.maxPurchases) {
+                item.purchased = true;
+            }
+
+            // 添加到已购买列表
+            if (this.purchasedItems.indexOf(itemId) === -1) {
+                this.purchasedItems.push(itemId);
+            }
+
+            this.saveShopData();
+            console.log(`成功购买: ${item.name}`);
+            
+            // 处理购买后的效果
+            this.applyItemEffect(item);
+            
+            return true;
+        }
+
+        return false;
+    }
+
+    // 应用物品效果
+    private applyItemEffect(item: ShopItem) {
+        switch (item.type) {
+            case 'weapon':
+                // 武器类型:解锁武器
+                console.log(`解锁武器: ${item.weaponId}`);
+                // 这里可以通知其他系统武器已解锁
+                break;
+                
+            case 'upgrade':
+                // 升级类型:应用永久效果
+                console.log(`应用升级: ${item.name}`);
+                // 这里可以修改全局属性
+                break;
+                
+            case 'consumable':
+                // 消耗品类型:立即使用
+                console.log(`使用消耗品: ${item.name}`);
+                // 这里可以应用临时效果
+                break;
+        }
+    }
+
+    // 检查物品是否已购买
+    public isItemPurchased(itemId: string): boolean {
+        return this.purchasedItems.indexOf(itemId) !== -1;
+    }
+
+    // 获取已购买的武器列表
+    public getPurchasedWeapons(): string[] {
+        const purchasedWeaponItems = this.shopItems.filter(item => 
+            item.type === 'weapon' && this.isItemPurchased(item.id)
+        );
+        return purchasedWeaponItems.map(item => item.weaponId).filter(id => id);
+    }
+
+    // 重置所有购买记录(调试用)
+    public resetPurchases() {
+        this.shopItems.forEach(item => {
+            item.purchased = false;
+            item.currentPurchases = 0;
+        });
+        this.purchasedItems = [];
+        this.saveShopData();
+        console.log('所有购买记录已重置');
+    }
+
+    // 添加免费金币(调试用)
+    public addFreeCoins(amount: number = 1000) {
+        this.addCoins(amount);
+        console.log(`添加免费金币: ${amount}`);
+    }
+
+    // 添加免费宝石(调试用)
+    public addFreeGems(amount: number = 100) {
+        this.addGems(amount);
+        console.log(`添加免费宝石: ${amount}`);
+    }
+} 

+ 9 - 0
assets/scripts/ShopSystem/ShopManager.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "2caeab67-10d0-4696-803a-ca2cb45880b9",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}