import { _decorator, BoxCollider2D, Button, CircleCollider2D, Collider2D, Component, find, Node, NodeEventType } from 'cc'; import { EventDispatcher } from '../../core_tgx/easy_ui_framework/EventDispatcher'; import { CarColorsGlobalInstance } from './CarColorsGlobalInstance'; import { CarCarColorsComponent } from './Components/CarCarColorsComponent'; import { PinComponent } from './Components/PinComponent'; import { GameEvent } from './Enum/GameEvent'; import { LayerAction } from './LayerAction'; import { UnitAction } from './UnitAction'; import { tgxUIMgr } from '../../core_tgx/tgx'; import { UI_BattleResult } from '../../scripts/UIDef'; import { LevelManager } from './Manager/LevelMgr'; import { CarBoxComponent } from './Components/CarBoxComponent'; import { CarColors, CarTypes } from './CarColorsGlobalTypes'; import { GameUtil } from './GameUtil'; const { ccclass, property } = _decorator; enum ParkingStatus { Empty = "empty", // 空闲 InUse = "inuse", // 已停车 Locked = "empty-lock" // 未解锁(后 3 个停车位) } @ccclass('LevelAction') export class LevelAction extends Component { start() { this.registerListener(); this.init_level(); this.schedule(this.moveToCar, 1.2); } registerListener() { EventDispatcher.instance.on(GameEvent.EVENT_UPDATE_LAYER, this.hide_element, this); } get_lvl(): number { let arr = this.node.name.split("_"); // console.log("split get_lvl>>>>>:", arr); return Number(arr[1].trim()); } get_hole_num(): number { let hole_num: number = 0; this.node.children.forEach(layer_node => { let num = layer_node.getComponent(UnitAction).get_hole_num(); hole_num += num; }); return hole_num; } async init_level() { for (let i = 0; i < this.node.children.length; i++) { const temp = this.node.children[i]; if (temp.getComponent(CarCarColorsComponent) || temp.getComponent(CarBoxComponent)) { CarColorsGlobalInstance.instance.carSysterm.addCar(this.node.children[i]); } } this.node.children.forEach(unit_node => { if (unit_node.getComponent(UnitAction)) { unit_node.getComponent(UnitAction).init_layer(); } }); await GameUtil.delay(0.2); CarColorsGlobalInstance.instance.carSysterm.sortCarSeatsByDifficulty(); const color_pin_arr = CarColorsGlobalInstance.instance.carSysterm.carSeats; this.node.children.forEach(unit_node => { if (unit_node.getComponent(UnitAction)) { unit_node.getComponent(UnitAction)!.init_pin(color_pin_arr); } }); this.init_parking(); //默认隐藏一些 await GameUtil.delay(0.2); this.set_default_layer(); // this.set_pin_color(); } init_parking() { const points = find("Canvas/Scene/Parkings").children for (let index = 0; index < points.length; index++) { const element = points[index]; element.name = 'empty'; if (index > 3) { element.name = `empty-lock${index}`; element.getChildByName('Barricade')!.active = true; element.getChildByName('Barricade')!.getChildByName('Ad')!.active = true; const childrenToRemove = element.children.slice(1); childrenToRemove.forEach(child => child.destroy()); } else { element.removeAllChildren(); } } } private set_default_layer() { //默认都是不显示的 let layer_arr = this.get_all_layer(); layer_arr.forEach(layer_action => { layer_action.set_status(0); }); this.hide_element(); } get_all_layer(): LayerAction[] { let arr: LayerAction[] = []; //默认都是不显示的 if (!this.node) return; for (let i = this.node.children.length - 1; i >= 0; i--) { if (this.node.children[i].getComponent(UnitAction)) { const unit = this.node.children[i].getComponent(UnitAction)!; unit.get_layer(arr); } } return arr; } private async hide_element() { let default_show_layer_num = 2; let show_num = 0; let layer_arr = this.get_all_layer(); if (!layer_arr) return; for (let i = 0; i < layer_arr.length; i++) { let layer_action = layer_arr[i]; if (layer_action.get_element_num() <= 0) { continue; } show_num++; if (show_num <= default_show_layer_num) { if (layer_action.layer_status != 1) { layer_action.set_status(1); this.check_pins_block(); // this.set_pin_color(); } } else if (show_num == (default_show_layer_num + 1)) { if (layer_action.layer_status != 2) { layer_action.set_status(2); } } else { layer_action.set_status(0); } } } //动态给钉子上色 private async set_pin_color() { const carSysterm = CarColorsGlobalInstance.instance.carSysterm; let layer_arr = this.get_all_layer(); let canOutCars = carSysterm.findCanOutCars(); // 找到所有无障碍物的车子 if (canOutCars.length === 0) { console.warn("没有可以开出的车,无法分配颜色"); return; } let allPins: any[] = []; // 获取所有可见钉子 layer_arr.forEach(layer => { if (layer.layer_status === 1) { let pinArr: any[] = []; layer.get_pin_color(pinArr); allPins.push(...pinArr); } }); console.log("总可见钉子数量:", allPins.length); if (allPins.length === 0) return; let pinIndex = 0; // 记录当前分配到哪个钉子 for (let car of canOutCars) { let carComp = car.getComponent(CarCarColorsComponent); let carColor = carComp.carColor; let seatCount = this.getCarSeatCount(carComp.carType); // 获取车的载客量 // 遍历当前车的座位数,依次给钉子赋值 for (let i = 0; i < seatCount; i++) { if (pinIndex >= allPins.length) return; // 说明钉子已经全部分配完毕 allPins[pinIndex].pin_color = carColor; pinIndex++; } } } /** 根据车辆类型获取对应的载客量 */ private getCarSeatCount(carType: CarTypes): number { switch (carType) { case CarTypes.Sedan: return 4; // 4座 case CarTypes.Minivan: return 6; // 6座 case CarTypes.Bus: return 8; // 8座 default: return 4; // 默认最小 } } //每个钉子检测是否被遮挡 private async check_pins_block() { let layer_arr = this.get_all_layer(); layer_arr.forEach(layer => { if (layer.layer_status == 1) { layer.node.children.forEach((element) => { const pins = element.getComponentsInChildren(PinComponent)!; pins.forEach(async (pin) => { const pinCom = pin.getComponent(PinComponent)!; pinCom.checkBlocking(); }) }) } }); } /** 返回顶部面板里的颜色钉子组件数组*/ get_pin_color(): PinComponent[] { let arr: PinComponent[] = []; const units = this.node.getComponentsInChildren(UnitAction)!; // console.log('units.length:', units.length); units.forEach((unit) => { unit.get_pin_color(arr); }) return arr } async moveToCar() { const { isEnd } = LevelManager.instance.levelModel; if (isEnd) return; const points = find("Canvas/Scene/Parkings").children let cars: Array = [] let isEmpty = false for (let i = points.length; i--;) { if (points[i].name === "inuse" && points[i].children.length === 1) { cars.push(points[i].children[0]) continue } if (points[i].name === "inuse" && points[i].children.length === 2) { cars.push(points[i].children[1]) isEmpty = true continue } if (points[i].name === "empty") { isEmpty = true continue } } if (cars.length === 0) { // console.log("没车了!") return } let pinCom = null; let layer_arr = this.get_all_layer(); layer_arr.forEach(layer => { if (layer.layer_status == 1) { layer.node.children.forEach((element) => { const pins = element.getComponentsInChildren(PinComponent)!; pins.forEach(async (pin) => { pinCom = pin.getComponent(PinComponent)!; if (pinCom.isBlocked) return let selectedCar: Node = null for (let i = cars.length; i--;) { const car = cars[i] const carComp = car.getComponent(CarCarColorsComponent)!; if (carComp && carComp.isFull) continue // 颜色相同 // console.log('车颜色:', carComp.carColor, '钉子颜色:', pinCom.pin_color); if (carComp && pinCom) { if (carComp.carColor === pinCom.pin_color) { if (selectedCar === null) { selectedCar = car continue } if (selectedCar.getComponent(CarCarColorsComponent).roleNum === 0) { selectedCar = car } } } } // 匹配的车 if (selectedCar !== null) { const pin_color = pinCom.pin_color CarColorsGlobalInstance.instance.carSysterm.removeColorFromSeats(pin_color) if (selectedCar.getComponent(CarCarColorsComponent).addRole(pinCom.node)) { selectedCar.setParent(find("Canvas/Scene/Levels"), true); } } }) }); } }); if (!isEmpty) { this.checkGameOver(); } } //检测游戏是否结束 async checkGameOver() { const checkOver = () => { const { isEnd } = LevelManager.instance.levelModel; if (isEnd) return; const isEmpty = this.checkParkingEmpty(); if (isEmpty) return; const hasMatchingNails = this.hasMatchingNails(); // console.log('hasMatchingNails:', hasMatchingNails); if (hasMatchingNails) { return false; } // 游戏结束 const ui = tgxUIMgr.inst.getUI(UI_BattleResult)!; if (!ui) { LevelManager.instance.levelModel.isWin = false; LevelManager.instance.levelModel.isEnd = true; tgxUIMgr.inst.showUI(UI_BattleResult); } }; this.unschedule(checkOver); this.scheduleOnce(checkOver, 3); } // 检查停车场是否为空 private checkParkingEmpty(): boolean { const points = find("Canvas/Scene/Parkings").children; for (let index = 0; index < points.length; index++) { const point = points[index]; const status = this.getParkingStatus(index, point); if (status === ParkingStatus.Empty) { return true; // 有空位 } } return false; // 停车场已满 } // 获取停车位状态 private getParkingStatus(index: number, point: Node): ParkingStatus { if (point.name.startsWith(ParkingStatus.Locked)) { const barricade = point.getChildByName("Barricade"); if (barricade && !barricade.active) { return ParkingStatus.Empty; // 已解锁但未停车 } return ParkingStatus.Locked; // 未解锁 } if (index <= 3) { if (point.name === ParkingStatus.InUse && point.children.length > 0) { return ParkingStatus.InUse; // 已停车 } } else { if (point.name === ParkingStatus.InUse && point.children.length > 1) { return ParkingStatus.InUse; // 已停车 } } return ParkingStatus.Empty; // 空闲 } private hasMatchingNails(): boolean { const points = find("Canvas/Scene/Parkings").children; const layer_arr = this.get_all_layer(); for (const point of points) { if (point.name === 'inuse' && point.children.length > 0) { const car = point.children[0]; const carComp = car.getComponent(CarCarColorsComponent); if (!carComp || carComp.isFull) { continue; // 车辆已满,跳过 } // 查找匹配的钉子 const carColor = carComp.carColor; for (const layer of layer_arr) { if (layer.layer_status !== 1) continue; for (const element of layer.node.children) { const pins = element.getComponentsInChildren(PinComponent); for (const pin of pins) { const pinCom = pin.getComponent(PinComponent); if (pinCom.isBlocked) continue; // 如果钉子已被匹配,跳过 // 颜色相同 if (pinCom.pin_color === carColor) { return true; // 找到匹配的钉子 } } } } } } return false; // 没有找到匹配的钉子 } protected onDestroy(): void { EventDispatcher.instance.off(GameEvent.EVENT_UPDATE_LAYER, this.hide_element); this.unscheduleAllCallbacks() } update(deltaTime: number) { // this.moveToCar(); } }