2025-06-25 17:50:40 +08:00
|
|
|
import { _decorator, Component, Node, Vec3, Color } from 'cc';
|
2025-06-24 23:51:59 +08:00
|
|
|
import { SimplePrefabFactory } from './components/SimplePrefabFactory';
|
2025-06-25 17:50:40 +08:00
|
|
|
import { BehaviorTreeComponent } from './components/BehaviorTreeComponent';
|
|
|
|
|
import { StatusUIManager } from './components/StatusUIManager';
|
2025-06-24 19:34:37 +08:00
|
|
|
|
|
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
|
|
|
|
/**
|
2025-06-25 17:50:40 +08:00
|
|
|
* 矿工AI演示场景
|
2025-06-24 19:34:37 +08:00
|
|
|
*/
|
2025-06-25 17:50:40 +08:00
|
|
|
@ccclass('SimpleMinerDemo')
|
|
|
|
|
export class SimpleMinerDemo extends Component {
|
2025-06-24 23:51:59 +08:00
|
|
|
|
|
|
|
|
@property
|
2025-06-25 17:50:40 +08:00
|
|
|
minerCount: number = 2;
|
2025-06-24 23:51:59 +08:00
|
|
|
|
|
|
|
|
@property
|
2025-06-25 17:50:40 +08:00
|
|
|
goldMineCount: number = 3;
|
2025-06-24 23:51:59 +08:00
|
|
|
|
|
|
|
|
private miners: Node[] = [];
|
2025-06-25 17:50:40 +08:00
|
|
|
private goldMines: Node[] = [];
|
2025-06-24 23:51:59 +08:00
|
|
|
private warehouse: Node | null = null;
|
|
|
|
|
private ground: Node | null = null;
|
2025-06-25 17:50:40 +08:00
|
|
|
private totalOresCollected: number = 0;
|
|
|
|
|
private warehouseUI: any = null;
|
2025-06-24 23:51:59 +08:00
|
|
|
|
|
|
|
|
start() {
|
|
|
|
|
this.createWorld();
|
|
|
|
|
this.createWarehouse();
|
2025-06-25 17:50:40 +08:00
|
|
|
this.createGoldMines();
|
2025-06-24 23:51:59 +08:00
|
|
|
this.createMiners();
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-24 23:51:59 +08:00
|
|
|
private createWorld() {
|
2025-06-25 17:50:40 +08:00
|
|
|
this.ground = SimplePrefabFactory.createGround(new Vec3(20, 0.2, 20));
|
|
|
|
|
this.node.addChild(this.ground);
|
|
|
|
|
this.ground.setWorldPosition(new Vec3(0, 0, 0));
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-24 23:51:59 +08:00
|
|
|
private createWarehouse() {
|
2025-06-25 17:50:40 +08:00
|
|
|
this.warehouse = SimplePrefabFactory.createBuilding('Warehouse', new Vec3(2, 2, 2), Color.GRAY);
|
|
|
|
|
this.node.addChild(this.warehouse);
|
|
|
|
|
this.warehouse.setWorldPosition(new Vec3(0, 1, 0));
|
|
|
|
|
this.createWarehouseUI();
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
private createGoldMines() {
|
|
|
|
|
for (let i = 0; i < this.goldMineCount; i++) {
|
|
|
|
|
const angle = (i / this.goldMineCount) * Math.PI * 2;
|
|
|
|
|
const radius = 6 + Math.random() * 2;
|
|
|
|
|
const position = new Vec3(
|
|
|
|
|
Math.cos(angle) * radius,
|
|
|
|
|
0.8,
|
|
|
|
|
Math.sin(angle) * radius
|
2025-06-24 23:51:59 +08:00
|
|
|
);
|
2025-06-24 19:34:37 +08:00
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
const goldMine = SimplePrefabFactory.createResource(`GoldMine_${i + 1}`, Color.YELLOW);
|
|
|
|
|
this.node.addChild(goldMine);
|
|
|
|
|
goldMine.setWorldPosition(position);
|
|
|
|
|
goldMine.setScale(new Vec3(1.2, 1.2, 1.2));
|
|
|
|
|
this.goldMines.push(goldMine);
|
2025-06-24 23:51:59 +08:00
|
|
|
}
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-24 23:51:59 +08:00
|
|
|
private createMiners() {
|
|
|
|
|
for (let i = 0; i < this.minerCount; i++) {
|
|
|
|
|
const angle = (i / this.minerCount) * Math.PI * 2;
|
|
|
|
|
const radius = 3;
|
|
|
|
|
const position = new Vec3(
|
|
|
|
|
Math.cos(angle) * radius,
|
|
|
|
|
1,
|
|
|
|
|
Math.sin(angle) * radius
|
|
|
|
|
);
|
2025-06-24 19:34:37 +08:00
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
const miner = SimplePrefabFactory.createUnit(`Miner_${i + 1}`, Color.BLUE);
|
|
|
|
|
this.node.addChild(miner);
|
|
|
|
|
miner.setWorldPosition(position);
|
2025-06-24 23:51:59 +08:00
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
const behaviorTree = miner.addComponent(BehaviorTreeComponent);
|
|
|
|
|
behaviorTree.behaviorTreeFile = 'miner-stamina-ai.bt';
|
|
|
|
|
behaviorTree.debugMode = true;
|
2025-06-24 23:51:59 +08:00
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
this.scheduleOnce(() => {
|
|
|
|
|
const blackboard = behaviorTree.getBlackboard();
|
|
|
|
|
if (blackboard) {
|
|
|
|
|
blackboard.setValue('homePosition', position.clone());
|
|
|
|
|
}
|
|
|
|
|
}, 0.5);
|
2025-06-24 23:51:59 +08:00
|
|
|
|
|
|
|
|
this.miners.push(miner);
|
|
|
|
|
}
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
public getAllGoldMines(): Node[] {
|
|
|
|
|
return this.goldMines.filter(mine => mine && mine.isValid);
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-24 23:51:59 +08:00
|
|
|
public getWarehouse(): Node | null {
|
|
|
|
|
return this.warehouse;
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-25 17:50:40 +08:00
|
|
|
public mineGoldOre(miner: Node): boolean {
|
|
|
|
|
this.totalOresCollected++;
|
|
|
|
|
this.updateWarehouseUI();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public getTotalOresCollected(): number {
|
|
|
|
|
return this.totalOresCollected;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private createWarehouseUI() {
|
|
|
|
|
if (!this.warehouse) return;
|
|
|
|
|
|
|
|
|
|
this.warehouseUI = StatusUIManager.createWarehouseUI(this.warehouse);
|
|
|
|
|
if (this.warehouseUI) {
|
|
|
|
|
this.updateWarehouseUI();
|
2025-06-24 23:51:59 +08:00
|
|
|
}
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|
2025-06-25 17:50:40 +08:00
|
|
|
|
|
|
|
|
private updateWarehouseUI() {
|
|
|
|
|
if (this.warehouseUI && this.warehouseUI.warehouseCountLabel) {
|
|
|
|
|
this.warehouseUI.warehouseCountLabel.string = `🏭 总存储: ${this.totalOresCollected}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDestroy() {
|
|
|
|
|
this.unscheduleAllCallbacks();
|
|
|
|
|
}
|
2025-06-24 19:34:37 +08:00
|
|
|
}
|