feat: rotation and more

This commit is contained in:
hypercross 2026-04-08 11:42:20 +08:00
parent 3e064f437b
commit 92e1a5bec1
2 changed files with 50 additions and 3 deletions

View File

@ -23,14 +23,19 @@ export class CardContainer extends Phaser.GameObjects.Container {
private highlightRect: Phaser.GameObjects.Rectangle | null = null; private highlightRect: Phaser.GameObjects.Rectangle | null = null;
private highlightTween: Phaser.Tweens.Tween | null = null; private highlightTween: Phaser.Tweens.Tween | null = null;
private _cardId: string; private _cardId: string;
private _rotation: number = 0;
constructor(scene: OnitamaScene, cardId: string, card: Card) { constructor(scene: OnitamaScene, cardId: string, card: Card, rotation: number = 0) {
super(scene, 0, 0); super(scene, 0, 0);
this._cardId = cardId; this._cardId = cardId;
this._rotation = rotation;
// 将容器添加到场景 // 将容器添加到场景
scene.add.existing(this); scene.add.existing(this);
// 应用旋转
this.angle = rotation;
// 创建卡牌视觉 // 创建卡牌视觉
this.createCardVisual(card); this.createCardVisual(card);
@ -42,6 +47,26 @@ export class CardContainer extends Phaser.GameObjects.Container {
this.addHighlightEffect(scene); this.addHighlightEffect(scene);
} }
/**
*
*/
setRotation(rotation: number, animated: boolean = false): this {
if (animated) {
const currentAngle = this.angle;
const tween = this.scene.tweens.add({
targets: this,
angle: { from: currentAngle, to: rotation },
duration: 400,
ease: 'Back.easeOut',
});
(this.scene as OnitamaScene).addTweenInterruption(tween);
} else {
this.angle = rotation;
}
this._rotation = rotation;
return this;
}
/** /**
* *
*/ */
@ -251,6 +276,20 @@ export class CardSpawner implements Spawner<CardSpawnData, CardContainer> {
} }
onUpdate(data: CardSpawnData, obj: CardContainer): void { onUpdate(data: CardSpawnData, obj: CardContainer): void {
const isBlackTurn = this.scene.state.currentPlayer === 'black';
// 检查卡牌是否需要旋转
let targetRotation = 0;
if (data.position === 'black') {
targetRotation = -180; // 黑方卡牌始终旋转
} else if (data.position === 'spare' && isBlackTurn) {
targetRotation = -180; // 备用卡牌在黑方回合旋转
}
if (obj.angle !== targetRotation) {
obj.setRotation(targetRotation, true);
}
// 只在位置实际变化时才播放移动动画 // 只在位置实际变化时才播放移动动画
if (!this.hasPositionChanged(data)) { if (!this.hasPositionChanged(data)) {
this.previousData.set(data.cardId, { ...data }); this.previousData.set(data.cardId, { ...data });
@ -285,7 +324,16 @@ export class CardSpawner implements Spawner<CardSpawnData, CardContainer> {
return emptyContainer; return emptyContainer;
} }
const container = new CardContainer(this.scene, data.cardId, card); // 计算旋转角度
const isBlackTurn = this.scene.state.currentPlayer === 'black';
let rotation = 0;
if (data.position === 'black') {
rotation = 180; // 黑方卡牌始终旋转
} else if (data.position === 'spare' && isBlackTurn) {
rotation = 180; // 备用卡牌在黑方回合旋转
}
const container = new CardContainer(this.scene, data.cardId, card, rotation);
const pos = this.getCardPosition(data); const pos = this.getCardPosition(data);
container.x = pos.x; container.x = pos.x;
container.y = pos.y; container.y = pos.y;

View File

@ -228,7 +228,6 @@ export class PawnSpawner implements Spawner<Pawn, PawnContainer> {
targets: obj, targets: obj,
scale: 0, scale: 0,
alpha: 0, alpha: 0,
y: obj.y - 30,
duration: 300, duration: 300,
ease: 'Back.easeIn', ease: 'Back.easeIn',
onComplete: () => obj.destroy(), onComplete: () => obj.destroy(),