Files
Continentis/Assets/Scripts/MainGame/Commands/Cmd_DrawCards.cs

86 lines
3.8 KiB
C#
Raw Normal View History

2025-10-03 00:02:43 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Card;
using Continentis.MainGame.Character;
using DG.Tweening;
using SoulliesFramework.General;
using UniRx;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Continentis.MainGame.Commands
{
public class Cmd_DrawCards : CommandBase
{
private readonly DeckSubmodule deck;
private readonly int drawCount;
private readonly float interval;
private readonly float singleCardAnimationDuration = 0.5f; // 单张卡牌的动画时长
public Cmd_DrawCards(DeckSubmodule deck, int drawCount, float interval)
{
this.deck = deck;
this.drawCount = drawCount;
this.interval = interval;
}
protected override IObservable<Unit> OnExecute(CommandContext context)
{
// 确定最终能抽的数量
int finalDrawCount = Mathf.Min(drawCount, deck.DrawPile.Count);
if (finalDrawCount <= 0)
{
Debug.Log("无牌可抽。");
context.sharedInfo["DrawnCards"] = new List<CardLogicBase>();
return Observable.Return(Unit.Default);
}
else
{
Debug.Log($"最终抽取 {finalDrawCount} 张卡牌。");
}
// 从抽牌堆顶部取出卡牌
List<CardInstance> drawnCards = deck.DrawPile.Take(finalDrawCount).ToList();
// --- 关键:将结果存入上下文 ---
// 这替代了 'out' 参数,让后续指令可以访问到这次抽到的牌。
context.sharedInfo["DrawnCards"] = drawnCards;
Debug.Log($"抽取 {drawnCards.Count} 张卡牌并将列表存入DrawnCards。");
// --- 2. 异步的动画阶段 ---
// 创建一个交错的动画流,和我们修正后的 Cmd_DiscardCards 完全一样
return drawnCards.ToObservable()
.Zip(Observable.Interval(TimeSpan.FromSeconds(interval)), (card, _) => card)
// 使用 Select 将每个 card 和它的索引传递给动画方法
.Select((card, index) => Draw(index, drawnCards.Count))
.Merge() // 并行执行所有交错开始的动画
.Last() // 等待最后一个动画流完成
.AsUnitObservable();
}
private IObservable<Unit> Draw(int index, int totalCount)
{
CardInstance card = deck.DrawPile[0];
deck.TransferCard(deck.DrawPile, deck.HandPile, card);
card.cardLogic.eventSubmodule.onDraw.Invoke();
card.handCardView.TransferCardView(CombatUIManager.Instance.deckPage.handPile);
Vector3 targetPosition = CombatUIManager.Instance.deckPage.handPile.GetCardPosition(index, totalCount);
Quaternion targetRotation = CombatUIManager.Instance.deckPage.handPile.GetCardRotation(index, totalCount);
Vector3 deltaMove = targetPosition - card.handCardView.cardTransform.localPosition;
Vector3 randomLift = new Vector3(Random.Range(-200f, 200f), Random.Range(200f, 600f), 0);
card.handCardView.cardTransform.DOBlendableLocalMoveBy(deltaMove, singleCardAnimationDuration).Play();
card.handCardView.cardTransform.DOBlendableLocalMoveBy(randomLift, singleCardAnimationDuration * 0.5f).SetLoops(2, LoopType.Yoyo).Play();
card.handCardView.cardTransform.DOLocalRotateQuaternion(targetRotation, singleCardAnimationDuration).Play();
card.handCardView.cardTransform.DOScale(Vector3.one, singleCardAnimationDuration).Play();
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
}
}
}