Complete Cocos Creator port with level bundles, themes, and tooling.
Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,59 +1,75 @@
|
||||
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 gm = GameManager.instance;
|
||||
const players = gm.curLevel?.children.filter((c) => c.name.includes('Player')) ?? [];
|
||||
const propCell = gm.worldToCell(this.node.worldPosition);
|
||||
for (const p of players) {
|
||||
const pc = p.getComponent(PlayerController);
|
||||
if (!pc) continue;
|
||||
const pcCell = gm.worldToCell(p.worldPosition);
|
||||
if (pcCell.x !== propCell.x || pcCell.y !== propCell.y) continue;
|
||||
this.onCollected(pc);
|
||||
break;
|
||||
}
|
||||
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();
|
||||
gm.removeProp(this.node.worldPosition);
|
||||
const remaining = (gm.curLevel?.children.filter((c) => c.name.includes('Prop') && c !== this.node).length ?? 0);
|
||||
const propCell = this.getLogicCell();
|
||||
gm.removePropAtCell(propCell);
|
||||
this.node.removeFromParent();
|
||||
this.node.destroy();
|
||||
|
||||
if (remaining === 0) {
|
||||
if (gm.multMode) this.resolveMultWin(gm);
|
||||
else player.externalCallResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
private resolveMultWin(gm: GameManager) {
|
||||
const sum = (names: string[]) =>
|
||||
names.reduce((t, n) => t + (gm.findNodeByName(n)?.getComponent(PlayerController)?.coins ?? 0), 0);
|
||||
const totalA = sum(['PlayerA1', 'PlayerA2', 'PlayerA3']);
|
||||
const totalB = sum(['PlayerB1', 'PlayerB2', 'PlayerB3']);
|
||||
const winA = totalA > totalB || (totalA === totalB && gm.stepA1Num + gm.stepA2Num + gm.stepA3Num <
|
||||
gm.stepB1Num + gm.stepB2Num + gm.stepB3Num);
|
||||
const set = (names: string[], win: boolean) => {
|
||||
for (const n of names) gm.findNodeByName(n)?.getComponent(PlayerController)?.externalCallResult(win);
|
||||
};
|
||||
if (winA) {
|
||||
set(['PlayerA1', 'PlayerA2', 'PlayerA3'], true);
|
||||
set(['PlayerB1', 'PlayerB2', 'PlayerB3'], false);
|
||||
} else {
|
||||
set(['PlayerA1', 'PlayerA2', 'PlayerA3'], false);
|
||||
set(['PlayerB1', 'PlayerB2', 'PlayerB3'], true);
|
||||
if (gm.allPropsCollected()) {
|
||||
player.externalCallResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user