Browse Source

完善自动模式

mojunshou 8 months ago
parent
commit
231c271800

+ 1 - 4
assets/bundle/gui/eliminate/prefab/item_none.prefab

@@ -246,10 +246,7 @@
       "b": 255,
       "a": 255
     },
-    "_spriteFrame": {
-      "__uuid__": "a10e48e6-5c5b-46a8-b176-ec787068ce6f@f9941",
-      "__expectedType__": "cc.SpriteFrame"
-    },
+    "_spriteFrame": null,
     "_type": 0,
     "_fillType": 0,
     "_sizeMode": 0,

+ 250 - 2
assets/script/game/eliminate/view/EliminateViewComp.ts

@@ -2,7 +2,7 @@
  * @Author: mojunshou 1637302775@qq.com
  * @Date: 2025-03-20 15:01:09
  * @LastEditors: mojunshou 1637302775@qq.com
- * @LastEditTime: 2025-03-27 17:40:24
+ * @LastEditTime: 2025-03-27 17:49:05
  * @Description: 消除游戏主场景
  */
 import { _decorator } from "cc";
@@ -169,6 +169,11 @@ export class EliminateViewComp extends CCComp {
     unavailableColor = new Color(255, 0, 0, 100)
     //旋转容错
     rotateFaultTolerant = 10;
+    private _isAutoFunc: (() => void) | null = null
+
+    isAutoMode: boolean = false;
+    autoModeInterval: number = 1  // 自动模式的间隔时间(秒)
+    autoModeTimer: number = 0  // 自动模式计时器
 
 
     //网格列表管理列表  
@@ -205,6 +210,7 @@ export class EliminateViewComp extends CCComp {
         this.initButtonState();
         await this.loadConfig();
         this.initGrid();
+        this.initData();
     }
 
 
@@ -239,6 +245,12 @@ export class EliminateViewComp extends CCComp {
     //初始化数据
     private initData() {
         this.gameMode = GameMode.MANUAL;
+        this.score = 0;
+        this.money = 0;
+        this.cash = 0;
+        this.lab_score.string = this.score.toString();
+        this.amountLb.string = this.money.toString();
+        this.awardLb.string = this.cash.toString();
     }
 
     //初始化网格
@@ -1167,6 +1179,220 @@ export class EliminateViewComp extends CCComp {
         }
     }
 
+
+    // ... 修改 autoPlaceBrick 方法
+    async autoPlaceBrick() {
+        if (!this.isAutoMode) return;
+        if (this.bricksList.length === 0) return
+
+        // 遍历所有方块,找到一个可以放置的方块
+        let bestMove = null;
+        let selectedBrickIndex = -1;
+
+        for (let i = 0; i < this.bricksList.length; i++) {
+            const move = this.findBestPosition(this.bricksList[i]);
+            if (move) {
+                // 优先选择可以消除的位置
+                if (move.score > 0) {
+                    bestMove = move;
+                    selectedBrickIndex = i;
+                    break;
+                } else if (bestMove === null) {
+                    // 如果还没有找到任何可放置的位置,保存这个位置
+                    bestMove = move;
+                    selectedBrickIndex = i;
+                }
+            }
+        }
+
+        // 如果所有方块都没有可放置的位置,游戏结束
+        if (!bestMove || selectedBrickIndex === -1) {
+            console.log('所有方块都没有可放置的位置,游戏结束');
+            this.isAutoMode = false;
+            if (this._isAutoFunc) {
+                this.unschedule(this._isAutoFunc);
+                this._isAutoFunc = null;
+            }
+            this.gameOver();
+            return;
+        }
+        // 获取选中的方块
+        const brickData = this.bricksList[selectedBrickIndex];
+        // 从列表中移除方块
+        this.bricksList.splice(selectedBrickIndex, 1);
+        // 保存方块的初始位置(从待选区开始)
+        const startPos = brickData.brickInitPos.clone();
+
+        // 设置方块到移动层并确保位置精确
+        if (brickData.brickNode) {
+            brickData.brickNode.setParent(this.moveNode);
+            brickData.brickNode.setWorldPosition(startPos);
+        }
+
+        // this.guideNode.active = true;
+        // this.guideNode.setWorldPosition(
+        //     startPos.x,
+        //     startPos.y + brickData.brickNode.getComponent(UITransform).height / 2,
+        //     startPos.z
+        // );
+
+        // 如果需要旋转,先旋转到正确的角度
+        if (brickData.rotateFlag && bestMove.rotation && bestMove.rotation.deg !== brickData.deg) {
+            await new Promise<void>((resolve) => {
+                if (brickData.brickNode) {
+                    tween(brickData.brickNode)
+                        .to(0.2, { angle: bestMove.rotation ? bestMove.rotation.deg : 0 })
+                        .call(() => {
+                            if (bestMove.rotation) {
+                                brickData.gridConfig = bestMove.rotation.gridConfig;
+                                brickData.deg = bestMove.rotation.deg;
+                            }
+                            resolve();
+                        })
+                        .start();
+                }
+            });
+        }
+
+        // 获取目标位置,有些目标位置获取有问题需要修改
+        const targetGrid = this.gridList[bestMove.position.row][bestMove.position.column];
+        if (!targetGrid.gridNode) {
+            console.error('targetGrid.gridNode is null');
+            return;
+        }
+        const targetWorldPos = targetGrid.gridNode.getWorldPosition().clone();
+
+        // 创建平滑的移动动画
+        await new Promise<void>((resolve) => {
+            if (brickData.brickNode) {
+                tween(brickData.brickNode)
+                    .to(0.3, {
+                        worldPosition: targetWorldPos,
+                    }, {
+                        easing: 'cubicOut'
+                    })
+                    .call(() => {
+                        if (brickData.brickNode) {
+                            brickData.brickNode.setWorldPosition(targetWorldPos);
+                            // 放置方块
+                            if (bestMove.rotation) {
+                                bestMove.rotation.gridConfig.forEach((gridConfigData) => {
+                                    const gridData = this.gridList[bestMove.position.row + gridConfigData.row][bestMove.position.column + gridConfigData.column];
+                                    gridData.status = CellState.FILLED;
+                                    gridData.gridColorKey = brickData.gridColorKey;
+                                    gridData.type = brickData.type;
+                                    this.generateGrid(gridData);
+                                });
+                            }
+                            // 销毁方块
+                            brickData.brickNode.destroy();
+                            // 添加新方块
+                            this.addBrick(brickData.index);
+                        }
+                        resolve();
+                    })
+                    .start();
+            }
+        });
+
+        // 检查并执行消除
+        await this.gridEliminate();
+
+        // 检查是否还有任何方块可以放置
+        let hasValidMove = false;
+        for (const brick of this.bricksList) {
+            if (this.findBestPosition(brick)) {
+                hasValidMove = true;
+                break;
+            }
+        }
+        if (!hasValidMove) {
+            console.log('没有方块可以放置,游戏结束');
+            this.isAutoMode = false;
+            if (this._isAutoFunc) {
+                this.unschedule(this._isAutoFunc);
+                this._isAutoFunc = null;
+            }
+            this.gameOver();
+        }
+    }
+
+    // ... 修改 findBestPosition 方法,这个方法有问题,需要修改
+    findBestPosition(brickData: BrickData) {
+        let bestScore = -1
+        let bestPosition = null
+        let bestRotation = null
+
+        let fallbackPosition = null
+        let fallbackRotation = null
+
+        // 遍历所有可能的位置
+        for (let rowIndex = 0; rowIndex < this.rows; rowIndex++) {
+            for (let columnIndex = 0; columnIndex < this.cols; columnIndex++) {
+                // 检查当前位置的所有可能旋转
+                let currentGridConfig = brickData.gridConfig
+                let currentDeg = brickData.deg
+
+                // 最多旋转4次(0°, 90°, 180°, 270°)
+                for (let rotation = 0; rotation < 4; rotation++) {
+                    if (this.moveIf(rowIndex, columnIndex, currentGridConfig)) {
+                        // 如果还没有找到后备位置,保存第一个可放置的位置
+                        if (fallbackPosition === null) {
+                            fallbackPosition = { row: rowIndex, column: columnIndex }
+                            fallbackRotation = { gridConfig: currentGridConfig, deg: currentDeg }
+                        }
+
+                        // 模拟放置并计算得分
+                        const gridList = this.copyGridList()
+                        currentGridConfig.forEach((gridConfigData) => {
+                            gridList[gridConfigData.row + rowIndex][gridConfigData.column + columnIndex].status = CellState.FILLED
+                        })
+
+                        // 计算这个位置的得分
+                        const eliminateCheck = this.gridEliminateCheck(gridList)
+                        let positionScore = eliminateCheck.gridEliminateList.length
+
+                        // 如果这个位置比之前找到的更好
+                        if (positionScore > bestScore) {
+                            bestScore = positionScore
+                            bestPosition = { row: rowIndex, column: columnIndex }
+                            bestRotation = { gridConfig: currentGridConfig, deg: currentDeg }
+                        }
+                    }
+                    // 如果方块可以旋转,计算下一个旋转状态
+                    if (brickData.rotateFlag && rotation < 3) {
+                        const next = this.nextGridRotate(currentGridConfig, currentDeg)
+                        currentGridConfig = next.gridConfig
+                        currentDeg = next.deg
+                    } else {
+                        break
+                    }
+                }
+            }
+        }
+
+        // 如果找到了最佳得分位置,返回它
+        if (bestPosition !== null) {
+            return {
+                position: bestPosition,
+                rotation: bestRotation,
+                score: bestScore
+            }
+        }
+
+        // 如果没有找到可消除的位置但有可放置的位置,返回第一个可放置的位置
+        if (fallbackPosition !== null) {
+            return {
+                position: fallbackPosition,
+                rotation: fallbackRotation,
+                score: 0
+            }
+        }
+
+        // 如果真的没有任何可放置的位置,返回null
+        return null
+    }
+
     //========================打开其他界面和按钮逻辑=======================
 
     /** 视图对象通过 ecs.Entity.remove(eliminateViewComp) 删除组件是触发组件处理自定义释放逻辑 */
@@ -1183,7 +1409,29 @@ export class EliminateViewComp extends CCComp {
                 this.autoClick = false;
                 break;
         }
-        console.log("自动点击状态:", this.autoClick);
+        this.startAutoMode();
+    }
+
+
+    private startAutoMode() {
+        if (
+            this.gameState !== GameState.READY ||
+            this.editingFlag
+        ) return
+        // 切换自动模式状态
+        this.isAutoMode = this.autoClick;
+        if (this.isAutoMode) {
+            this._isAutoFunc = () => {
+                this.autoPlaceBrick()
+            }
+            this.schedule(this._isAutoFunc, this.autoModeInterval)
+        } else {
+            if (this._isAutoFunc) {
+                this.unschedule(this._isAutoFunc)
+                this._isAutoFunc = null
+            }
+        }
+
     }