勇者与羁绊 游戏开发日志(五)
开发进度
完成了基本的抽卡弃卡的逻辑
代码思路
首先我需要一个管理类,并且这是一个单例,用于持有一些全局变量以及控制所有的卡牌逻辑
然后从流程上来说分成三个部分展开
一、战斗开始
1.根据获取到的卡牌ID数组生成对象
2.将所有生成的对象打乱后放入抽牌堆数组
二、回合开始
调用抽牌方法,并传入一个int类型的参数,表示抽几张牌
这个参数得由一个管理类持有
三、回合结束
将所有的手牌和在本回合内使用过的卡牌都放入弃牌堆中
Ps.关于抽牌方法的实现逻辑流程图
具体执行步骤
Step1:创建管理类CardManager
public class CardManager : SingletonMonoBehaviour<CardManager>
{
#region Piles
public List<GameObject> AllCards;//所有的卡牌
public List<GameObject> DrawPile;//这是抽牌堆
public List<GameObject> FoldPile;//这是弃牌堆
public List<GameObject> HandPile;//这是手牌堆
public List<GameObject> UsedPile;//这是当前使用区,玩家在回合内打出的卡牌先进入当前使用区,在回合结束的时候再全部转入弃牌堆
public List<GameObject> EquipPile;//这是装备区
public List<GameObject> ExhaustPile;//这是放逐区
#endregion
#region PileParents
public GameObject InitPile_Parent;//生成卡牌对象时所使用的父节点
public GameObject DrawPile_Parent;//抽牌堆的父节点
public GameObject FoldPile_Parent;//弃牌堆的父节点
public GameObject HandPile_Parent;//手牌堆的父节点
public GameObject UsedPile_Parent;//当前使用区的父节点
public GameObject EquipPile_Parent;//装备区的父节点
public GameObject ExhaustPile_Parent;//放逐区的父节点
#endregion
public GameObject CardPrefab;//卡牌的prefab
public int DrawCount;//回合开始时的抽牌数
}
Step2:完成战斗开始部分的逻辑
因为BattleManager是控制战斗流程的管理器,所以通过PlayMaker来加载卡牌数据
LoadBattleInfoAction是扩展自FsmStateAction
public class LoadBattleInfoAction : FsmStateAction
{
public override void OnEnter()
{
LoadMapInfo();
LoadPlayerInfo();
LoadCardInfo();
LoadEnemiesInfo();
Finish();
}
public void LoadMapInfo()
{
//TODO
}
public void LoadPlayerInfo()
{
//TODO
}
public void LoadCardInfo()
{
CardManager._instance.InitCards(TestData._instance.CardIDList);
}
public void LoadEnemiesInfo()
{
//TODO
}
}
所调用的InitCards方法的实现方式:
/// <summary>
/// 战斗开始时初始化卡牌
/// </summary>
/// <param name="IDs"></param>
public void InitCards(List<int> IDs)
{
//根据ID生成卡牌对象
int i = 0;
foreach (int id in IDs)
{
GameObject go = GameObject.Instantiate(CardPrefab, InitPile_Parent.transform);
go.GetComponent<CardScriptContainer>().SetCardScriptByID(id);
AllCards.Add(go);
go.name = id + "";
go.SetActive(false);
i++;
}
//将数组打乱后放入抽牌堆
DrawPile = Disorganize<GameObject>(AllCards); //这是一个用于打乱List的方法,定义在下面
foreach (GameObject go in DrawPile)
{
go.transform.SetParent(DrawPile_Parent.transform);
}
}
/// <summary>
/// 将一个List打乱的方法
/// </summary>
/// <param name="input">所需打乱的List</param>
/// <typeparam name="T">List的类型</typeparam>
/// <returns></returns>
private List<T> Disorganize<T>(List<T> input)
{
List<T> output = new List<T>();
foreach (var item in input)
{
output.Insert(Random.Range(0, output.Count), item);
}
return output;
}
Step3:完成回合开始部分的逻辑
通过PlayMaker对抽牌方法进行调用
以下是抽牌方法的实现方式:
/// <summary>
/// 抽牌
/// </summary>
/// <param name="count">抽牌的数量</param>
public void DrawCard(int count)
{
if (count > DrawPile.Count + FoldPile.Count) count = DrawPile.Count + FoldPile.Count;
if (count == 0) return;
if (count > DrawPile.Count)
{
//如果抽牌堆数量不足的话
Shuffle();//先洗牌
DrawCard(count);//再尝试抽一次牌
}
else
{
//如果抽牌堆数量充足的话
List<GameObject> temp = new List<GameObject>();
//将抽牌堆中的对应数量的卡牌放入手牌堆
for (int i = 0; i < count; i++)
{
HandPile.Add(DrawPile[i]);
temp.Add(DrawPile[i]);
}
//再将放入手牌堆的那些牌从抽牌堆中移除
foreach (GameObject go in temp)
{
DrawPile.Remove(go);
}
//刷新UI
RefreshUI();
}
}
在写抽牌方法的时候,发现了之前流程图中存在的问题,那就是当抽牌数量超过了抽牌堆和弃牌堆数量之和时,会产生无限循环的问题。
因此在第一条判断中,就加入了一个这个判断:
如果抽牌数量大于抽牌堆和弃牌堆之和的话,就将抽牌数量改为最大数量。
如果这个数量是0的话,也就是抽牌堆和弃牌堆都没有卡牌但是仍然要抽牌的话,那么是不会有任何反应的。
抽牌方法中调用了一个洗牌方法
以下是洗牌方法的实现方式:
public void Shuffle()
{
DrawPile.AddRange(Disorganize<GameObject>(FoldPile));//Disorganize是前面提到的打乱一个List的方法
FoldPile.Clear();
RefreshUI();
}
Step4:完成回合结束部分的逻辑
同样是通过PlayMaker调用CardManager的方法
以下是在回合结束时弃牌的方法实现:
public void FoldCardsOnTurnEnd()
{
//将使用区和手牌区的卡牌全部移入弃牌区
FoldPile.AddRange(UsedPile);
FoldPile.AddRange(HandPile);
//然后清空使用区与手牌区
HandPile.Clear();
UsedPile.Clear();
RefreshUI();
}
运行效果
正常情况下的测试
测试数据:
第一回合:
第二回合
上图中蓝色区域的应该移到弃牌堆,红色区域的应该移到手牌堆
实际效果:
第三回合
弃牌区应该为空,因为回合结束的时候先把手牌五张移入弃牌区,第三回合开始的时候要抽五张,但是抽牌堆中只有1张,所以会把弃牌堆洗回抽牌堆
然后手牌区的第一张应该是绿色的那张,下面四张是随机的,因为洗过牌了
抽牌堆则应该都是随机顺序的几张牌
实际效果:
第四回合
跟第二回合应该是同一种情况
实际效果:
第N回合
在N回合后,没有出现报错的现象。
正常情况功能测试完成。
当牌库数量少于每回合抽卡数量时的测试
第一回合
第二回合
第三回合
第N回合
每回合的卡牌顺序都会随机排序,在N回合后,没有出现报错的现象。
测试完成。
寻找合作
目前需要Unity开发程序员、UI美术、二次元人物原画师
数值、关卡、剧情等策划如果有兴趣也可以来聊一聊交流交流
如果有想参与项目的小伙伴,或者只是单纯想交朋友的,都可以添加我QQ:425202998