Browse Source

敌人线处生成和NavBar

181404010226 5 months ago
parent
commit
3ead95ddcd

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


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

@@ -60,7 +60,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -114,7 +114,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -161,7 +161,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -252,7 +252,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,

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

@@ -60,7 +60,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -114,7 +114,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -161,7 +161,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -252,7 +252,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,

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

@@ -60,7 +60,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -117,7 +117,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -164,7 +164,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -252,7 +252,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -343,7 +343,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,

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

@@ -60,7 +60,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -120,7 +120,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -167,7 +167,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -255,7 +255,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -343,7 +343,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -434,7 +434,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,

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

@@ -60,7 +60,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -120,7 +120,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -167,7 +167,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -255,7 +255,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -343,7 +343,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,
@@ -434,7 +434,7 @@
       "z": 1
     },
     "_mobility": 0,
-    "_layer": 33554432,
+    "_layer": 1073741824,
     "_euler": {
       "__type__": "cc.Vec3",
       "x": 0,

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

@@ -292,12 +292,22 @@ export class EnemyController extends BaseSingleton {
         
         enemyContainer.addChild(enemy);
         
-        // 设置敌人位置
-        const xPos = this.gameBounds.left + Math.random() * (this.gameBounds.right - this.gameBounds.left);
-        const yPos = fromTop ? this.gameBounds.top + 100 : this.gameBounds.bottom - 100;
-        
-        // 将世界坐标转换为相对于enemyContainer的本地坐标
-        const localPos = enemyContainer.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(xPos, yPos, 0));
+        // 生成在对应线(Line1 / Line2)上的随机位置
+        const lineName = fromTop ? 'Line1' : 'Line2';
+        const lineNode = enemyContainer.getChildByName(lineName);
+
+        if (!lineNode) {
+            console.warn(`[EnemyController] 未找到 ${lineName} 节点,取消本次敌人生成`);
+            enemy.destroy();
+            return;
+        }
+
+        // 在对应 line 上随机 X 坐标
+        const spawnWorldX = this.gameBounds.left + Math.random() * (this.gameBounds.right - this.gameBounds.left);
+        const spawnWorldY = lineNode.worldPosition.y;
+
+        const worldPos = new Vec3(spawnWorldX, spawnWorldY, 0);
+        const localPos = enemyContainer.getComponent(UITransform).convertToNodeSpaceAR(worldPos);
         enemy.position = localPos;
         
         // === 根据配置设置敌人 ===
@@ -330,6 +340,10 @@ export class EnemyController extends BaseSingleton {
             enemyComp.attackPower = this.defaultAttackPower;
         }
 
+        // 额外的属性设置
+        enemyComp.spawnFromTop = fromTop;
+        enemyComp.targetFence = find(fromTop ? 'Canvas/GameLevelUI/GameArea/TopFence' : 'Canvas/GameLevelUI/GameArea/BottomFence');
+
         enemyComp.movingDirection = Math.random() > 0.5 ? 1 : -1;
         enemyComp.targetY = fromTop ? this.gameBounds.top - 50 : this.gameBounds.bottom + 50;
         enemyComp.changeDirectionTime = 0;

+ 25 - 9
assets/scripts/CombatSystem/EnemyInstance.ts

@@ -29,6 +29,12 @@ export class EnemyInstance extends Component {
     public speed: number = 50;
     public attackPower: number = 10;
     
+    // === 新增属性 ===
+    /** 是否从上方生成 */
+    public spawnFromTop: boolean = true;
+    /** 目标 Fence 节点(TopFence / BottomFence) */
+    public targetFence: Node | null = null;
+    
     // 移动属性
     public movingDirection: number = 1; // 1: 向右, -1: 向左
     public targetY: number = 0; // 目标Y位置
@@ -235,16 +241,26 @@ export class EnemyInstance extends Component {
 
     // 移动到目标位置
     private moveTowardsTarget(deltaTime: number) {
-        const currentPos = this.node.position;
-        
-        // 简单的向中心移动
-        const targetPos = new Vec3(0, 0, 0); // 移动到中心
-        const direction = targetPos.subtract(currentPos).normalize();
-        
-        // 应用移动
+        // 使用世界坐标进行移动计算,确保不受父节点坐标系影响
+        const currentWorldPos = this.node.worldPosition.clone();
+
+        // 目标世界坐标:优先使用指定的 Fence,其次退化到游戏区域中心
+        let targetWorldPos: Vec3;
+        if (this.targetFence && this.targetFence.isValid) {
+            targetWorldPos = this.targetFence.worldPosition.clone();
+        } else {
+            targetWorldPos = this.gameAreaCenter.clone();
+        }
+
+        const dir = targetWorldPos.subtract(currentWorldPos);
+        if (dir.length() === 0) return;
+        dir.normalize();
+
         const moveDistance = this.speed * deltaTime;
-        const newPos = currentPos.add(direction.multiplyScalar(moveDistance));
-        this.node.position = newPos;
+        const newWorldPos = currentWorldPos.add(dir.multiplyScalar(moveDistance));
+
+        // 直接设置世界坐标
+        this.node.setWorldPosition(newWorldPos);
     }
 
     // 更新攻击逻辑

+ 8 - 8
assets/scripts/Core/PhysicsManager.ts

@@ -22,14 +22,14 @@ export class PhysicsManager extends BaseSingleton {
         // 设置物理系统的重力为零(因为是2D平面游戏)
         PhysicsSystem2D.instance.gravity = new Vec2(0, 0);
         
-        // // // 调试绘制
-        PhysicsSystem2D.instance.debugDrawFlags = this.debugDraw ?
-            (EPhysics2DDrawFlags.Aabb |
-             EPhysics2DDrawFlags.Pair |
-             EPhysics2DDrawFlags.CenterOfMass |
-             EPhysics2DDrawFlags.Joint |
-             EPhysics2DDrawFlags.Shape) :
-            EPhysics2DDrawFlags.None;
+        // // // // 调试绘制
+        // PhysicsSystem2D.instance.debugDrawFlags = this.debugDraw ?
+        //     (EPhysics2DDrawFlags.Aabb |
+        //      EPhysics2DDrawFlags.Pair |
+        //      EPhysics2DDrawFlags.CenterOfMass |
+        //      EPhysics2DDrawFlags.Joint |
+        //      EPhysics2DDrawFlags.Shape) :
+        //     EPhysics2DDrawFlags.None;
     }
 
     /**

+ 9 - 0
assets/scripts/FourUI.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "7fb4b205-2faa-49f9-bd78-b8fec6724b17",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 9 - 0
assets/scripts/FourUI/MainSystem.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "37a77d2f-466d-4c2c-9a6e-8a2ad3020edb",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 13 - 13
assets/scripts/LevelSystem/MainUIController.ts → assets/scripts/FourUI/MainSystem/MainUIControlller.ts

@@ -1,8 +1,8 @@
 // MainUIController.ts
 import { _decorator, Component, Node, Button, Label, find } from 'cc';
-import { SaveDataManager } from './SaveDataManager';
-import { GameManager } from './GameManager';
-import { GameStartMove } from '../Animations/GameStartMove';
+import { SaveDataManager } from '../../LevelSystem/SaveDataManager';
+import { GameManager } from '../../LevelSystem/GameManager';
+import { GameStartMove } from '../../Animations/GameStartMove';
 const { ccclass, property } = _decorator;
 
 @ccclass('MainUIController')
@@ -26,9 +26,7 @@ export class MainUIController extends Component {
   /* 主功能按钮 */
   @property(Node) battleBtn: Node = null;            // 战斗
   @property(Node) shopBtn: Node = null;              // 商店
-  @property(Node) navUpgradeBtn: Node = null;        // 底栏 UPGRADE
-  @property(Node) navBattleBtn: Node = null;         // 底栏 BATTLE
-  @property(Node) navSkillBtn: Node = null;          // 底栏 SKILL
+  // 底栏按钮由 NavBarController 统一管理,这里不再需要引用
   @property(Node) topArea: Node = null;              // Canvas-001/TopArea
 
   private sdm: SaveDataManager = null;
@@ -59,10 +57,7 @@ export class MainUIController extends Component {
     this.battleBtn?.on(Button.EventType.CLICK, this.onBattle, this);
     this.shopBtn?.on(Button.EventType.CLICK, this.onShop, this);
 
-    // 底栏按钮暂只打印
-    this.navUpgradeBtn?.on(Button.EventType.CLICK, () => console.log('底栏 UPGRADE'), this);
-    this.navBattleBtn?.on(Button.EventType.CLICK, () => console.log('底栏 BATTLE'), this);
-    this.navSkillBtn?.on(Button.EventType.CLICK, () => console.log('底栏 SKILL'), this);
+    // 底栏按钮已迁移至 NavBarController,无需在此脚本绑定
   }
 
   /* ================= 业务逻辑 ================= */
@@ -106,6 +101,9 @@ export class MainUIController extends Component {
   }
 
   private onBattle () {
+    // 显示 TopArea(拖拽引用),避免使用 find()
+    if (this.topArea) this.topArea.active = true;
+
     // 若上一关已完成则自动+1
     const lvl = this.sdm.getCurrentLevel();
     if (this.sdm.isLevelCompleted(lvl)) {
@@ -126,12 +124,14 @@ export class MainUIController extends Component {
     gm?.restartGame();
     gm?.loadCurrentLevelConfig();
 
-    // 显示 TopArea(拖拽引用),避免使用 find()
-    if (this.topArea) this.topArea.active = true;
+ 
+    // 隐藏底部导航栏 NavBar
+    const navBarNode = find('Canvas/NavBar');
+    if (navBarNode) navBarNode.active = false;
 
     // Camera move down instantly for battle prep
     // 兼容 "Camera" 或 "Main Camera" 等命名
-    const camNode = find('Main Camera') || find('Camera') || find('Canvas/Camera');
+    const camNode = find('Canvas/Camera');
     const gsm = camNode?.getComponent(GameStartMove);
     gsm?.moveDownInstant();
   }

+ 1 - 1
assets/scripts/LevelSystem/MainUIController.ts.meta → assets/scripts/FourUI/MainSystem/MainUIControlller.ts.meta

@@ -2,7 +2,7 @@
   "ver": "4.0.24",
   "importer": "typescript",
   "imported": true,
-  "uuid": "725f5db8-abb6-4a81-8702-b08eb87709fd",
+  "uuid": "f53de50a-484e-40a9-999a-eb101d6cc9a9",
   "files": [],
   "subMetas": {},
   "userData": {}

+ 31 - 0
assets/scripts/FourUI/NavBarController.ts

@@ -0,0 +1,31 @@
+import { _decorator, Color, Component, Node, Sprite } from 'cc';
+const { ccclass, property } = _decorator;
+
+@ccclass('NavBarController')
+export class NavBarController extends Component {
+    @property({ type: [Node] }) panels: Node[] = [];      // 依次给 Main、Shop、Upgrade、Skill
+    @property({ type: [Node] }) buttons: Node[] = [];     // 依次给 Battle、Shop、Upgrade、Skill
+    private normalColor = new Color(255, 255, 255, 255);
+    private activeColor = new Color(255, 0, 0, 255);      // 红色
+
+    start () {
+        // 默认打开 MainUI
+        this.switchTo(0);
+    }
+
+    onBattleClick ()  { this.switchTo(0); }
+    onShopClick ()    { this.switchTo(1); }
+    onUpgradeClick () { this.switchTo(2); }
+    onSkillClick ()   { this.switchTo(3); }
+
+    private switchTo (index: number) {
+        // 显示对应面板
+        this.panels.forEach((p, i) => p.active = i === index);
+
+        // 设置按钮颜色
+        this.buttons.forEach((btn, i) => {
+            const sp = btn.getComponent(Sprite);
+            if (sp) sp.color = (i === index) ? this.activeColor : this.normalColor;
+        });
+    }
+}

+ 1 - 1
assets/scripts/ShopSystem/ShopManager.ts.meta → assets/scripts/FourUI/NavBarController.ts.meta

@@ -2,7 +2,7 @@
   "ver": "4.0.24",
   "importer": "typescript",
   "imported": true,
-  "uuid": "2caeab67-10d0-4696-803a-ca2cb45880b9",
+  "uuid": "351a1c3e-5b42-4f9c-98e9-56f3595db104",
   "files": [],
   "subMetas": {},
   "userData": {}

+ 0 - 0
assets/scripts/ShopSystem.meta → assets/scripts/FourUI/ShopSystem.meta


+ 9 - 0
assets/scripts/FourUI/SkillSystem.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "dc9af37c-a825-4646-8812-bb25463bb274",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 9 - 0
assets/scripts/FourUI/UpgradeSystem.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "4be6b80b-5522-46de-bff4-32345a40f47d",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 8 - 9
assets/scripts/LevelSystem/GameManager.ts

@@ -2,12 +2,11 @@ import { _decorator, Component, Node, Prefab, instantiate, Vec3, find, director,
 import { LevelManager } from './LevelManager';
 import { LevelConfigManager } from './LevelConfigManager';
 import { SaveDataManager } from './SaveDataManager';
-import { ShopManager } from '../ShopSystem/ShopManager';
+// import { ShopManager } from '../ShopSystem/ShopManager';
 import { ConfigManager } from '../Core/ConfigManager';
 import { EnemyController } from '../CombatSystem/EnemyController';
 import EventBus, { GameEvents } from '../Core/EventBus';
 import { PhysicsManager } from '../Core/PhysicsManager';
-import { MainUIController } from './MainUIController';
 import { BallController } from '../CombatSystem/BallController';
 import { BlockManager } from '../CombatSystem/BlockManager';
 import { LevelSessionManager } from '../Core/LevelSessionManager';
@@ -112,7 +111,7 @@ export class GameManager extends Component {
     private levelManager: LevelManager = null;
     private levelConfigManager: LevelConfigManager = null;
     private saveDataManager: SaveDataManager = null;
-    private shopManager: ShopManager = null;
+    // private shopManager: ShopManager = null;
     private configManager: ConfigManager = null;
     private enemySpawningStarted: boolean = false;
     private totalEnemiesSpawned: number = 0;
@@ -216,7 +215,7 @@ export class GameManager extends Component {
     // === 管理器初始化 ===
     private initializeManagers() {
         this.levelManager = LevelManager.getInstance();
-        this.shopManager = ShopManager.getInstance();
+        // this.shopManager = ShopManager.getInstance();
         this.configManager = ConfigManager.getInstance();
         this.levelConfigManager = LevelConfigManager.getInstance();
         this.enemyController = EnemyController.getInstance() || null;
@@ -729,9 +728,9 @@ export class GameManager extends Component {
         if (mainUI) mainUI.active = true;
         
         // 更新主界面
-        const mainUIController = mainUI?.getComponent(MainUIController);
-        if (mainUIController) {
-            mainUIController.updateUI();
+        const mainUIController = mainUI?.getComponent('MainUIController' as any);
+        if (mainUIController && typeof (mainUIController as any).updateUI === 'function') {
+            (mainUIController as any).updateUI();
         }
     }
     
@@ -765,7 +764,7 @@ export class GameManager extends Component {
     // === 原GameManager方法 ===
     public onConfirmButtonClicked() {
         if (this.blockSelectionUI) {
-            const cam = find('Main Camera') || find('Camera') || find('Canvas/Camera');
+            const cam = find('Canvas/Camera');
             const gsm = cam?.getComponent(GameStartMove);
             if (gsm) {
                 gsm.slideDibanDownAndHide();
@@ -776,7 +775,7 @@ export class GameManager extends Component {
         }
 
         // Camera move back up with smooth animation
-        const camNode = find('Main Camera') || find('Camera') || find('Canvas/Camera');
+        const camNode = find('Canvas/Camera');
         const gsm = camNode?.getComponent(GameStartMove);
         gsm?.moveUpSmooth();
 

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

@@ -1,348 +0,0 @@
-import { _decorator, sys } from 'cc';
-import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
-import { BaseSingleton } from '../Core/BaseSingleton';
-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 BaseSingleton {
-    // 仅用于类型声明,实例由 BaseSingleton 维护
-    public static _instance: ShopManager;
-    
-    private coins: number = 0;
-    private gems: number = 0;
-    private purchaseHistory: any = {};
-    private itemPurchaseCounts: any = {};
-    private initialized: boolean = false;
-    private shopItems: ShopItem[] = [];
-    private purchasedItems: string[] = [];
-
-    /**
-     * BaseSingleton 首次实例化回调
-     */
-    protected init() {
-        if (!this.initialized) {
-            this.loadShopData();
-            this.initializeShopItems();
-            this.initialized = true;
-        }
-    }
-
-    // 初始化商店物品
-    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 || 0;
-                this.gems = data.gems || 0;
-                this.purchaseHistory = data.purchaseHistory || {};
-                this.itemPurchaseCounts = data.itemPurchaseCounts || {};
-                this.purchasedItems = data.purchasedItems || [];
-            } catch (error) {
-                this.resetShopData();
-            }
-        } else {
-            this.resetShopData();
-        }
-    }
-
-    // 保存商店数据
-    private saveShopData() {
-        const data = {
-            coins: this.coins,
-            gems: this.gems,
-            purchaseHistory: this.purchaseHistory,
-            itemPurchaseCounts: this.itemPurchaseCounts,
-            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));
-        } catch (error) {
-            // 静默处理保存错误
-        }
-    }
-
-    // 重置商店数据
-    private resetShopData() {
-        this.coins = 100;
-        this.gems = 10;
-        this.purchaseHistory = {};
-        this.itemPurchaseCounts = {};
-        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();
-    }
-
-    // 添加宝石
-    public addGems(amount: number) {
-        this.gems += amount;
-        this.saveShopData();
-    }
-
-    // 消费金币
-    public spendCoins(amount: number): boolean {
-        if (this.coins >= amount) {
-            this.coins -= amount;
-            this.saveShopData();
-            return true;
-        }
-        return false;
-    }
-
-    // 消费宝石
-    public spendGems(amount: number): boolean {
-        if (this.gems >= amount) {
-            this.gems -= amount;
-            this.saveShopData();
-            return true;
-        }
-        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 purchaseItem(itemId: string, price: number, currency: 'coins' | 'gems' = 'coins', maxPurchases: number = -1): boolean {
-        // 检查购买次数限制
-        if (maxPurchases > 0) {
-            const currentCount = this.itemPurchaseCounts[itemId] || 0;
-            if (currentCount >= maxPurchases) {
-                return false;
-            }
-        }
-
-        // 检查货币并扣除
-        let success = false;
-        if (currency === 'coins') {
-            success = this.spendCoins(price);
-        } else {
-            success = this.spendGems(price);
-        }
-
-        if (success) {
-            // 记录购买历史
-            if (!this.purchaseHistory[itemId]) {
-                this.purchaseHistory[itemId] = [];
-            }
-            this.purchaseHistory[itemId].push({
-                price: price,
-                currency: currency,
-                timestamp: Date.now()
-            });
-
-            // 更新购买次数
-            this.itemPurchaseCounts[itemId] = (this.itemPurchaseCounts[itemId] || 0) + 1;
-            
-            this.saveShopData();
-        }
-
-        return success;
-    }
-
-    // 获取物品购买次数
-    public getItemPurchaseCount(itemId: string): number {
-        return this.itemPurchaseCounts[itemId] || 0;
-    }
-
-    // 检查是否可以购买物品
-    public canPurchaseItem(itemId: string, price: number, currency: 'coins' | 'gems' = 'coins', maxPurchases: number = -1): boolean {
-        // 检查购买次数限制
-        if (maxPurchases > 0) {
-            const currentCount = this.itemPurchaseCounts[itemId] || 0;
-            if (currentCount >= maxPurchases) {
-                return false;
-            }
-        }
-
-        // 检查货币是否足够
-        if (currency === 'coins') {
-            return this.coins >= price;
-        } else {
-            return this.gems >= price;
-        }
-    }
-
-    // 获取购买历史
-    public getPurchaseHistory(itemId?: string): any {
-        if (itemId) {
-            return this.purchaseHistory[itemId] || [];
-        }
-        return this.purchaseHistory;
-    }
-
-    // 重置所有购买数据
-    public resetAllPurchases() {
-        this.resetShopData();
-    }
-
-    // 调试用:添加大量货币
-    public addDebugCurrency() {
-        this.coins += 10000;
-        this.gems += 1000;
-        this.saveShopData();
-    }
-
-    // 检查物品是否已购买
-    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();
-    }
-
-    // 添加免费金币(调试用)
-    public addFreeCoins(amount: number = 1000) {
-        this.addCoins(amount);
-    }
-
-    // 添加免费宝石(调试用)
-    public addFreeGems(amount: number = 100) {
-        this.addGems(amount);
-    }
-} 

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