咕咕咕,鸽了好久,今天来继续我们的游戏开发
今天实现的内容是把卡牌加入卡组,从文件读取卡组,从卡组删除卡牌,把卡组保存到文件中。
---------------------------------------------------分割线---------------------------------------------------------------------
首先是卡牌加入卡组。上一期我们实现了加载所有卡牌列表,现在我想要点击某张卡牌时它能够加入到卡组中。那么我们先新建一个卡组ui,用来显示卡组中的卡牌。
大概这样。我们需要卡牌按一定的规则排列好,方便检查卡组,所以在卡组对象下挂一个空对象,给它加一个Grid Layout Group组件,这样可以让它的子对象以表格的显示显示。
约束计数就是一行放多少个子对象。上面的数据自己看着填就行。
接下来要做的事情很简单:点击卡牌列表的卡牌时,新建一个子对象挂在deck_parent上。首先我们把card_inlist预制体复制一下,后面还得做个卡组中的卡牌。因为需要增加点击事件,所以在预制体中增加一个空对象,在上面挂一个脚本,脚本里写一个public的函数,然后给预制体增加点击事件,把这个空对象放到点击事件中,右侧选择刚刚写的函数即可。我写的函数名字是PushCard
可以在PushCard函数中写个debug测试一下能不能正常触发事件。
思考一下,我们要往卡组里增加卡牌,如何表示卡组中的卡牌数量呢,有两种方法,一是有多少张就显示多少张,二是在卡牌上显示一个数字,表示卡组里面的这张卡牌已经有多少张了。为了方便,我选择了第二种。因此,我们要用到刚刚复制出来的预制体。
把复制出来的预制体改名为Card_indeck,表示这个卡牌预制体是用来在卡组中显示的。给它添加一个新的空对象名为nums,方便管理卡牌数量。其实在随便一个预制体的脚本增加一个public的变量也行,只要会调用就行。在nums下面挂一个text组件,用来存储和显示数量。
接下来回到PushCard函数,首先获取所有卡牌列表,方便添加卡牌到卡组中。然后获取卡组当前卡牌列表,如果点击的卡牌的id不存在于卡组中,那么新建一个卡牌对象放入卡组;如果存在,就传入id,调用Card_indeck的脚本把对应id的卡牌的nums加一。(这个函数等下讲)
public void PushCard()
{
Cardlist = GameObject.Find("parent").GetComponent<showcard>().card_informations_list;
//把卡牌加入卡组,按下按钮后再保存
//Debug.Log(transform);
//Debug.Log("PushCard");
//首先读取DeckScript的卡牌列表
int id = transform.parent.GetComponent<saveCardInformation>().id;//踩坑,这个脚本放在了子物体上,导致一开始找不到指定的脚本
if (GameObject.Find("deck_parent").GetComponent<DeckScript>().deck[id] != null)
{
//获取卡牌数量,转为int类型然后加一
string nums_string = GameObject.Find("deck_parent").GetComponent<DeckScript>().deck[id].transform.Find("nums").GetComponent<TextMeshProUGUI>().text;
int.TryParse(nums_string, out int nums);
nums++;
GameObject.Find("deck_parent").GetComponent<DeckScript>().deck[id].transform.Find("nums").GetComponent<TextMeshProUGUI>().text=nums.ToString();
}
else
{
//如果当前卡组没有这张卡牌,调用函数新建卡牌
GameObject.Find("deck_parent").GetComponent<DeckScript>().AddToParent(id,Cardlist,true);
}
}
好了,让我们回到卡组。为了读取卡组文件,在deck对象下挂一个脚本,读取卡组文件并生成卡牌显示在卡组框中。
private int[] Cards=new int[100];//下标就是卡牌编号,数组数字就是下标id的卡牌的数量
public TextAsset DeckText;//卡组文件
public GameObject card_indeck;//卡组卡牌预制件
public GameObject[] deck;//卡组卡牌数组
首先是读取文件。这里我用的是public的textassest变量,可以在unity中把文本文件放到上面。根据逗号来分割每一行的内容。卡组文件只需要存储id和数量num就行。csv文件最后有一个回车,如果读取到最后一行,说明item的长度是0,直接跳过。id和num已经存入数组Cards,可以在其他函数直接调用。
void GetDeckFile()
{
//string path_root = Directory.GetCurrentDirectory()+ "/Assets/deck/deck.csv";
string[] datarow = DeckText.text.Split("\n");
foreach (var item in datarow)
{
if (item.Length == 0)
{
continue;
}
string[] carddata = item.Split(',');
if (carddata[0] == "id")
{
continue;
}
int.TryParse(carddata[0], out int id);
int.TryParse(carddata[1], out int num);
Cards[id] = num;
}
}
然后是把刚刚拿到的数组变成ui显示出来,函数根据id来读取之前初始化好的卡牌列表,把每一张卡牌的信息存入实例化的卡牌中,这样子就可以让卡牌信息显示出来。其中的bool isadd用来判断是添加卡牌还是卡牌数量加一。添加卡牌就是上面写的,点击卡牌往卡组添加。
void LoadDeck()
{
//先读取所有卡牌的文件
List<Card_information> Cardlist = new();
Cardlist = GameObject.Find("parent").GetComponent<showcard>().card_informations_list;
//遍历卡组列表
for (int id = 1; id < Cards.Length; id++)
{
//如果卡牌数量为0则不显示
if (Cards[id] == 0)
{
continue;
}
//生成卡牌并作为子对象放在deck下
AddToParent(id, Cardlist,false);
}
}
//把卡牌显示在卡组中额外写一个函数,方便其他脚本调用
public void AddToParent(int id, List<Card_information> Cardlist,bool IsAdd)
{
GameObject a = Instantiate(card_indeck, transform.position, Quaternion.identity);//实例化物体
a.transform.Find("name").GetComponent<TextMeshProUGUI>().text = Cardlist[id - 1].name;
a.transform.Find("attack").GetComponent<TextMeshProUGUI>().text = Cardlist[id - 1].attack.ToString();
a.transform.Find("defense").GetComponent<TextMeshProUGUI>().text = Cardlist[id - 1].defense.ToString();
a.transform.Find("fakang").GetComponent<TextMeshProUGUI>().text = Cardlist[id - 1].fakang.ToString();
a.transform.Find("health").GetComponent<TextMeshProUGUI>().text = Cardlist[id - 1].health.ToString();
a.transform.Find("Character_image").GetComponent<Image>().sprite = Cardlist[id - 1].Character.sprite;//因为cardlist是从零开始,所以减一
if(IsAdd)
{
Cards[id]++;
}
a.transform.Find("nums").GetComponent<TextMeshProUGUI>().text = Cards[id].ToString();
a.transform.parent = this.transform;
//把实例化的物体加入数组,方便修改
//UnityEngine.Debug.Log(deck.Length);
deck[id] = a;
Saveinformation(a, Cardlist[id - 1].id, Cardlist[id - 1].cost, Cardlist[id - 1].name, Cardlist[id - 1].attack, Cardlist[id - 1].defense, Cardlist[id - 1].health, Cardlist[id - 1].fakang, Cardlist[id - 1].birth, Cardlist[id - 1].career, Cardlist[id - 1].force, Cardlist[id - 1].race, Cardlist[id - 1].description, Cardlist[id - 1].Character);
}
//用来保存卡牌信息,方便显示
void Saveinformation(GameObject a, int _id, int _cost, string _name, double _attack, double _defense, float _health, double _fakang, string _birth, string _career, string _force, string _race, string _des, UnityEngine.UI.Image _ch)
{
a.GetComponent<saveCardInformation>().id = _id;
a.GetComponent<saveCardInformation>().cost = _cost;
a.GetComponent<saveCardInformation>().cardname = _name;
a.GetComponent<saveCardInformation>().attack = _attack;
a.GetComponent<saveCardInformation>().defense = _defense;
a.GetComponent<saveCardInformation>().health = _health;
a.GetComponent<saveCardInformation>().fakang = _fakang;
a.GetComponent<saveCardInformation>().birth = _birth;
a.GetComponent<saveCardInformation>().career = _career;
a.GetComponent<saveCardInformation>().force = _force;
a.GetComponent<saveCardInformation>().race = _race;
a.GetComponent<saveCardInformation>().description = _des;
a.GetComponent<saveCardInformation>().Character = _ch;
}
然后是删除卡牌,这个很简单,点击卡组中的卡牌触发删除函数,num-1,如果num=0,就销毁卡牌实例。随便在卡牌的脚本中写一个简单的销毁函数。
public void deleteself()
{
Destroy(gameObject);
}
如法炮制,给卡组的卡牌弄一个删除按钮函数
public void DeleteButton()
{
Debug.Log(transform.parent);
string num=transform.parent.Find("nums").GetComponent<TextMeshProUGUI>().text;
int.TryParse(num, out int num_int);
num_int--;
if(num_int == 0)
{
transform.parent.GetComponent<show_in_deckedit>().deleteself();
}
else
{
transform.parent.Find("nums").GetComponent<TextMeshProUGUI>().text=num_int.ToString();
}
}
最后就是保存卡组。文章来源:https://www.toymoban.com/news/detail-860094.html
public void SaveDeckFuntion()
{
//根据tag获取卡组中的卡牌对象
GameObject[] CardDeckList = GameObject.FindGameObjectsWithTag("CardInDeck");
using (StreamWriter sw = new(@"Assets\deck\deck.csv"))
{
foreach (GameObject card in CardDeckList)
{
//获取每一张卡牌的id和nums
string num_str = card.transform.Find("nums").GetComponent<TextMeshProUGUI>().text;
int id = card.transform.GetComponent<saveCardInformation>().id;
//把id和nums写入csv文件
string csv_str = id.ToString() + "," + num_str;
sw.WriteLine(csv_str);
}
}
}
至此,卡组编辑界面已经差不多完成。检索卡牌还没做,以后有机会再实现吧。接下来就是实现战斗了。文章来源地址https://www.toymoban.com/news/detail-860094.html
到了这里,关于unity卡牌游戏开发记录(4)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!