import { v3 } from "cc"; import { AsyncQueue } from "../../../../../extensions/oops-plugin-framework/assets/libs/collection/AsyncQueue"; import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { Grid } from "../../grid/Grid"; import { Checkpoint } from "../Checkpoint"; import { CheckpointModelLevelComp } from "../model/CheckpointModelLevel"; import { CheckpointViewComp } from "../view/CheckpointViewComp"; import { CheckpointModelComp } from "../model/CheckpointModel"; import { Station } from "../../station/Station"; import { GridModelComp } from "../../grid/model/GridModelComp"; import { Obstacle } from "../../obstacle/Obstacle"; import { Puppet } from "../../puppet/puppet"; import { PuppetModelComp } from "../../puppet/model/PuppetModelComp"; import { ObstacleModelComp } from "../../obstacle/model/ObstacleModelComp"; import { PathFindComp } from "../../common/ecs/path/PathFind"; import { oops } from "../../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { Vehicle } from "../../vehicle/Vehicle"; import { VehicleModelComp } from "../../vehicle/model/VehicleModelComp"; /** 初始化游戏公共资源 */ @ecs.register('InitCheckpoint') export class InitCheckpointComp extends ecs.Comp { reset() { } } export class InitCheckpointSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem { filter(): ecs.IMatcher { return ecs.allOf(InitCheckpointComp, CheckpointModelComp, CheckpointModelLevelComp); } entityEnter(e: Checkpoint): void { const levelConfig = e.get(CheckpointModelLevelComp)?.rtluCurrent const { gridCount, levelColor, peopleCount, levelObstacle, obstacleCount, stationCount } = levelConfig this.resetCheckpoint(e) // 关卡数据 e.CheckpointModel.vmAdd(); // 添加关卡到场景 e.load(oops.game.root, v3(0, 0, 0)); this.createGrid(e, gridCount, gridCount, levelColor, levelObstacle, peopleCount, obstacleCount) this.createStation(e, stationCount) this.createVehicle(e, peopleCount,levelColor) e.remove(InitCheckpointComp) } resetCheckpoint(e: Checkpoint) { e.remove(CheckpointViewComp); e.add(CheckpointModelComp, true) e.children.forEach(child => { e.removeChild(child); child.destroy(); }); } // 生成棋盘相关 createGrid(e: Checkpoint, row: number, col: number, colors: string[], obstacles: number[], peopleCount: number, obstacleCount: number) { const checkpoint_root = e.get(CheckpointViewComp).node const checkpoint_model = e.get(CheckpointModelComp) const grids = this.generateGridWithEmptySpaces(row, col, colors, obstacles, peopleCount, obstacleCount) checkpoint_model.grids = Array.from({ length: row }, () => new Array(col).fill(null)); checkpoint_model.cells = Array.from({ length: row }, () => new Array(col).fill(null)); checkpoint_model.path_grid = Array.from({ length: row }, () => new Array(col).fill(null)); const start_point = v3(-1.706, 0, -1.718) for (let index = 0; index < grids.length; index++) { for (let j = 0; j < grids[index].length; j++) { const gridEnt = ecs.getEntity(Grid); const gridModel = gridEnt.get(GridModelComp) // 添加关卡到场景 const fill = grids[index][j] gridModel.color = fill const pos = v3(start_point.x + j * 0.6, 0, start_point.z + index * 0.6) gridEnt.load(checkpoint_root, pos); e.addChild(gridEnt) checkpoint_model.grids[index][j] = gridEnt if (typeof grids[index][j] === 'number') { // 生成障碍物 const obstacle = ecs.getEntity(Obstacle) const obstacleModel = obstacle.get(ObstacleModelComp) obstacleModel.type = fill obstacle.load(checkpoint_root, pos); checkpoint_model.cells[index][j] = obstacle checkpoint_model.path_grid[index][j] = { x: index, y: j, fill: fill, pos: pos } } else if (typeof grids[index][j] === 'string') { // 生成人物 const puppet = ecs.getEntity(Puppet) const puppetModel = puppet.get(PuppetModelComp) puppetModel.color = fill puppetModel.x = index puppetModel.y = j puppet.load(checkpoint_root, fill, pos); checkpoint_model.cells[index][j] = puppet checkpoint_model.path_grid[index][j] = { x: index, y: j, fill: fill, pos: pos } const pathComp = puppet.add(PathFindComp) pathComp.x = index pathComp.y = j } else { // 空格 checkpoint_model.path_grid[index][j] = { x: index, y: j, fill: null, pos: pos } } } } } // // 生成棋盘格 // createGrid(e: Checkpoint, row: number, col: number) { // const checkpoint_root = e.get(CheckpointViewComp).node // const checkpoint_model = e.get(CheckpointModelComp) // checkpoint_model.grids = Array.from({ length: row }, () => new Array(col).fill(null)); // const start_point = v3(-1.706, 0, -1.718) // for (let index = 0; index < row; index++) { // for (let j = 0; j < col; j++) { // const grid = ecs.getEntity(Grid); // // 添加关卡到场景 // grid.load(checkpoint_root, v3(start_point.x + index * 0.6, 0, start_point.z + j * 0.6)); // e.addChild(grid) // checkpoint_model.grids[index][j] = grid // } // } // } // 生成站台 createStation(e: Checkpoint, count: number) { const checkpoint_root = e.get(CheckpointViewComp).node const checkpoint_model = e.get(CheckpointModelComp) const start_point = v3(-1, 0, -3) for (let index = 0; index < count; index++) { const station = ecs.getEntity(Station); // 添加关卡到场景 station.load(checkpoint_root, v3(start_point.x + index * 0.6, 0, start_point.z)); e.addChild(station) checkpoint_model.stations.push(station) } } // 生成交通工具 createVehicle(e: Checkpoint, peopleCount: number, colors: string[]) { const checkpoint_root = e.get(CheckpointViewComp).node const checkpoint_model = e.get(CheckpointModelComp) const start_point = v3(0, 0, -5) const vechicleCount = Math.ceil(peopleCount / 3) for (let index = 0; index < vechicleCount; index++) { const vehicle = ecs.getEntity(Vehicle); const vehicleModel = vehicle.get(VehicleModelComp) vehicleModel.color = colors[index % 3] // 添加车到场景 vehicle.load(checkpoint_root, vehicleModel.color, start_point); e.addChild(vehicle) checkpoint_model.vehicles.push(vehicle) } } // 生成人物 createMan(x: number, y: number, color: string) { } // 生成障碍物 createObstacle() { } generateGridWithEmptySpaces(row: number, col: number, colors: string[], obstacles: number[], peopleCount: number, obstacleCount: number) { const totalCells = row * col; let grid = Array.from({ length: row }, () => new Array(col).fill(null)); // 初始化颜色计数 let counts = {}; colors.forEach(color => { let maxCount = Math.floor((totalCells - 1) / 3) * 3; // 最大可能的 3 的倍数 counts[color] = Math.min(maxCount / 3, peopleCount * 3); // 分配三分之一 }); // 创建所有可能的格子位置数组 let availablePositions = []; for (let i = 0; i < row; i++) { for (let j = 0; j < col; j++) { availablePositions.push([i, j]); } } let obstacleNum = obstacleCount // 随机分配颜色到网格中 while (availablePositions.length > 0) { let randomIndex = Math.floor(Math.random() * availablePositions.length); let position = availablePositions.splice(randomIndex, 1)[0]; let x = position[0]; let y = position[1]; let colorIndex = Math.floor(Math.random() * colors.length); let color = colors[colorIndex]; if (counts[color] > 0) { grid[x][y] = color; counts[color]--; } else if (obstacleNum > 0) { grid[x][y] = obstacles[Math.floor(Math.random() * obstacles.length)] obstacleNum-- } } return grid; } // generateOptimizedGrid(colors:string[]) { // const gridSize = 7; // const totalCells = gridSize * gridSize; // // const colors = ['红色', '蓝色', '绿色']; // let grid = Array(gridSize).fill().map(() => Array(gridSize).fill('')); // // 初始化每种颜色的人数 // let counts = { '红色': 0, '蓝色': 0, '绿色': 0 }; // // 首先分配每种颜色的人数,使其尽可能接近总数且是 3 的倍数 // for (let color of colors) { // let maxCount = Math.floor((totalCells - 1) / 3) * 3; // 最大可能的 3 的倍数 // counts[color] = maxCount / 3; // 分配三分之一 // } // // 在剩余的空格中随机分配颜色或保持为空 // let remainingCells = totalCells - 3 * Math.floor((totalCells - 1) / 3); // let colorIndices = colors.map((_, index) => index); // while (remainingCells > 0) { // let randomIndex = Math.floor(Math.random() * colorIndices.length); // let color = colors[colorIndices[randomIndex]]; // counts[color]++; // remainingCells--; // } // // 将颜色分配到网格中 // let flatGrid = grid.flat(); // colors.forEach(color => { // for (let i = 0; i < counts[color]; i++) { // let pos; // do { // pos = Math.floor(Math.random() * flatGrid.length); // } while (flatGrid[pos] !== ''); // flatGrid[pos] = color; // } // }); // // 重新构建二维网格 // for (let i = 0; i < flatGrid.length; i++) { // grid[Math.floor(i / gridSize)][i % gridSize] = flatGrid[i]; // } // return grid; // } }