LevelAction.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. import { _decorator, BoxCollider2D, Button, CircleCollider2D, Collider2D, Component, find, Node, NodeEventType } from 'cc';
  2. import { EventDispatcher } from '../../core_tgx/easy_ui_framework/EventDispatcher';
  3. import { CarColorsGlobalInstance } from './CarColorsGlobalInstance';
  4. import { CarCarColorsComponent } from './Components/CarCarColorsComponent';
  5. import { PinComponent } from './Components/PinComponent';
  6. import { GameEvent } from './Enum/GameEvent';
  7. import { LayerAction } from './LayerAction';
  8. import { UnitAction } from './UnitAction';
  9. import { tgxUIMgr } from '../../core_tgx/tgx';
  10. import { UI_BattleResult } from '../../scripts/UIDef';
  11. import { LevelManager } from './Manager/LevelMgr';
  12. import { CarBoxComponent } from './Components/CarBoxComponent';
  13. import { CarColors } from './CarColorsGlobalTypes';
  14. const { ccclass, property } = _decorator;
  15. enum ParkingStatus {
  16. Empty = "empty", // 空闲
  17. InUse = "inuse", // 已停车
  18. Locked = "empty-lock" // 未解锁(后 3 个停车位)
  19. }
  20. @ccclass('LevelAction')
  21. export class LevelAction extends Component {
  22. start() {
  23. this.registerListener();
  24. this.init_level();
  25. this.schedule(this.moveToCar, 1.2);
  26. }
  27. registerListener() {
  28. EventDispatcher.instance.on(GameEvent.EVENT_UPDATE_LAYER, this.hide_element, this);
  29. }
  30. get_lvl(): number {
  31. let arr = this.node.name.split("_");
  32. // console.log("split get_lvl>>>>>:", arr);
  33. return Number(arr[1].trim());
  34. }
  35. get_hole_num(): number {
  36. let hole_num: number = 0;
  37. this.node.children.forEach(layer_node => {
  38. let num = layer_node.getComponent(UnitAction).get_hole_num();
  39. hole_num += num;
  40. });
  41. return hole_num;
  42. }
  43. public init_level() {
  44. for (let i = 0; i < this.node.children.length; i++) {
  45. const temp = this.node.children[i];
  46. if (temp.getComponent(CarCarColorsComponent) || temp.getComponent(CarBoxComponent)) {
  47. CarColorsGlobalInstance.instance.carSysterm.addCar(this.node.children[i]);
  48. }
  49. }
  50. this.node.children.forEach(unit_node => {
  51. if (unit_node.getComponent(UnitAction)) {
  52. unit_node.getComponent(UnitAction).init_layer();
  53. }
  54. });
  55. CarColorsGlobalInstance.instance.carSysterm.sortCarSeatsByDifficulty();
  56. const color_pin_arr = CarColorsGlobalInstance.instance.carSysterm.carSeats;
  57. console.log(color_pin_arr);
  58. this.node.children.forEach(unit_node => {
  59. if (unit_node.getComponent(UnitAction)) {
  60. unit_node.getComponent(UnitAction)!.init_pin(color_pin_arr);
  61. }
  62. });
  63. this.init_parking();
  64. //默认隐藏一些
  65. this.scheduleOnce(() => {
  66. this.set_default_layer();
  67. }, 0.2)
  68. }
  69. init_parking() {
  70. const points = find("Canvas/Scene/Parkings").children
  71. for (let index = 0; index < points.length; index++) {
  72. const element = points[index];
  73. element.name = 'empty';
  74. if (index > 3) {
  75. element.name = `empty-lock${index}`;
  76. element.getChildByName('Barricade')!.active = true;
  77. element.getChildByName('Barricade')!.getChildByName('Ad')!.active = true;
  78. const childrenToRemove = element.children.slice(1);
  79. childrenToRemove.forEach(child => child.destroy());
  80. } else {
  81. element.removeAllChildren();
  82. }
  83. }
  84. }
  85. private set_default_layer() {
  86. //默认都是不显示的
  87. let layer_arr = this.get_all_layer();
  88. layer_arr.forEach(layer_action => {
  89. layer_action.set_status(0);
  90. });
  91. this.hide_element();
  92. }
  93. get_all_layer(): LayerAction[] {
  94. let arr: LayerAction[] = [];
  95. //默认都是不显示的
  96. if (!this.node) return;
  97. for (let i = this.node.children.length - 1; i >= 0; i--) {
  98. if (this.node.children[i].getComponent(UnitAction)) {
  99. const unit = this.node.children[i].getComponent(UnitAction)!;
  100. unit.get_layer(arr);
  101. }
  102. }
  103. return arr;
  104. }
  105. private async hide_element() {
  106. let default_show_layer_num = 2;
  107. let show_num = 0;
  108. let layer_arr = this.get_all_layer();
  109. if (!layer_arr) return;
  110. for (let i = 0; i < layer_arr.length; i++) {
  111. let layer_action = layer_arr[i];
  112. if (layer_action.get_element_num() <= 0) {
  113. continue;
  114. }
  115. show_num++;
  116. if (show_num <= default_show_layer_num) {
  117. if (layer_action.layer_status != 1) {
  118. layer_action.set_status(1);
  119. // EventDispatcher.instance.emit(GameEvent.EVENT_REFRESH_PIN_COLORS);
  120. }
  121. } else if (show_num == (default_show_layer_num + 1)) {
  122. if (layer_action.layer_status != 2) {
  123. layer_action.set_status(2);
  124. }
  125. } else {
  126. layer_action.set_status(0);
  127. }
  128. }
  129. this.check_pins_block();
  130. }
  131. //每个钉子检测是否被遮挡
  132. private async check_pins_block() {
  133. let layer_arr = this.get_all_layer();
  134. layer_arr.forEach(layer => {
  135. if (layer.layer_status == 1) {
  136. layer.node.children.forEach((element) => {
  137. const pins = element.getComponentsInChildren(PinComponent)!;
  138. pins.forEach(async (pin) => {
  139. const pinCom = pin.getComponent(PinComponent)!;
  140. pinCom.checkBlocking();
  141. })
  142. })
  143. }
  144. });
  145. }
  146. /** 返回顶部面板里的颜色钉子组件数组*/
  147. get_pin_color(): PinComponent[] {
  148. let arr: PinComponent[] = [];
  149. const units = this.node.getComponentsInChildren(UnitAction)!;
  150. // console.log('units.length:', units.length);
  151. units.forEach((unit) => {
  152. unit.get_pin_color(arr);
  153. })
  154. return arr
  155. }
  156. async moveToCar() {
  157. const { isEnd } = LevelManager.instance.levelModel;
  158. if (isEnd) return;
  159. const points = find("Canvas/Scene/Parkings").children
  160. let cars: Array<Node> = []
  161. let isEmpty = false
  162. for (let i = points.length; i--;) {
  163. if (points[i].name === "inuse" && points[i].children.length === 1) {
  164. cars.push(points[i].children[0])
  165. continue
  166. }
  167. if (points[i].name === "inuse" && points[i].children.length === 2) {
  168. cars.push(points[i].children[1])
  169. isEmpty = true
  170. continue
  171. }
  172. if (points[i].name === "empty") {
  173. isEmpty = true
  174. continue
  175. }
  176. }
  177. if (cars.length === 0) {
  178. // console.log("没车了!")
  179. return
  180. }
  181. let pinCom = null;
  182. let layer_arr = this.get_all_layer();
  183. layer_arr.forEach(layer => {
  184. if (layer.layer_status == 1) {
  185. layer.node.children.forEach((element) => {
  186. const pins = element.getComponentsInChildren(PinComponent)!;
  187. pins.forEach(async (pin) => {
  188. pinCom = pin.getComponent(PinComponent)!;
  189. if (pinCom.isBlocked)
  190. return
  191. let selectedCar: Node = null
  192. for (let i = cars.length; i--;) {
  193. const car = cars[i]
  194. const carComp = car.getComponent(CarCarColorsComponent)!;
  195. if (carComp && carComp.isFull)
  196. continue
  197. // 颜色相同
  198. // console.log('车颜色:', carComp.carColor, '钉子颜色:', pinCom.pin_color);
  199. if (carComp && pinCom) {
  200. if (carComp.carColor === pinCom.pin_color) {
  201. if (selectedCar === null) {
  202. selectedCar = car
  203. continue
  204. }
  205. if (selectedCar.getComponent(CarCarColorsComponent).roleNum === 0) {
  206. selectedCar = car
  207. }
  208. }
  209. }
  210. }
  211. // 匹配的车
  212. if (selectedCar !== null) {
  213. const pin_color = pinCom.pin_color
  214. CarColorsGlobalInstance.instance.carSysterm.removeColorFromSeats(pin_color)
  215. if (selectedCar.getComponent(CarCarColorsComponent).addRole(pinCom.node)) {
  216. selectedCar.setParent(find("Canvas/Scene/Levels"), true);
  217. }
  218. }
  219. })
  220. });
  221. }
  222. });
  223. if (!isEmpty) {
  224. this.checkGameOver();
  225. }
  226. }
  227. //检测游戏是否结束
  228. checkGameOver() {
  229. const checkOver = () => {
  230. const { isEnd } = LevelManager.instance.levelModel;
  231. if (isEnd) return;
  232. const isEmpty = this.checkParkingEmpty();
  233. if (isEmpty) return;
  234. const hasMatchingNails = this.hasMatchingNails();
  235. // console.log('hasMatchingNails:', hasMatchingNails);
  236. if (hasMatchingNails) {
  237. return false;
  238. }
  239. // 游戏结束
  240. const ui = tgxUIMgr.inst.getUI(UI_BattleResult)!;
  241. if (!ui) {
  242. LevelManager.instance.levelModel.isWin = false;
  243. LevelManager.instance.levelModel.isEnd = true;
  244. tgxUIMgr.inst.showUI(UI_BattleResult);
  245. }
  246. };
  247. this.unschedule(checkOver);
  248. this.scheduleOnce(checkOver, 3);
  249. }
  250. // 检查停车场是否为空
  251. private checkParkingEmpty(): boolean {
  252. const points = find("Canvas/Scene/Parkings").children;
  253. for (let index = 0; index < points.length; index++) {
  254. const point = points[index];
  255. const status = this.getParkingStatus(index, point);
  256. if (status === ParkingStatus.Empty) {
  257. return true; // 有空位
  258. }
  259. }
  260. return false; // 停车场已满
  261. }
  262. // 获取停车位状态
  263. private getParkingStatus(index: number, point: Node): ParkingStatus {
  264. if (point.name.startsWith(ParkingStatus.Locked)) {
  265. const barricade = point.getChildByName("Barricade");
  266. if (barricade && !barricade.active) {
  267. return ParkingStatus.Empty; // 已解锁但未停车
  268. }
  269. return ParkingStatus.Locked; // 未解锁
  270. }
  271. if (index <= 3) {
  272. if (point.name === ParkingStatus.InUse && point.children.length > 0) {
  273. return ParkingStatus.InUse; // 已停车
  274. }
  275. } else {
  276. if (point.name === ParkingStatus.InUse && point.children.length > 1) {
  277. return ParkingStatus.InUse; // 已停车
  278. }
  279. }
  280. return ParkingStatus.Empty; // 空闲
  281. }
  282. private hasMatchingNails(): boolean {
  283. const points = find("Canvas/Scene/Parkings").children;
  284. const layer_arr = this.get_all_layer();
  285. for (const point of points) {
  286. if (point.name === 'inuse' && point.children.length > 0) {
  287. const car = point.children[0];
  288. const carComp = car.getComponent(CarCarColorsComponent);
  289. if (!carComp || carComp.isFull) {
  290. continue; // 车辆已满,跳过
  291. }
  292. // 查找匹配的钉子
  293. const carColor = carComp.carColor;
  294. for (const layer of layer_arr) {
  295. if (layer.layer_status !== 1) continue;
  296. for (const element of layer.node.children) {
  297. const pins = element.getComponentsInChildren(PinComponent);
  298. for (const pin of pins) {
  299. const pinCom = pin.getComponent(PinComponent);
  300. if (pinCom.isBlocked) continue; // 如果钉子已被匹配,跳过
  301. // 颜色相同
  302. if (pinCom.pin_color === carColor) {
  303. return true; // 找到匹配的钉子
  304. }
  305. }
  306. }
  307. }
  308. }
  309. }
  310. return false; // 没有找到匹配的钉子
  311. }
  312. protected onDestroy(): void {
  313. EventDispatcher.instance.off(GameEvent.EVENT_UPDATE_LAYER, this.hide_element);
  314. this.unscheduleAllCallbacks()
  315. }
  316. update(deltaTime: number) {
  317. // this.moveToCar();
  318. }
  319. }