【Unity】类杀戮尖塔手牌系统实现(初始卡组、随机抽牌、卡牌绘制)

制作初始卡组

  1. DontDestroyOnLoad 的物体下挂不会被销毁的Global脚本,用于跨场景调用玩家当前手牌
  2. 制作ScriptableObject类型的卡资源,这样策划可以直接在Unity编辑器中新建并填写数据来制作多个卡牌
public enum CardClass {Attack,Armor,Thron,Special }
[CreateAssetMenu(menuName = "Create CardAsset ")]
public class CardAsset : ScriptableObject
{
    [Header("描述一张卡牌的功能")]
    [Space]
    [Tooltip("ID")]
    public int cardID;
    [Tooltip("价格")]
    public int price;
    [Tooltip("稀有度")]//数字越大越稀有
    public int value;
}
  1. 添加了很多其他属性后制作好的CardAsset的样子
    制作好的CardAsset

  2. 并在命名时直接使用从0开始的数字,方便使用Resource.Load()
    制作好的多个CardAsset

  3. 脚本在Awake()中直接从资源中寻找卡的资源 Cards

  4. 简单粗暴的直接定义玩家手牌CardAsset,缺点:对策划来说改起来麻烦,优点:易于后期添加手牌

private void Awake()
    {
        //cards是卡资源
        for (int i = 0; i < 6; i++)
        {
            cards[i] = Resources.Load<CardAsset>(i.ToString());
        }
        //cardAsset卡池
        cardAsset = new CardAsset[]{cards[0], cards[0], cards[0], cards[1], cards[2], cards[3], cards[3], cards[3], cards[3], cards[4], cards[5] };
        Debug.Log("global.cardAsset.length =" + cardAsset.Length.ToString());

    }

随机抽牌

杀戮尖塔的抽牌系统

  • 玩家手牌在关卡中被分成可视化的抽牌堆(NotUsedCard)和弃牌堆(UsedCard)
  • 每轮都是从抽牌堆中抽牌,但当抽牌堆无牌时,弃牌堆数量归零,抽牌堆为全部手牌
  • 如果每轮发牌数多于当前抽牌堆牌数,那么玩家下回合抽到的牌,必包括当前抽牌堆所有牌

所以我是这么写的:

  1. 先定义两个CardAsset数组,作为抽牌堆和弃牌堆
    [Tooltip("当前关卡的牌库")]
    [SerializeField]
    public CardAsset[] NotUsedCard;
    //public CardAsset[] NotUsedCard;
    public CardAsset[] UsedCard;
  1. 写生成多张牌的方法,也就是每轮发牌调用的方法:其中CardNum代表每轮发牌数,用ExistCard数组保存已生成的卡,方便销毁
public void DeliverCard(int CardNum)
    {
        ExistCard = new GameObject[CardNum];
        //顺手删除没用完的卡
        if (ExistCard != null)
        {
            foreach (var ec in ExistCard)
            {
                Destroy(ec);
            }
        }
        //生成单张卡
        for (int i = 0; i < CardNum; i++)
        {
            StartCoroutine(CardAppear(i, CardNum, i * 0.1f));
        }
    }
  1. 写生成单张卡的函数
IEnumerator CardAppear(int i,int CardNum, float Wait)
    {
        yield return new WaitForSeconds(Wait);

        //当抽牌堆里已经没有牌的时候
        if (bs.NotUsedCard.Length == 0)
        {
            //重置抽牌堆和弃牌堆
            NotUsedCard = CardBundle;
            UsedCard = Array.Empty<CardAsset>();
            //抽牌堆用随机种子洗牌:遍历每个元素,将它和随机的元素交换位置
            for (int j = 0; j < bs.NotUsedCard.Length - 1; j++)
            {
                int rd = random.Next(0,bs.NotUsedCard.Length - 1);
                var t = bs.NotUsedCard[rd];
                bs.NotUsedCard[rd] = bs.NotUsedCard[j];
                bs.NotUsedCard[j] = t;
            }
            //随机种子重置,以免每次洗牌结果相同
            random = new System.Random(++seed);
        }
        
        //拿到抽牌堆的最后一张牌
        int r = bs.NotUsedCard.Length - 1;
        //抽牌堆长度减一
        Array.Resize(ref bs.NotUsedCard,bs.NotUsedCard.Length - 1);
        
        //弃牌堆长度加一
        Array.Resize(ref bs.UsedCard,bs.UsedCard.Length + 1);
        //弃牌堆最后一个元素变成抽到的牌
        bs.UsedCard[bs.UsedCard.Length - 1] = cardData;
   
        //拿到卡的数据
        var cardData = bs.NotUsedCard[r];
        //生成牌
        var newCard = Instantiate(card, DeliverPos.transform.position,transform.rotation,transform);
        
        ExistCard[i] = newCard;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值