Files
watermelon/assets/script/Fruit.ts

92 lines
2.4 KiB
TypeScript
Raw Normal View History

1970-01-01 08:26:29 +08:00
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);
}
}