|
|
@@ -2,7 +2,7 @@
|
|
|
* @Author: mojunshou 1637302775@qq.com
|
|
|
* @Date: 2025-03-20 15:01:09
|
|
|
* @LastEditors: mojunshou 1637302775@qq.com
|
|
|
- * @LastEditTime: 2025-03-31 17:33:44
|
|
|
+ * @LastEditTime: 2025-04-01 15:42:00
|
|
|
* @Description: 消除游戏主场景
|
|
|
*/
|
|
|
import { _decorator, Color, EventTouch, instantiate, JsonAsset, Label, Node, Prefab, randomRangeInt, Sprite, Toggle, tween, UITransform, Vec2, Vec3, Widget } from "cc";
|
|
|
@@ -14,6 +14,7 @@ import { CCComp } from "db://oops-framework/module/common/CCComp";
|
|
|
import { GameEvent } from "../../common/config/GameEvent";
|
|
|
import { UIID } from "../../common/config/GameUIConfig";
|
|
|
import { BlockItemView } from "./BlockItemView";
|
|
|
+import { Button } from "cc";
|
|
|
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
@@ -130,11 +131,9 @@ export class EliminateViewComp extends CCComp {
|
|
|
@property({ type: Label, displayName: "每次放置添加的分数" })
|
|
|
private lab_addScore: Label = null!;
|
|
|
|
|
|
+ @property({ type: Button, displayName: "自动按钮" })
|
|
|
+ private autoBtn: Button = null!;
|
|
|
|
|
|
- private lab_speed: Label = null!;
|
|
|
- private winthdrawNode: Node = null!;
|
|
|
- private awardNode: Node = null!;
|
|
|
- private autoOnToggle: Toggle = null!;
|
|
|
|
|
|
//游戏配置行列
|
|
|
private rows: number = 8; // 行数
|
|
|
@@ -142,11 +141,7 @@ export class EliminateViewComp extends CCComp {
|
|
|
private itemSize: number = 82; // 格子大小
|
|
|
private brickNum: number = 3; // 砖块数量
|
|
|
|
|
|
- //按钮状态
|
|
|
- private autoClick: boolean = false;
|
|
|
private gameState: GameState = GameState.READY;
|
|
|
- private gameMode: GameMode = GameMode.MANUAL;
|
|
|
- private rotateTag: boolean = false; // 旋转标志
|
|
|
private score: number = 0; //本局分数
|
|
|
private money: number = 0; //左边金钱
|
|
|
private cash: number = 0; //右边红包钱数
|
|
|
@@ -191,13 +186,7 @@ export class EliminateViewComp extends CCComp {
|
|
|
|
|
|
//旋转标记
|
|
|
rotateFlag = false
|
|
|
- rotateBrickData: BrickData | null = null;
|
|
|
- // 网格相关
|
|
|
- private grid: CellState[][] = []; //数组管理网格状态
|
|
|
- private gridBlocks: (BlockItemView | null)[][] = []; // 存储网格中的方块脚本引用
|
|
|
- private gridCells: Node[][] = [];
|
|
|
- // 方块数据保存数组,生成后就保存起来
|
|
|
- private brickList: BrickData[] = [];
|
|
|
+ rotateBrickData: BrickData | null = null
|
|
|
|
|
|
// 添加新的属性来跟踪是否需要重置消除计数
|
|
|
private shouldResetEliminateCount: boolean = true;
|
|
|
@@ -215,14 +204,14 @@ export class EliminateViewComp extends CCComp {
|
|
|
//通关一局算一块金砖
|
|
|
//通关比例算金砖比例
|
|
|
|
|
|
-
|
|
|
+ private autoState: boolean = false; //自动状态
|
|
|
|
|
|
/** 视图层逻辑代码分离演示 */
|
|
|
async start() {
|
|
|
// const entity = this.ent as ecs.Entity; // ecs.Entity 可转为当前模块的具体实体对象
|
|
|
this.setButton();
|
|
|
this.initComponents();
|
|
|
- this.initButtonState();
|
|
|
+ this.initButtonState(false);
|
|
|
await this.loadConfig();
|
|
|
this.initGrid();
|
|
|
this.initData();
|
|
|
@@ -232,37 +221,10 @@ export class EliminateViewComp extends CCComp {
|
|
|
|
|
|
addEventList() {
|
|
|
oops.message.on(GameEvent.RestartGame, this.restartGame, this);
|
|
|
- // oops.message.on(GameEvent.Resurrection, this.resurrection, this);
|
|
|
- }
|
|
|
-
|
|
|
- //增加一个新人新手引导
|
|
|
- private addNewPlayerGuide() {
|
|
|
- // 获取当前引导步骤
|
|
|
- // const currentStep = this.getTutorialStep();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private initComponents() {
|
|
|
- // this.winthdrawNode = this.node.getChildByPath("Scene/Top/btn_withdraw")!;
|
|
|
- // this.awardNode = this.node.getChildByPath("Scene/Top/btn_award")!;
|
|
|
- const toggle = this.node.getChildByPath("Scene/Bottom/btn_auto/auto_Toggle/Off")!;
|
|
|
- this.autoOnToggle = toggle.getComponent(Toggle)!;
|
|
|
- this.lab_speed = this.node.getChildByPath("Scene/Bottom/btn_double/lab_time")!.uiLabel;
|
|
|
- this.lab_speed.string = "二倍速"
|
|
|
-
|
|
|
- // this.brickNode.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
|
|
|
- // const touch = event.touch;
|
|
|
- // console.log("iiiiii", touch)
|
|
|
-
|
|
|
- // }, this);
|
|
|
- // this.brickNode.on(Node.EventType.TOUCH_MOVE, () => {
|
|
|
-
|
|
|
- // console.log("22222")
|
|
|
-
|
|
|
- // }, this);
|
|
|
- // this.brickNode.on(Node.EventType.TOUCH_END, () => {
|
|
|
- // console.log("333333")
|
|
|
- // }, this);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -275,21 +237,26 @@ export class EliminateViewComp extends CCComp {
|
|
|
}
|
|
|
|
|
|
//初始化按钮状态
|
|
|
- private initButtonState() {
|
|
|
+ private initButtonState(state: boolean) {
|
|
|
//自动按钮默认关闭
|
|
|
- if (this.autoOnToggle) {
|
|
|
- console.log("自动按钮状态:", this.autoOnToggle.isChecked);
|
|
|
- this.autoOnToggle.isChecked = true;
|
|
|
+ if (this.autoBtn) {
|
|
|
+ //关闭
|
|
|
+ const on = this.autoBtn.node.getChildByName("on");
|
|
|
+ on ? on.active = state : null;
|
|
|
+ const off = this.autoBtn.node.getChildByName("off");
|
|
|
+ off ? off.active = !state : null;
|
|
|
+ // this.autoState = state;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//初始化数据
|
|
|
private initData() {
|
|
|
- this.gameMode = GameMode.MANUAL;
|
|
|
+ // this.gameMode = GameMode.MANUAL;
|
|
|
this.score = 0;
|
|
|
this.money = 0;
|
|
|
this.cash = 0;
|
|
|
this.totalNum = 0;
|
|
|
+ this.autoState = false;
|
|
|
this.shouldResetEliminateCount = true;
|
|
|
this.consecutiveEliminations = false;
|
|
|
this.lab_score.string = this.score.toString();
|
|
|
@@ -415,10 +382,8 @@ export class EliminateViewComp extends CCComp {
|
|
|
console.warn('无法获取网格预制体');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
// 创建并配置新节点
|
|
|
const node = this.createNewGridNode(prefab, gridData);
|
|
|
-
|
|
|
// 设置节点属性
|
|
|
this.setupGridNode(node, gridData);
|
|
|
}
|
|
|
@@ -436,12 +401,10 @@ export class EliminateViewComp extends CCComp {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (gridData.status === CellState.FILLED && gridData.gridColorKey) {
|
|
|
- console.log("gridData.type>>>>>", gridData.type)
|
|
|
+ if (gridData.status === CellState.FILLED && gridData.type) {
|
|
|
const type = gridData.type;
|
|
|
return this.itemPrefabs[type];
|
|
|
}
|
|
|
-
|
|
|
throw new Error('Invalid grid status or missing gridColorKey');
|
|
|
}
|
|
|
|
|
|
@@ -1492,218 +1455,6 @@ 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
|
|
|
- }
|
|
|
|
|
|
//========================打开其他界面和按钮逻辑=======================
|
|
|
|
|
|
@@ -1712,50 +1463,6 @@ export class EliminateViewComp extends CCComp {
|
|
|
this.node.destroy();
|
|
|
}
|
|
|
|
|
|
- private onToggleContainerAutoClick(toggle: Toggle) {
|
|
|
-
|
|
|
- switch (toggle.node.name) {
|
|
|
- case "On":
|
|
|
- if (this.autoClick) {
|
|
|
- oops.gui.toast("已经是自动模式啦")
|
|
|
- return;
|
|
|
- }
|
|
|
- this.autoClick = true;
|
|
|
- break;
|
|
|
- case "Off":
|
|
|
- this.autoClick = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- this.startAutoMode();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private startAutoMode() {
|
|
|
- if (
|
|
|
- this.gameState !== GameState.READY ||
|
|
|
- this.editingFlag
|
|
|
- ) return
|
|
|
- // 切换自动模式状态
|
|
|
- //如果状态一样,不做任何操作
|
|
|
- if (this.isAutoMode === this.autoClick) {
|
|
|
- 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
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
private btn_setting() {
|
|
|
oops.gui.open(UIID.Setting);
|
|
|
}
|
|
|
@@ -1768,11 +1475,20 @@ export class EliminateViewComp extends CCComp {
|
|
|
oops.gui.open(UIID.RedPacketWithdraw);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ private btn_auto() {
|
|
|
+ //自动放置
|
|
|
+ this.autoState = !this.autoState;
|
|
|
+ this.initButtonState(this.autoState);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
//重新开始
|
|
|
private restartGame() {
|
|
|
if (this.gameState === GameState.READY) return;
|
|
|
this.initData();
|
|
|
this.reopenGrid();
|
|
|
+ this.initButtonState(this.autoState);
|
|
|
}
|
|
|
|
|
|
//重新清除网格
|