Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { _decorator, Component, Vec3 } from 'cc';
|
||
import { GameManager } from '../manager/GameManager';
|
||
import { forEachLevelEntityNode } from '../level/TileLayout';
|
||
import { PlayerController } from './PlayerController';
|
||
|
||
const { ccclass } = _decorator;
|
||
|
||
/**
|
||
* 可拾取物(对齐 Unity PropController OnTriggerEnter2D)
|
||
* 玩家进入道具格且靠近时拾取(由 PlayerController 判定时机)
|
||
*/
|
||
@ccclass('PropController')
|
||
export class PropController extends Component {
|
||
private collected = false;
|
||
private spawnCell: Vec3 | null = null;
|
||
|
||
setSpawnCell(cell: Vec3) {
|
||
this.spawnCell = cell.clone();
|
||
}
|
||
|
||
getSpawnCell(): Vec3 | null {
|
||
return this.spawnCell ? this.spawnCell.clone() : null;
|
||
}
|
||
|
||
matchesCell(cell: Vec3): boolean {
|
||
const propCell = this.getLogicCell();
|
||
return propCell.x === cell.x && propCell.y === cell.y;
|
||
}
|
||
|
||
private getLogicCell(): Vec3 {
|
||
if (this.spawnCell) return this.spawnCell;
|
||
const gm = GameManager.instance!;
|
||
return gm.worldToCell(this.node.position);
|
||
}
|
||
|
||
/** 玩家落格后尝试拾取(由 PlayerController 调用) */
|
||
static tryCollectAtCell(cell: Vec3, player: PlayerController) {
|
||
const gm = GameManager.instance;
|
||
const level = gm?.curLevel;
|
||
if (!level) return;
|
||
forEachLevelEntityNode(level, (ch) => {
|
||
const prop = ch.getComponent(PropController);
|
||
if (!prop || prop.collected || !prop.matchesCell(cell)) return;
|
||
prop.collect(player);
|
||
});
|
||
}
|
||
|
||
update() {
|
||
if (this.collected || !GameManager.instance) return;
|
||
const player = GameManager.instance.findNodeByName('Player');
|
||
const pc = player?.getComponent(PlayerController);
|
||
if (!pc?.canCollectProp(this)) return;
|
||
this.collect(pc);
|
||
}
|
||
|
||
collect(player: PlayerController) {
|
||
if (this.collected) return;
|
||
this.onCollected(player);
|
||
}
|
||
|
||
private onCollected(player: PlayerController) {
|
||
if (this.collected) return;
|
||
this.collected = true;
|
||
this.node.active = false;
|
||
const gm = GameManager.instance!;
|
||
player.addCoins();
|
||
const propCell = this.getLogicCell();
|
||
gm.removePropAtCell(propCell);
|
||
this.node.removeFromParent();
|
||
this.node.destroy();
|
||
if (gm.allPropsCollected()) {
|
||
player.externalCallResult(true);
|
||
}
|
||
}
|
||
}
|