制作初始卡组
- 在DontDestroyOnLoad 的物体下挂不会被销毁的Global脚本,用于跨场景调用玩家当前手牌
- 制作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;
}
-
添加了很多其他属性后制作好的CardAsset的样子
-
并在命名时直接使用从0开始的数字,方便使用Resource.Load()
-
脚本在Awake()中直接从资源中寻找卡的资源 Cards
-
简单粗暴的直接定义玩家手牌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)
- 每轮都是从抽牌堆中抽牌,但当抽牌堆无牌时,弃牌堆数量归零,抽牌堆为全部手牌
- 如果每轮发牌数多于当前抽牌堆牌数,那么玩家下回合抽到的牌,必包括当前抽牌堆所有牌
所以我是这么写的:
- 先定义两个CardAsset数组,作为抽牌堆和弃牌堆
[Tooltip("当前关卡的牌库")]
[SerializeField]
public CardAsset[] NotUsedCard;
//public CardAsset[] NotUsedCard;
public CardAsset[] UsedCard;
- 写生成多张牌的方法,也就是每轮发牌调用的方法:其中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));
}
}
- 写生成单张卡的函数
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;
}