You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

660 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using System.IO;
public enum GamePhase
{
gameStart,playerDraw,playerAction,enemyDraw,enemyAction
}
public class BattleManager : MonoSingleton<BattleManager>
{
public static BattleManager instance;
public PlayerData playerData;
public PlayerData enemyData;//数据
public PlayerData spellData;
public GameObject cardPrefab;
public List<Card> playerDeckList = new List<Card>();
public List<Card> enemyDeckList = new List<Card>();//卡组数据
public List<Card> spellDeckList = new List<Card>();
public Transform playerHand;
public Transform enemyHand;//手牌
public GameObject[] playerBlocks;
public GameObject[] enemyBlocks;//格子
//public GameObject playerIcon;
//public GameObject enemyIcon;//头像
public GamePhase gamePhase = GamePhase.gameStart;
public UnityEvent phaseChangeEvent = new UnityEvent();
public int[] SummonCountMax = new int[2];
private int[] SummonCounter = new int[2];
//召唤辅助变量
private GameObject waitingMonster;
private int waitingPlayer;
//箭头辅助变量
public GameObject ArrowPrefab;
private GameObject arrow;
public GameObject canvas;
//攻击辅助变量
private GameObject attackingMonster;
private int attackingPlayer;
public GameObject attackArrow;
//效果辅助变量
private GameObject effectingSpell;
private int effectingPlayer;
//引入文件,即学生积分
public TextAsset studentData;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
GameStart();
}
// Update is called once per frame
void Update()
{
if(Input.GetMouseButton(1))
{
waitingMonster = null;
DestroyArrow();
CloseSummonBlocks();
CloseAttackBlocks();
}
}
//游戏流程
//开始游戏:加载数据.卡组洗牌.抽初始手牌
public void GameStart()
{
//读取数据
ReadDeck();
//卡组洗牌
//ShuffletDeck(0);
//ShuffletDeck(1);
//玩家抽卡
//DrawCard(0, 1);
//DrawCard(1, 1);
gamePhase = GamePhase.playerDraw;
phaseChangeEvent.Invoke();
SummonCountMax.CopyTo(SummonCounter, 0);
}
public void ReadDeck()
{
//加载卡组
for (int i = 0;i<playerData.playerDeck.Length;i++)
{
if (playerData.playerDeck[i]!=0)
{
int count = playerData.playerDeck[i];
for(int j = 0;j<count;j++)
{
//playerDeckList.Add(playerData.CardStore.cardList[i]);//引用类型,无法独立会造成混乱
playerDeckList.Add(playerData.CardStore.CopyCard(i));
enemyDeckList.Add(playerData.CardStore.CopyCard(i));
}
}
}
for (int i = 0; i < spellData.playerDeck.Length; i++)
{
if (spellData.playerDeck[i] != 0)
{
int count = spellData.playerDeck[i];
for (int j = 0; j < count; j++)
{
spellDeckList.Add(spellData.CardStore.CopyCard(i));
}
}
}
}
public int DrawStudent()
{
List<float> weights = new List<float>();
float totalWeight = 0;
string[] dateRow = studentData.text.Split('\n');
foreach (var row in dateRow)
{
string[] rowArray = row.Split(',');
if (rowArray[0] == "#")
{
continue;
}
else if (rowArray[0] == "monster")
{
int id = int.Parse(rowArray[1]);
float point = int.Parse(rowArray[3]);
float weight = 1f / point; // 积分越高,权重越小
weights.Add(weight);
totalWeight += weight;
//Debug.Log("Save Card:" + monsterCard.CardName);
}
}
// 归一化权重
for (int i = 0; i < weights.Count; i++)
{
weights[i] /= totalWeight;
}
// 根据权重随机抽取学生
float randomValue = Random.Range(0f, 1f);
float cumulativeWeight = 0f;
for (int i = 0; i < weights.Count; i++)
{
cumulativeWeight += weights[i];
if (randomValue < cumulativeWeight)
{
return i; // 抽中此学生
}
}
return 0; // 不应该到达这里
}
public void ShuffletDeck(int _player)//洗牌函数 可参考网上洗牌算法 这里需要学根据积分权重的洗牌
{
//样例------------------------------------------------
List<Card> shuffletDeck = new List<Card> ();
if(_player==0)
{
shuffletDeck = playerDeckList;
}
else if(_player==1)
{
shuffletDeck = enemyDeckList;
}
for(int i = 0; i<shuffletDeck.Count;i++)
{
int rad = Random.Range(0, shuffletDeck.Count);
Card temp = shuffletDeck[i];
shuffletDeck[i] = shuffletDeck[rad];
shuffletDeck[rad] = temp;
}
}
public void OnclickDrawCard()
{
if (gamePhase == GamePhase.playerDraw)
{
DrawCrad2(0);
SummonCounter[0] = SummonCountMax[0];
gamePhase = GamePhase.playerAction;
phaseChangeEvent.Invoke();
}
if (gamePhase == GamePhase.enemyDraw)
{
DrawCrad2(1);
SummonCounter[1] = SummonCountMax[1];
gamePhase = GamePhase.enemyAction;
phaseChangeEvent.Invoke();
}
}
public void OnclickDrawspellCard()//抽魔法卡,正常游戏逻辑?
{
if (gamePhase == GamePhase.playerAction)
{
DrawCrad3(0, 1);
}
if (gamePhase == GamePhase.enemyAction)
{
DrawCrad3(1, 1);
}
}
public int flag1 = 0;
public void DrawCrad3(int _player, int _count)//抽魔法卡啦啦啦啦啦啦啦
{
PlayerData Deckfrom = spellData;
List<Card> DrawDeck = new List<Card>();
DrawDeck = spellDeckList;
Transform hand = transform;
if (_player == 0)
{
hand = playerHand;
}
else if (_player == 1)
{
hand = enemyHand;
}
for (int i = 0; i < _count; i++)
{
GameObject card = Instantiate(cardPrefab, hand);
if(flag1 == 0)
{
card.GetComponent<CardDisplay>().card = DrawDeck[0];//抽头一张,再把数据清空
flag1 = 1;
DrawDeck.RemoveAt(0);
}
else if(flag1 ==1)
{
card.GetComponent<CardDisplay>().card = DrawDeck[10];//这里的10是因为设计成十张这样抽基本不会超限
flag1 = 2;
DrawDeck.RemoveAt(10);
}
else
{
card.GetComponent<CardDisplay>().card = DrawDeck[DrawDeck.Count - 1];
DrawDeck.RemoveAt(DrawDeck.Count - 1);
}
card.GetComponent<BattleCard>().playerID = _player;
}
}
public void DrawCrad2(int _player)//每次抽一张,根据积分越大抽取概率越低的规则
{
PlayerData Deckfrom = playerData;
Transform hand = transform;
if (_player == 0)
{
Deckfrom = playerData;
hand = playerHand;
}
else if (_player == 1)
{
Deckfrom = enemyData;
hand = enemyHand;
}
GameObject card = Instantiate(cardPrefab, hand);
int _id = DrawStudent();
card.GetComponent<CardDisplay>().card = Deckfrom.CardStore.CopyCard(_id);//不洗牌时相当于卡组此时就是按照学生名单排的将算法选择到的学生id抽取即可
card.GetComponent<BattleCard>().playerID = _player;
}
//public void DrawCrad4(int _player)//抽卡备份版本,此版本可以根据卡组进行修改
//{
// List<Card> DrawDeck = new List<Card>();
// Transform hand = transform;
// if (_player == 0)
// {
// DrawDeck = playerDeckList;
// hand = playerHand;
// }
// else if (_player == 1)
// {
// DrawDeck = enemyDeckList;
// hand = enemyHand;
// }
// GameObject card = Instantiate(cardPrefab, hand);
// int _id = DrawStudent();
// while(_id != 0) { }
// card.GetComponent<CardDisplay>().card = DrawDeck[0];//抽头一张,再把数据清空
// card.GetComponent<BattleCard>().playerID = _player;
// DrawDeck.RemoveAt(0);
//}
public void DrawCard(int _player,int _count)
{
List<Card> DrawDeck = new List<Card>();
Transform hand = transform;
if (_player == 0)
{
DrawDeck = playerDeckList;
hand = playerHand;
}
else if (_player == 1)
{
DrawDeck = enemyDeckList;
hand = enemyHand;
}
for(int i = 0;i< _count; i++)
{
GameObject card = Instantiate(cardPrefab, hand);
card.GetComponent<CardDisplay>().card = DrawDeck[0];//抽头一张,再把数据清空
card.GetComponent<BattleCard>().playerID = _player;
//加载成功
//Debug.Log("ID has loaded");
DrawDeck.RemoveAt(0);
}
}
public void OnClickNextRound()
{
TurnEnd();//正常游戏逻辑,但想实现的不一样
//if (gamePhase == GamePhase.playerAction)
//{
// gamePhase = GamePhase.playerDraw;
// phaseChangeEvent.Invoke();
//}
}
public void TurnEnd()
{
GameObject[] blocks;
GameObject _monster;
if (gamePhase == GamePhase.playerAction)
{
blocks = playerBlocks;
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)
{
_monster = block.GetComponent<Block>().card;
_monster.GetComponent<BattleCard>().ResetAttack();
}
}
gamePhase = GamePhase.enemyDraw;
phaseChangeEvent.Invoke();
}
else if(gamePhase == GamePhase.enemyAction)
{
blocks = enemyBlocks;
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)
{
_monster = block.GetComponent<Block>().card;
_monster.GetComponent<BattleCard>().ResetAttack();
}
}
gamePhase = GamePhase.playerDraw;
phaseChangeEvent.Invoke();
}
}//回合结束:游戏阶段
public void SummonRequst(int _player,GameObject _monster)//召唤请求,点击手牌时触发
{
GameObject[] blocks;
bool hasEmptyBlock = false;
if(_player == 0 && gamePhase == GamePhase.playerAction)
{
blocks = playerBlocks;
}
else if(_player == 1 && gamePhase == GamePhase.enemyAction)
{
blocks = enemyBlocks;
}
else
{
return;
}
if (SummonCounter[_player] > 0)
{
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card == null)//如果格子是空的
{
block.GetComponent<Block>().SummonBlock.SetActive(true);//等待召唤显示,即让格子高亮显示,或可增添其他.......
hasEmptyBlock = true;
}
}
}
if(hasEmptyBlock)
{
waitingMonster = _monster;
//Debug.Log("waitingMonster :" + waitingMonster.ToString());
waitingPlayer = _player;
CreateArrow(_monster.transform, ArrowPrefab);
}
}
public void SummonConfirm(Transform _block)
{
Summon(waitingPlayer, waitingMonster, _block);
CloseSummonBlocks();
DestroyArrow();
}
public void Summon(int _player,GameObject _monster,Transform _block)
{
_monster.transform.SetParent(_block);
_monster.transform.localPosition = Vector3.zero;
_monster.GetComponent<BattleCard>().state = BattleCardState.inBlock;
_block.GetComponent<Block>().card = _monster;
SummonCounter[_player]--;
MonsterCard mc = _monster.GetComponent<CardDisplay>().card as MonsterCard;
_monster.GetComponent<BattleCard>().AttackCount = mc.attackTime;//初始化召唤出来的怪兽的攻击次数
_monster.GetComponent<BattleCard>().ResetAttack(); //初始化攻击次数
}
public void AttackRequst(int _player, GameObject _monster)
{
GameObject[] blocks;
bool hasMonsterBlock = false;
if (_player == 0 && gamePhase == GamePhase.playerAction)
{
blocks = enemyBlocks;
}
else if (_player == 1 && gamePhase == GamePhase.enemyAction)
{
blocks = playerBlocks;
}
else
{
return;
}
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)//如果格子不是空的,即对方场地有可攻击的怪兽
{
block.GetComponent<Block>().AttackBlock.SetActive(true);//等待攻击显示,即让格子高亮显示,或可增添其他.......
block.GetComponent<Block>().card.GetComponent<AttackTarget>().attackable = true;
hasMonsterBlock = true;
}
}
if(hasMonsterBlock)
{
attackingMonster = _monster;
attackingPlayer = _player;
CreateArrow(_monster.transform,attackArrow);
}
}
public void AttackConfirm(GameObject _target)
{
Attack(attackingMonster, _target);
DestroyArrow();
CloseAttackBlocks();
GameObject[] blocks;
//关闭可攻击性
if (attackingPlayer == 0)
{
blocks = playerBlocks;
}
else
{
blocks = enemyBlocks;
}
foreach (var block in blocks)
{
if(block.GetComponent<Block>().card != null)
{
block.GetComponent<Block>().card.GetComponent<AttackTarget>().attackable = false;
}
}
}
public void Attack(GameObject _attacker, GameObject _target)
{
MonsterCard monster = _attacker.GetComponent<CardDisplay>().card as MonsterCard;
//-----------------------------------------------------------------------------------------------
string path = Application.dataPath + "/Datas/studentdata.csv";
List<string> datas = new List<string>();
datas.Add("#,编号,学生姓名,积分");
string[] lines = File.ReadAllLines(path);
for (int i = 1; i < lines.Length; i++) // 跳过标题行
{
string[] values = lines[i].Split(',');
if (int.Parse(values[1]) == monster.id) //是攻击的怪兽
{
int _value = int.Parse(values[3]);
_value += monster.attack;
datas.Add("monster," + values[1] + "," + values[2] + "," + _value.ToString());
}
else
{
datas.Add("monster," + values[1] + "," + values[2] + "," + values[3]);
}
}
File.WriteAllLines(path, datas);
#if UNITY_EDITOR
UnityEditor.AssetDatabase.Refresh();
#endif
//-----------------------------------------------------------------------------------------------
_target.GetComponent<AttackTarget>().ApplyDamage(monster.attack);
_attacker.GetComponent<BattleCard>().CostAttackCount();
_target.GetComponent<CardDisplay>().ShowCard();//刷新怪兽属性
}
public void EffectRequst(int _player, GameObject _spell)
{
GameObject[] blocks;
bool hasMonsterBlock = false;
if (_player == 0 && gamePhase == GamePhase.playerAction)
{
blocks = playerBlocks;
}
else if (_player == 1 && gamePhase == GamePhase.enemyAction)
{
blocks = enemyBlocks;
}
else
{
return;
}
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)//如果格子不是空的,即我方场地有可以获得增幅魔法卡的怪兽
{
block.GetComponent<Block>().AttackBlock.SetActive(true);//等待效果显示
block.GetComponent<Block>().card.GetComponent<AttackTarget>().effectable = true;
hasMonsterBlock = true;
}
}
if (hasMonsterBlock)
{
effectingSpell = _spell;
effectingPlayer = _player;
CreateArrow(_spell.transform, attackArrow);//先借用攻击箭头,懒得做新的
}
}
public void EffectConfirm(GameObject _target)
{
Effect(effectingSpell, _target);
DestroyArrow();
CloseAttackBlocks();
GameObject[] blocks;
if (effectingPlayer == 0)
{
blocks = playerBlocks;
}
else
{
blocks = enemyBlocks;
}
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)
{
block.GetComponent<Block>().card.GetComponent<AttackTarget>().effectable = false;
}
}
}
public void Effect(GameObject _speller, GameObject _target)
{
SpellCard speller = _speller.GetComponent<CardDisplay>().card as SpellCard;
_target.GetComponent<AttackTarget>().IncreaseDamage(_speller);//选中的目标增加效果值
//Destroy(_speller);//销毁魔法卡
_target.GetComponent<CardDisplay>().ShowCard();//刷新怪兽属性
}
public void CreateArrow(Transform _startPoint, GameObject _Prefab)
{
DestroyArrow();
arrow = GameObject.Instantiate(_Prefab, _startPoint);
arrow.GetComponent<Arrow>().SetStartPoint(new Vector2(_startPoint.position.x, _startPoint.position.y));
arrow.transform.SetParent(canvas.transform, false);
}
public void DestroyArrow()
{
Destroy(arrow);
}
public void CloseSummonBlocks()
{
GameObject[] blocks;
if (waitingPlayer == 0)
{
blocks = playerBlocks;
}
else
{
blocks = enemyBlocks;
}
foreach (var block in blocks)
{
block.GetComponent<Block>().SummonBlock.SetActive(false);//关闭召唤显示,及时关闭保证卡牌在召唤之后不能移动到其他格子
}
}
public void CloseAttackBlocks()
{
GameObject[] blocks;
blocks = playerBlocks;
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)
{
block.GetComponent<Block>().AttackBlock.SetActive(false);//关闭攻击显示
block.GetComponent<Block>().card.GetComponent<AttackTarget>().attackable = false;
}
}
blocks = enemyBlocks;
foreach (var block in blocks)
{
if (block.GetComponent<Block>().card != null)
{
block.GetComponent<Block>().AttackBlock.SetActive(false);//关闭攻击显示
block.GetComponent<Block>().card.GetComponent<AttackTarget>().attackable = false;
}
}
//if (attackingPlayer == 1)
//{
// blocks = playerBlocks;
//}
//else
//{
// blocks = enemyBlocks;
//}
//foreach (var block in blocks)
//{
// if (block.GetComponent<Block>().card != null)
// {
// block.GetComponent<Block>().AttackBlock.SetActive(false);//关闭攻击显示
// block.GetComponent<Block>().card.GetComponent<AttackTarget>().attackable = false;
// }
//}
}
}