我以 JSON 形式获取卡片数据,它被添加到我的牌组列表中,但是当我开始绘制卡片的 ID 时,这表明卡片的信息不相同,而是随机的。例如:
{ "cardsWithThisId": [ 0, 0, 0, 0, 0, 0, 0, 0, 40 ] }
在我的 JSON 中,这应该意味着我有 40 张 ID 为 8 的卡片,因为目前它是 0 - 8。
可能是随机播放失败,但我完全不确定
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System.IO;
public class PlayerDeck : MonoBehaviour
{
public List<Card> deck = new List<Card>();
public List<Card> container = new List<Card>();
public static List<Card> staticDeck = new List<Card>();
private CustomDeckData deckData;
public int x;
public static int deckSize;
public GameObject cardInDeck1;
public GameObject cardInDeck2;
public GameObject cardInDeck3;
public GameObject cardInDeck4;
public GameObject CardBack;
public GameObject CardToHand;
public GameObject Deck;
public GameObject[] Clones;
public GameObject Hand;
// Reference to ThisCard script
public ThisCard thisCardScript;
public TextMeshProUGUI LoseText;
public GameObject LoseTextGameObject;
// Start is called before the first frame update
void Start()
{
LoadDeckFromJSON(); // Load the deck from JSON
thisCardScript = GetComponentInChildren<ThisCard>();
StartCoroutine(StartGame());
}
// Update is called once per frame
void Update()
{
if (deckSize <= 0)
{
LoseTextGameObject.SetActive(true);
LoseText.text = "Deck Out, You Lose";
}
staticDeck = deck;
if (deckSize < 30)
{
cardInDeck1.SetActive(false);
}
if (deckSize < 20)
{
cardInDeck2.SetActive(false);
}
if (deckSize < 2)
{
cardInDeck3.SetActive(false);
}
if (deckSize < 1)
{
cardInDeck4.SetActive(false);
}
if (ThisCard.drawX > 0)
{
StartCoroutine(Draw(ThisCard.drawX));
ThisCard.drawX = 0;
}
if (TurnSystem.startTurn == true)
{
StartCoroutine(Draw(1));
TurnSystem.startTurn = false;
}
}
void LoadDeckFromJSON()
{
// Load the JSON file into a string
string jsonString = File.ReadAllText(Application.persistentDataPath + "/deck.json");
// Parse the JSON string into a CustomDeckData object
deckData = JsonUtility.FromJson<CustomDeckData>(jsonString);
if (deckData != null)
{
// Clear the existing deck
deck.Clear();
// Populate the deck based on the loaded data
for (int i = 0; i < deckData.cardsWithThisId.Length; i++)
{
int cardId = deckData.cardsWithThisId[i];
// Find the corresponding card in the database and add it to the deck
for (int j = 0; j < cardId; j++)
{
Card foundCard = CardDataBase.cardList.Find(card => card.id == i);
if (foundCard != null)
{
deck.Add(foundCard);
}
}
}
deckSize = deck.Count; // Set the deck size based on the loaded deck
}
}
IEnumerator Example()
{
yield return new WaitForSeconds(1);
Clones = GameObject.FindGameObjectsWithTag("Deck");
foreach (GameObject Deck in Clones)
{
Destroy(Deck);
}
}
IEnumerator StartGame()
{
// Draw 4 initial cards
for (int i = 0; i <= 4; i++)
{
DrawCardToHand();
yield return new WaitForSeconds(1);
}
}
public void DrawCardToHand()
{
if (deckData != null && deckData.cardsWithThisId.Length > 0)
{
// Iterate through the loaded deck IDs
foreach (int cardId in deckData.cardsWithThisId)
{
// Find the corresponding card in the database
Card drawnCard = CardDataBase.cardList.Find(card => card.id == cardId);
// If the card is found, draw it and remove from the deck
if (drawnCard != null)
{
// Set the ID on the ThisCard script before instantiating
if (thisCardScript != null)
{
thisCardScript.thisID = drawnCard.id;
}
else
{
Debug.LogError("thisCardScript is null");
}
// Instantiate the CardToHand object
Instantiate(CardToHand, transform.position, transform.rotation);
deckSize--;
return; // Exit the method after drawing one card
}
}
Debug.LogWarning("No more cards to draw from the loaded deck.");
}
else
{
Debug.LogWarning("Deck data is missing or empty, cannot draw more cards.");
}
}
public void Shuffle()
{
for (int i = 0; i < deckSize; i++)
{
container[0] = deck[i];
int randomIndex = Random.Range(i, deckSize);
deck[i] = deck[randomIndex];
deck[randomIndex] = container[0];
}
Instantiate(CardBack, transform.position, transform.rotation);
StartCoroutine(Example());
}
IEnumerator Draw(int x)
{
for (int i = 0; i < x; i++)
{
yield return new WaitForSeconds(1);
DrawCardToHand();
}
}
}
[System.Serializable]
public class CustomDeckData
{
public int[] cardsWithThisId;
}
这是卡牌代码,如果你想查看的话,尽管我想重点关注playerdeck代码。
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class ThisCard : MonoBehaviour
{
private List<Card> thisCardList = new List<Card>();
public int thisID;
public int id;
public string cardName;
public int cost;
public int power;
public string cardDescription;
public TextMeshProUGUI nameText;
public TextMeshProUGUI costText;
public TextMeshProUGUI powerText;
public TextMeshProUGUI descriptionText;
public Sprite thisSprite;
public Image thatImage;
public Image frame;
public bool cardBack;
CardBack CardBackScript;
public GameObject Hand;
public int numberOfCardsInDeck;
public bool canBeSummon;
public bool summoned;
public GameObject battleZone;
public static int drawX;
public int drawXcards;
public int addXmaxGil;
public GameObject attackBorder;
public GameObject Target;
public GameObject Enemy;
public bool summoningSickness;
public bool cantAttack;
public bool canAttack;
public static bool staticTargeting;
public static bool staticTargetingEnemy;
public bool targeting;
public bool targetingEnemy;
public bool onlyThisCardAttack;
public GameObject summonBorder;
public bool canBeDestroyed;
public GameObject Graveyard;
public bool beInGraveyard;
public int hurted;
public int actualpower;
public int returnXcards;
public bool useReturn;
public int resurrectXcards;
public static bool UcanReturn;
public int healXpower;
public bool canHeal;
public static bool useRevive;
public int boostXpower;
public bool canBoost;
public GameObject EnemyZone;
public AICardToHand aiCardToHand;
public bool spell;
public int damageDealtBySpell;
public bool dealDamage;
public bool stopDealDamage;
public bool ward;
public bool directattack;
public GameObject wardguard;
// Start is called before the first frame update
void Start()
{
CardBackScript = GetComponent<CardBack>();
thisCardList.Add(CardDataBase.cardList[Random.Range(1, CardDataBase.cardList.Count)]);
thatImage.sprite = thisCardList[0].thisImage;
//UpdateUI();
canBeSummon = false;
summoned = false;
drawX = 0;
canAttack = false;
summoningSickness = true;
Enemy = GameObject.Find("Enemy HP");
targeting = false;
targetingEnemy = false;
beInGraveyard = false;
canHeal = true;
canBoost = true;
directattack = true;
EnemyZone = GameObject.Find("EnemyZone");
Graveyard = GameObject.Find("MyGraveyard");
}
// Update is called once per frame
void Update()
{
Hand = GameObject.Find("Hand");
if (this.transform.parent == Hand.transform)
{
cardBack = false;
}
id = thisCardList[0].id;
cardName = thisCardList[0].cardName;
cost = thisCardList[0].cost;
power = thisCardList[0].power;
actualpower = power - hurted;
cardDescription = thisCardList[0].cardDescription;
thisSprite = thisCardList[0].thisImage;
drawXcards = thisCardList[0].drawXcards;
addXmaxGil = thisCardList[0].addXmaxGil;
returnXcards = thisCardList[0].returnXcards;
healXpower = thisCardList[0].healXpower;
boostXpower = thisCardList[0].boostXpower;
spell = thisCardList[0].spell;
damageDealtBySpell = thisCardList[0].damageDealtBySpell;
ward = thisCardList[0].ward;
resurrectXcards = thisCardList[0].resurrectXcards;
// Check for color condition using the color property of the Card class
if (thisCardList[0].color == "White")
{
frame.color = new Color32(255, 255, 255, 255); // Set the color to white
}
else if (thisCardList[0].color == "Blue")
{
frame.color = new Color32(26, 109, 236, 255); // Set the color to white
}
else if (thisCardList[0].color == "Green")
{
frame.color = new Color32(122, 236, 26, 255); // Set the color to white
}
else if (thisCardList[0].color == "Black")
{
frame.color = new Color32(51, 32, 32, 255); // Set the color to white
}
CardBackScript.UpdateCard(cardBack);
UpdateUI();
if (this.tag == "Clone")
{
thisCardList[0] = PlayerDeck.staticDeck[PlayerDeck.deckSize - 1];
PlayerDeck.deckSize--;
cardBack = false;
this.tag = "Untagged";
}
if (this.tag != "Clone")
{
if (TurnSystem.currentGil >= cost && summoned == false && beInGraveyard == false && TurnSystem.isYourTurn ==true)
{
canBeSummon = true;
}
else
{
canBeSummon = false;
}
if (canBeSummon == true)
{
gameObject.GetComponent<Draggable>().enabled = true;
}
else
{
gameObject.GetComponent<Draggable>().enabled = false;
}
battleZone = GameObject.Find("Zone");
if (!summoned && this.transform.parent == battleZone.transform)
{
Summon();
}
if(ward == true && summoned == true)
{
wardguard.SetActive(true);
}
else
{
wardguard.SetActive(false);
}
}
if(canAttack == true && beInGraveyard == false )
{
Debug.Log("Can attack1.");
attackBorder.SetActive(true);
}
else
{
Debug.Log("Can't attack1.");
attackBorder.SetActive(false);
}
if(TurnSystem.isYourTurn == false && summoned == true)
{
summoningSickness = false;
cantAttack = false;
}
if(TurnSystem.isYourTurn == true && summoningSickness == false && cantAttack == false)
{
canAttack = true;
}
else
{
canAttack = false;
}
targeting = staticTargeting;
targetingEnemy = staticTargetingEnemy;
if(targetingEnemy == true)
{
Target = Enemy;
}
else
{
Target = null;
}
if(targeting == true && onlyThisCardAttack == true)
{
Attack();
}
if(canBeSummon == true || UcanReturn == true && beInGraveyard == true || useRevive == true && beInGraveyard == true)
{
summonBorder.SetActive(true);
}
else
{
summonBorder.SetActive(false);
}
/* if (canBeSummon == true || useRevive == true && beInGraveyard == true)
{
summonBorder.SetActive(true);
Debug.Log("revive border test.");
}
else
{
summonBorder.SetActive(false);
}*/
if (actualpower <= 0 && spell == false)
{
Destroy();
canBeDestroyed = true;
}
if(returnXcards > 0 && summoned == true && useReturn == false && TurnSystem.isYourTurn == true)
{
Return(returnXcards);
useReturn = true;
}
if (resurrectXcards > 0 && summoned == true && useRevive == false && TurnSystem.isYourTurn == true)
{
Revive(resurrectXcards);
useRevive = true;
}
if (TurnSystem.isYourTurn == false)
{
useRevive = false;
useReturn = false;
}
if(canHeal == true && summoned == true)
{
Heal();
canHeal = false;
}
if(canBoost == true && summoned == true)
{
// AttackBoost();
// canBoost = false;
}
if(damageDealtBySpell >0)
{
dealDamage = true;
}
if(dealDamage == true && this.transform.parent == battleZone.transform && spell ==true)
{
Debug.Log("spell test1.");
attackBorder.SetActive(true);
}
else if(dealDamage == false && this.transform.parent == battleZone.transform && spell == true)
{
Debug.Log("spell test2.");
attackBorder.SetActive(false);
}
if(dealDamage == true && this.transform.parent == battleZone.transform)
{
Debug.Log("Attempting to speelll test.");
dealxDamage(damageDealtBySpell);
}
if(stopDealDamage == true)
{
Debug.Log("Stop deal damage test.");
attackBorder.SetActive(false);
dealDamage = false;
}
if(this.transform.parent == battleZone.transform && spell == true && dealDamage == false)
{
Debug.Log("Spell gone");
canBeDestroyed = true;
Destroy();
}
foreach (Transform child in EnemyZone.transform)
{
AICardToHand childAICard = child.GetComponent<AICardToHand>();
if (childAICard.ward == true)
{
directattack = false;
}
else
{
directattack = true;
}
}
}
public void Summon()
{
TurnSystem.currentGil -= cost;
summoned = true;
MaxGil(addXmaxGil);
drawX = drawXcards;
}
public void MaxGil(int x)
{
TurnSystem.maxGil += x;
}
void UpdateUI()
{
nameText.text = cardName;
costText.text = cost.ToString();
powerText.text = actualpower.ToString();
descriptionText.text = cardDescription;
thatImage.sprite = thisSprite;
}
public void Attack()
{
if (canAttack && summoned && Target != null)
{
Debug.Log("Attempting to attack.");
if (Target == Enemy && directattack == true)
{
Debug.Log("Attacking Enemy");
EnemyHp.staticHp -= power;
targeting = false;
cantAttack = true;
}
}
else
{
// Debug.Log("Attempting to attack AI.");
foreach (Transform child in EnemyZone.transform)
{
AICardToHand childAICard = child.GetComponent<AICardToHand>();
if ( childAICard.isTarget == true && cantAttack == false)
{
Debug.Log("Target found in EnemyZone.");
childAICard.hurted += actualpower; // Adjusting hurted value by the power of the attacking card
hurted = childAICard.actualpower;
cantAttack = true;
}
/* else
{
Debug.LogError("AICardToHand component not found or conditions not met on the target AI card.");
}*/
}
}
}
public void UntargetEnemy()
{
staticTargetingEnemy = false;
}
public void TargetEnemy()
{
staticTargetingEnemy = true;
}
public void StartAttack()
{
staticTargeting = true;
}
public void StopAttack()
{
staticTargeting = false;
}
public void OneCardAttack()
{
onlyThisCardAttack = true;
}
public void OneCardAttackStop()
{
onlyThisCardAttack = false;
}
public void Destroy()
{
Graveyard = GameObject.Find("MyGraveyard");
if(canBeDestroyed == true)
{
this.transform.SetParent(Graveyard.transform);
canBeDestroyed = false;
summoned = false;
beInGraveyard = true;
hurted = 0;
}
}
public void Revive(int x)
{
for (int i = 0; i <= x; i++)
{
ReviveCard();
}
}
public void ReviveCard()
{
Debug.Log("Revive card test.");
useRevive = true;
actualpower += power;
}
public void Return(int x)
{
for(int i = 0; i <= x; i++)
{
ReturnCard();
}
}
public void ReturnCard()
{
UcanReturn = true;
}
public void ReturnThis()
{
if (beInGraveyard == true && UcanReturn == true && Graveyard.transform.childCount > 0)
{
this.transform.SetParent(Hand.transform);
UcanReturn = false;
beInGraveyard = false;
summoningSickness = true;
}
else if (beInGraveyard == true && useRevive == true && Graveyard.transform.childCount > 0 && spell == false)
{
this.transform.SetParent(battleZone.transform);
useRevive = false;
beInGraveyard = false;
summoningSickness = true;
}
/* else if (beInGraveyard == true && useRevive == true && Graveyard.transform.childCount == 0)
{
this.transform.SetParent(Hand.transform);
UcanReturn = false;
beInGraveyard = false;
summoningSickness = true;
}*/
}
/* public void ReviveThis()
{
if (beInGraveyard == true && useRevive == true && Graveyard.transform.childCount > 0)
{
Debug.Log("Reviving card");
this.transform.SetParent(Hand.transform);
useRevive = false;
beInGraveyard = false;
summoningSickness = true;
}
else
{
Debug.Log("Revive conditions not met");
Debug.Log("beInGraveyard: " + beInGraveyard);
Debug.Log("useRevive: " + useRevive);
Debug.Log("Graveyard child count: " + Graveyard.transform.childCount);
}
}*/
public void Heal()
{
PlayerHp.staticHp += healXpower;
}
/*public void AttackBoost()
{
power += boostXpower; // Update power first
actualpower = power - hurted; // Update actualpower after modifying power
UpdateUI();
}*/
public void dealxDamage(int x)
{
if (Target != null)
{
if (staticTargetingEnemy = true && stopDealDamage == false && Input.GetMouseButton(0))
{
EnemyHp.staticHp -= damageDealtBySpell;
stopDealDamage = true;
}
}
else
{
foreach (Transform child in EnemyZone.transform)
{
Debug.Log("Attempting to deal damage to AI.");
AICardToHand childAICard = child.GetComponent<AICardToHand>();
if (childAICard.isTarget == true && stopDealDamage == false)
{
childAICard.hurted += damageDealtBySpell; // Adjusting hurted value by the power of the attacking card
stopDealDamage = true;
Debug.Log("Test)");
}
}
}
}
}
在
DrawCardToHand
中,您迭代原始的 deckData.cardsWithThisId
。
相反,您可能应该使用
deck
!
此外,像
deckSize
等附加字段并不是真正必要的,需要做更多的工作来保持它们同步。
你可能应该做类似的事情
// use correct prefab type - see further below
// ThisCard is btw a very misleading class name
public ThisCard CardToHand;
public void DrawCardToHand()
{
// do not hide essential issues like deckData being null
// You would WANT an exception in that case because it means
// that something is essentially wrong in your app
if (deck.Count > 0)
{
// there is no real need to shuffle your deck
// simply access a random index
var randomIndex = Random.Range(0, deck.Count);
var drawnCard = deck[randomIndex];
deck.RemoveAt(randomIndex);
// // Set the ID on the ThisCard script before instantiating
// No! Instead rather use correct prefab type and set it on the newly spawned instance!
var cardInstance = Instantiate(CardToHand, transform.position, transform.rotation);
cardInstance.thisID = drawnCard.id;
}
else
}
Debug.LogWarning("No more cards to draw from the loaded deck.");
}
}
然后进一步
ThisCard
id
和 thisID
List<Card> thisCardList
?thisCardList[0]
中每一帧的硬编码值来推翻你可能从外部设置的任何内容?
Update
后,我宁愿希望您现在用相应的
cardInstance
数据填充它并执行类似的操作drawnCard
然后在上面做
public class ThisCard : MonoBehaviour
{
public Card AssociatedCard { get; private set; }
public void Initialize(Card card)
{
AssociatedCard = card;
// TODO initialize displayed visuals accordingly
}
}