74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import { _decorator, Component, Sprite, SpriteFrame, UITransform, Size, CircleCollider2D, Contact2DType, IPhysics2DContact, RigidBody2D, Vec2, Node } from 'cc';
|
|
import { FRUITS, MAX_LEVEL } from './FruitConfig';
|
|
import { GameManager } from './GameManager';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('Fruit')
|
|
export class Fruit extends Component {
|
|
@property
|
|
level = 1; // 1..MAX_LEVEL
|
|
|
|
@property(Sprite)
|
|
sprite!: Sprite;
|
|
|
|
game!: GameManager;
|
|
collider!: CircleCollider2D;
|
|
body!: RigidBody2D;
|
|
|
|
// 防止同一对重复合成
|
|
merging = false;
|
|
removed = false;
|
|
|
|
init(level: number, spriteFrame: SpriteFrame, game: GameManager) {
|
|
this.level = level;
|
|
this.game = game;
|
|
if (!this.sprite) this.sprite = this.getComponent(Sprite)!;
|
|
this.sprite.spriteFrame = spriteFrame;
|
|
|
|
const def = FRUITS[this.level - 1];
|
|
const ui = this.getComponent(UITransform)!;
|
|
ui.setContentSize(new Size(def.radius * 2, def.radius * 2));
|
|
|
|
this.collider = this.getComponent(CircleCollider2D)!;
|
|
this.collider.radius = def.radius;
|
|
|
|
this.body = this.getComponent(RigidBody2D)!;
|
|
this.body.enabled = true;
|
|
|
|
this.merging = false;
|
|
this.removed = false;
|
|
}
|
|
|
|
onEnable() {
|
|
const col = this.getComponent(CircleCollider2D);
|
|
if (col) col.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
|
}
|
|
|
|
onDisable() {
|
|
const col = this.getComponent(CircleCollider2D);
|
|
if (col) col.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
|
}
|
|
|
|
private onBeginContact(selfCol: CircleCollider2D, otherCol: CircleCollider2D, _contact: IPhysics2DContact | null) {
|
|
if (this.removed || this.merging) return;
|
|
const otherNode = otherCol.node as Node;
|
|
const otherFruit = otherNode.getComponent(Fruit);
|
|
if (!otherFruit || otherFruit.removed || otherFruit.merging) return;
|
|
|
|
// 仅同级可合成,且不能超过最大级
|
|
if (otherFruit.level !== this.level || this.level >= MAX_LEVEL) return;
|
|
|
|
// 为避免两者都合成,使用 uuid 决定触发者(只让“较小”的触发)
|
|
if (this.node.uuid > otherNode.uuid) return;
|
|
|
|
this.merging = true;
|
|
otherFruit.merging = true;
|
|
|
|
// 合成到下一级
|
|
const nextLevel = this.level + 1;
|
|
const wpA = this.node.worldPosition;
|
|
const wpB = otherNode.worldPosition;
|
|
const mid = wpA.clone().add(wpB).multiplyScalar(0.5);
|
|
this.game.spawnMerged(nextLevel, mid, this, otherFruit);
|
|
}
|
|
} |