Browse Source

局内引导完成

181404010226 1 month ago
parent
commit
f6d34eaf41

+ 23 - 5
assets/NewbieGuidePlugin-v1.0.0/NewbieGuidePlugin-v1.0.0/scripts/GuideUIController.ts

@@ -225,6 +225,24 @@ export class GuideUIController extends Component {
         if (!this.fingerStartNodes[5]) {
             this.fingerStartNodes[5] = this.guideStepsTargets[5] ?? null;
         }
+        
+        // Step 6: 第七步,与第三步相同 —— 确认按钮
+        if (!this.guideStepsTargets[6]) {
+            const confirmButton = find('Canvas/GameLevelUI/BlockSelectionUI/diban/confirm');
+            if (!confirmButton) {
+                console.warn('[GuideUIController] Confirm button node not found for step 7');
+            }
+            this.guideStepsTargets[6] = this.guideStepsTargets[6] ?? confirmButton ?? null;
+        }
+        this.guideStepsActions[6] = this.guideStepsActions[6] ?? 'wait_event';
+        this.guideStepsEvents[6] = this.guideStepsEvents[6] ?? 'BLOCK_SELECTION_CONFIRMED';
+        // 遮罩与Frame与第三步复用
+        if (!this.guideStepsMaskAreas[6] && this.guideStepsMaskAreas[2]) {
+            this.guideStepsMaskAreas[6] = this.guideStepsMaskAreas[2];
+        }
+        if (!this.guideStepsFrameDecorators[6] && this.guideStepsFrameDecorators[2]) {
+            this.guideStepsFrameDecorators[6] = this.guideStepsFrameDecorators[2];
+        }
 
         console.log('[GuideUIController] Tutorial steps ensured (editor config first, find as fallback)');
     }
@@ -729,8 +747,8 @@ export class GuideUIController extends Component {
                     console.warn('[GuideUIController] 未找到Grid_3_1,使用普通指向动画');
                 }
             }
-        } else if (idx === 2 && action === 'wait_event') {
-            // 第三步:将手指(guild_1)放到确认按钮右下角,并让手指原地缩放
+        } else if ((idx === 2 || idx === 6) && action === 'wait_event') {
+            // 第三步或第七步:将手指(guild_1)放到确认按钮右下角,并让手指原地缩放
             if (this._activeBlinkComp) {
                 this._activeBlinkComp.stop();
                 this._activeBlinkComp = null;
@@ -767,7 +785,7 @@ export class GuideUIController extends Component {
                     easingUp: 'sineOut',
                     easingDown: 'sineIn'
                 });
-                console.log('[GuideUIController] 第三步:手指位于按钮右下角并进行缩放闪烁');
+                console.log('[GuideUIController] 第三/七步:手指位于按钮右下角并进行缩放闪烁');
             } else {
                 console.warn('[GuideUIController] 未找到 guild_1 手指节点');
                 // 兜底使用普通指向动画
@@ -837,7 +855,7 @@ export class GuideUIController extends Component {
         // 清理事件监听/计时器
         this.clearCurrentStepListeners();
     
-        // 进入下一步(第三步结束后延迟3秒再触发第四步;第四步结束等待第二次方块放置再触发第五步)
+        // 进入下一步(第三步结束后延迟5秒再触发第四步;第四步结束等待第二次方块放置再触发第五步)
         const prevIndex = this._currentStepIndex;
         this._currentStepIndex++;
         const nextIndex = this._currentStepIndex;
@@ -853,7 +871,7 @@ export class GuideUIController extends Component {
                 this._autoScheduleCallback = null;
                 this.runCurrentStep();
             };
-            this.scheduleOnce(this._autoScheduleCallback as any, 3.0);
+            this.scheduleOnce(this._autoScheduleCallback as any, 5.0);
         } else if (prevIndex === 3 && nextIndex === 4) {
             // 第四步完成后不要立刻开始第五步,等待第二次方块放置开始
             const bus = EventBus.getInstance();

+ 22 - 3
assets/Scenes/GameLevel.scene

@@ -47763,9 +47763,21 @@
       },
       {
         "__id__": 1378
+      },
+      {
+        "__id__": 1032
+      },
+      {
+        "__id__": 1045
+      },
+      {
+        "__id__": 1135
       }
     ],
     "guideStepsActions": [
+      "wait_event",
+      "wait_event",
+      "wait_event",
       "wait_event",
       "wait_event",
       "wait_event",
@@ -47775,7 +47787,9 @@
       "TUTORIAL_BLOCK_1_PLACED",
       "TUTORIAL_BLOCK_2_PLACED",
       "BLOCK_SELECTION_CONFIRMED",
-      "TUTORIAL_BLOCK_3_PLACED"
+      "TUTORIAL_BLOCK_3_PLACED",
+      "TUTORIAL_BLOCK_4_PLACED",
+      "TUTORIAL_BLOCK_5_PLACED"
     ],
     "guideStepsMaskAreas": [
       {
@@ -47795,6 +47809,9 @@
       },
       {
         "__id__": 1381
+      },
+      {
+        "__id__": 1358
       }
     ],
     "guideStepsFrameDecorators": [
@@ -47813,7 +47830,8 @@
       },
       {
         "__id__": 1378
-      }
+      },
+      null
     ],
     "fingerStartNodes": [
       {
@@ -47829,7 +47847,8 @@
       },
       {
         "__id__": 1045
-      }
+      },
+      null
     ],
     "fingerTargetNodes": [
       {

BIN
assets/data/excel/__pycache__/level_config_manager.cpython-313.pyc


+ 1 - 1
assets/data/levels/Level1.json

@@ -20,7 +20,7 @@
       "enemies": [
         {
           "enemyType": "normal_zombie",
-          "count": 2,
+          "count": 5,
           "spawnInterval": 1.0,
           "spawnDelay": 0.0,
           "characteristics": "中速移动, 无技能",

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

@@ -940,6 +940,16 @@ export class BlockManager extends Component {
         }
     }
 
+    // 新增:教程阶段对场上已放置方块的移动控制
+    public canMovePlacedBlocks(): boolean {
+        try {
+            // 仅在第4步允许移动,或第6步完成(_tutorialStep >= 7)后恢复自由移动
+            return this._tutorialStep === 4 || this._tutorialStep >= 7;
+        } catch (e) {
+            return true;
+        }
+    }
+
     /**
      * 新手引导下为第 i 个容器选择固定形状(I、S、L),并确保形状在该武器可用
      */
@@ -1292,6 +1302,50 @@ export class BlockManager extends Component {
                 return false;
             }
         }
+
+        // 扩展教程(第5-6步):只允许拖到指定格子
+        if (this._tutorialStep >= 5 && this._tutorialStep < 7) {
+            const basePair = this._tutorialStep >= 6 ? this._tutorialTargetGridsStep4 : this._tutorialTargetGridsStep2;
+            if (basePair && basePair.length === 2) {
+                const parse = (name: string) => {
+                    const m = name.match(/^Grid_(\d+)_(\d+)$/);
+                    return m ? { row: parseInt(m[1]), col: parseInt(m[2]) } : null;
+                };
+                const pairKey = (arr: string[]) => arr.slice().sort().join('|');
+                const p0 = parse(basePair[0]);
+                const p1 = parse(basePair[1]);
+                if (p0 && p1) {
+                    let anchor = p0;
+                    if (p0.row !== p1.row) {
+                        anchor = p0.row < p1.row ? p0 : p1;
+                    } else if (p0.col !== p1.col) {
+                        anchor = p0.col < p1.col ? p0 : p1;
+                    }
+                    const horizontalPair = [`Grid_${anchor.row}_${anchor.col}`, `Grid_${anchor.row}_${anchor.col + 1}`];
+                    const verticalPair = [`Grid_${anchor.row}_${anchor.col}`, `Grid_${anchor.row + 1}_${anchor.col}`];
+                    const allowedPairs = new Set<string>([
+                        pairKey(horizontalPair),
+                        pairKey(verticalPair),
+                        pairKey(basePair),
+                    ]);
+                    const targetRowCol = this.getGridRowCol(nearestGrid);
+                    if (!targetRowCol) return false;
+                    const parts = this.getBlockParts(block);
+                    const occupiedNames: string[] = [];
+                    for (let i = 0; i < parts.length; i++) {
+                        const part = parts[i];
+                        const row = targetRowCol.row - part.y;
+                        const col = targetRowCol.col + part.x;
+                        occupiedNames.push(`Grid_${row}_${col}`);
+                    }
+                    const occupiedKey = pairKey(occupiedNames);
+                    if (!allowedPairs.has(occupiedKey)) {
+                        console.log(`[BlockManager] 扩展教程:方块不能放置到此网格`);
+                        return false;
+                    }
+                }
+            }
+        }
         
         return this.tryPlaceBlockToSpecificGrid(block, nearestGrid);
     }
@@ -2864,6 +2918,22 @@ export class BlockManager extends Component {
             // 注意:参与合成的方块都在网格中,它们的db标签本来就应该是隐藏的
             // 不需要调用hideDbLabel,因为这些方块已经不在block容器中了
 
+            // 在扩展教程(第5-6步)中,合成即可视为完成,触发教程完成判断
+            if (this.isExtendedTutorialEventContext()) {
+                let gridNode: Node | null = null;
+                const occupied = (target as any)['occupiedGrids'];
+                if (occupied && occupied.length > 0) {
+                    const first = occupied[0];
+                    if (first && this.gridNodes[first.row] && this.gridNodes[first.row][first.col]) {
+                        gridNode = this.gridNodes[first.row][first.col];
+                    }
+                }
+                // 如果能定位到目标格子,则用源方块+该格子进行教程完成判定
+                if (gridNode) {
+                    this.handleTutorialBlockPlacement(source, gridNode);
+                }
+            }
+
             // 销毁被合并方块
             source.destroy();
 
@@ -3101,6 +3171,43 @@ export class BlockManager extends Component {
             console.log(`[BlockManager] 检查方块碰撞`);
             if (this.rectIntersects(dragBB, targetBB)) {
                 console.log(`[BlockManager] 方块重叠,执行合成`);
+                // 扩展教程(第5-6步):仅允许在指定格子处合成
+                if (this._tutorialStep >= 5 && this._tutorialStep < 7) {
+                    const basePair = this._tutorialStep >= 6 ? this._tutorialTargetGridsStep4 : this._tutorialTargetGridsStep2;
+                    if (basePair && basePair.length === 2) {
+                        const pairKey = (arr: string[]) => arr.slice().sort().join('|');
+                        const occupied = (target as any)['occupiedGrids'] as { row: number, col: number }[] | undefined;
+                        if (occupied && occupied.length >= 2) {
+                            const occupiedNames = occupied.map(g => `Grid_${g.row}_${g.col}`);
+                            const parse = (name: string) => {
+                                const m = name.match(/^Grid_(\d+)_(\d+)$/);
+                                return m ? { row: parseInt(m[1]), col: parseInt(m[2]) } : null;
+                            };
+                            const p0 = parse(basePair[0]);
+                            const p1 = parse(basePair[1]);
+                            if (p0 && p1) {
+                                let anchor = p0;
+                                if (p0.row !== p1.row) {
+                                    anchor = p0.row < p1.row ? p0 : p1;
+                                } else if (p0.col !== p1.col) {
+                                    anchor = p0.col < p1.col ? p0 : p1;
+                                }
+                                const horizontalPair = [`Grid_${anchor.row}_${anchor.col}`, `Grid_${anchor.row}_${anchor.col + 1}`];
+                                const verticalPair = [`Grid_${anchor.row}_${anchor.col}`, `Grid_${anchor.row + 1}_${anchor.col}`];
+                                const allowedPairs = new Set<string>([
+                                    pairKey(horizontalPair),
+                                    pairKey(verticalPair),
+                                    pairKey(basePair),
+                                ]);
+                                const occupiedKey = pairKey(occupiedNames);
+                                if (!allowedPairs.has(occupiedKey)) {
+                                    console.log(`[BlockManager] 扩展教程:目标位置不在要求格子,禁止合成`);
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                }
                 // 执行合并:目标保留,拖拽方块销毁
                 this.performMerge(target, draggedBlock, rarity);
                 return true;

+ 8 - 2
assets/scripts/CombatSystem/BlockSelection/GameBlockSelection.ts

@@ -823,7 +823,10 @@ export class GameBlockSelection extends Component {
             // 只对grid区域的方块检查移动限制,kuang区域的方块可以自由拖拽
             const blockLocation = this.blockManager.blockLocations.get(block);
             
-            // grid区域的方块目前允许自由移动
+            // 教程阶段:第6步结束前禁止移动已上阵方块(第4步除外)
+            if (blockLocation === 'grid' && !this.blockManager.canMovePlacedBlocks()) {
+                return;
+            }
             
             if (!this.currentDragBlock) return;
             
@@ -847,7 +850,10 @@ export class GameBlockSelection extends Component {
             // 只对grid区域的方块检查移动限制,kuang区域的方块可以自由拖拽
             const blockLocation = this.blockManager.blockLocations.get(block);
             
-            // grid区域的方块目前允许自由移动
+            // 教程阶段:第6步结束前禁止移动已上阵方块(第4步除外)
+            if (blockLocation === 'grid' && !this.blockManager.canMovePlacedBlocks()) {
+                return;
+            }
             
             if (this.currentDragBlock) {
                 try {