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.

752 lines
27 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 TMPro;
using UnityEngine.Playables;
// !!读写存档
using UnityEngine.SceneManagement;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using LitJson;
using System;
//控制选中取消角色与角色的移动
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public GameObject menuUI; // 调出菜单
public float speed = 3.0f; // 镜头移动速度
public Character selected; // 记录选中的棋子
bool menuActive = false; // 是否显示菜单
bool exploreMode = false; // true时为探索模式false时为战斗模式
public TMP_Text cellCost; // 显示鼠标所在单元格消耗行动力
public TMP_Text cellDamage; // 显示鼠标所在单元格造成的伤害
public TMP_Text characterHealth; // 显示鼠标所在角色当前生命值
public TMP_Text characterPoise; // 显示鼠标所在角色当前韧性值
public GameObject[] pieces; // 记录所有的棋子
public int[] groupCount; // 记录敌我双方棋子数量groupCount[0]为友方groupCount[1]为敌方
public int currentGroup = 0; // 当前的回合是哪一方的,0是友军,1是敌方
float horizontal; // 移动镜头
float vertical; // 移动镜头
public GameObject turnObject; // 回合UI
public GameObject turnText;
public TMP_Text DEX;
public TMP_Text SAN;
public TMP_Text VIG;
public TMP_Text DEF;
public TMP_Text STR;
public TMP_Text INT;
public TMP_Text CurrentHealth;
public TMP_Text MaxHealth;
public TMP_Text CurrentPoise;
public TMP_Text MaxPoise;
public TMP_Text CurrentMana;
public TMP_Text MaxMana;
public GameObject detailInformation;
int enemyNumber; // 关卡中敌人总数
Character maincharacter; // 记录主角
public GameObject myBag; // 背包
bool isOpen; // 背包是否打开
public GameObject gameSettlement; // 结算界面
bool settlementFlag; // 是否需要结算界面
// 加点界面
public GameObject strAdd;
public GameObject dexAdd;
public GameObject sanAdd;
public GameObject inteAdd;
public GameObject defAdd;
public GameObject vigAdd;
public TMP_Text IsUsingSkill;
// 背包
public Inventory myInventory;
//控制摄像机移动范围
Rigidbody2D rigidbody2d;
//过场动画
public enum GameMode
{
Normal,
GamePlay,
DialogueMovement
}
public GameMode gameMode;
private PlayableDirector playableDirector;
void Start()
{
SearchPieces();
SetCount();
SetExploreMode();
rigidbody2d = GetComponent<Rigidbody2D>();
if (GetExploreMode())
{
settlementFlag = false; // 初始状态中无敌人时不需要结算界面
enemyNumber = 0; // 初始状态敌人数量为0
}
else
{
settlementFlag = true; // 初始状态中有敌人时需要结算界面
enemyNumber = groupCount[1]; // 记录初始状态关卡中敌人总数
}
if(UIManager.instance.openingStatus)
gameMode = GameMode.GamePlay;
else
FinishedCG();
}
private void Awake()
{
if(instance == null)
instance = this;
else if(instance != this)
Destroy(gameObject);
//DontDestroyOnLoad(gameObject);
}
public void FinishedCG()
{
gameMode = GameMode.Normal;
RefreshCharacterUIs();
if(selected != null)
selected.Cancel();
}
public void ResumeTimeline()
{
gameMode = GameMode.GamePlay;
playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(1d);
//Debug.Log(UIManager.instance.name);
UIManager.instance.ToggleSpaceBar(false);
UIManager.instance.ToggleDialogueBox(false);
}
public void PauseTimeline(PlayableDirector director)
{
//Debug.Log(UIManager.instance.name);
playableDirector = director;
gameMode = GameMode.DialogueMovement;
playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(0d);
UIManager.instance.ToggleSpaceBar(true);
}
void Update()
{
if(gameMode == GameMode.DialogueMovement)
{
if(Input.GetKeyDown("space"))
{
ResumeTimeline();
}
}
if(!menuActive)
{
if(GameManager.instance.gameMode == GameMode.Normal)
{
CheckIsUsingSkill();
ShowSettlement();
ShowTurn(); // 不显示菜单时先判断是否显示敌我回合
ShowBag(); // 不显示菜单时可以打开背包
// 选中角色时,镜头移动到角色上,方向键控制角色走动
if (selected != null)
{
// 取消选择
if(Input.GetMouseButtonDown(1))
{
selected.Cancel();
return;
}
MoveCharacter();
// 选中角色在lookDirection方向上与NPC对话
if (exploreMode && Input.GetKeyDown(KeyCode.F))
selected.Dialogue();
// 选中角色在lookDirection方向上进入下一场景
if (exploreMode && selected == maincharacter)
selected.EnterNextScene();
// 选中角色时按f捡起物品
if (Input.GetKeyDown("f"))
selected.Pickup();
if(!exploreMode)
{
// 选中角色时可切换武器
if(Input.GetKeyDown("c"))
selected.GetNextWeapon();
if(Input.GetKeyDown("e"))
selected.weaponManager.SetWeaponsGUI();
if(Input.GetKeyDown("z"))
{
selected.skillManager.SetSkillsGUI();
bool value = !selected.skillManager.GetGameObjectValue();
//selected.weaponManager.gameObject.SetActive(value);
}
if(Input.GetKeyDown("x") && !selected.GetIsUsingSkill())
{
selected.Attack();
}
}
}
}
}
CallMenu();
}
private void FixedUpdate()
{
if(!menuActive && selected == null)
MoveCamera(); //未选中角色时,方向键控制镜头移动
}
// 移动镜头
void MoveCamera()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
Vector2 position = rigidbody2d.position;
position.x += speed*horizontal*Time.deltaTime;
position.y += speed*vertical*Time.deltaTime;
rigidbody2d.MovePosition(position);
}
// 检测当前是在使用技能还是武器
void CheckIsUsingSkill()
{
if(selected == null)
{
IsUsingSkill.text = "---";
return;
}
if(selected.GetIsUsingSkill())
IsUsingSkill.text = "技能";
else
IsUsingSkill.text = "武器";
}
// 移动角色
void MoveCharacter()
{
transform.position = selected.transform.position;
// 角色走动
if(Input.GetKeyDown("up"))
{
StartCoroutine(selected.Move(Vector2.up));
}
if(Input.GetKeyDown("down"))
{
StartCoroutine(selected.Move(Vector2.down));
}
if(Input.GetKeyDown("left"))
{
StartCoroutine(selected.Move(Vector2.left));
}
if(Input.GetKeyDown("right"))
{
StartCoroutine(selected.Move(Vector2.right));
}
// 角色转向
if(Input.GetKeyDown("w"))
{
selected.Turn(Vector2.up);
}
if(Input.GetKeyDown("s"))
{
selected.Turn(Vector2.down);
}
if(Input.GetKeyDown("a"))
{
selected.Turn(Vector2.left);
}
if(Input.GetKeyDown("d"))
{
selected.Turn(Vector2.right);
}
}
// 呼出菜单
void CallMenu()
{
if(Input.GetKeyDown("escape"))
{
menuActive = !menuActive;
menuUI.SetActive(menuActive);
}
}
// 改变选中的棋子
public void SetSelected(Character character)
{
selected = character;
}
// 返回选中的棋子
public Character GetSelected()
{
return selected;
}
// 回合结束
public void TurnEnd()
{
//if(exploreMode) return;
if(selected != null)
selected.Cancel();
//int count = 0;
if(currentGroup == 0)
StartCoroutine(ApplyAIInTurn());
}
IEnumerator ApplyAIInTurn()
{
currentGroup = 1;
// AI行动
foreach (var piece in pieces)
{
AI character = piece.GetComponent<AI>();
if(piece.GetComponent<Character>().groupNumber == currentGroup)
{
character.ReSet();
character.buffManager.TurnEnd();
//Debug.Log("Start Time : " + Time.time);
yield return StartCoroutine(character.ApplyAI());
//Debug.Log("End Time : " + Time.time);
}
//Debug.Log("count = " + count);
}
// 轮换至我方回合
currentGroup = 0;
foreach (var piece in pieces)
{
if(piece.GetComponent<Character>().groupNumber == currentGroup)
{
piece.GetComponent<Character>().ReSet();
piece.GetComponent<Character>().buffManager.TurnEnd();
}
}
yield return null;
}
// 搜寻棋子
public void SearchPieces()
{
pieces = GameObject.FindGameObjectsWithTag("Pieces");
foreach (var piece in pieces)
{
if(piece.GetComponent<Character>().id == 0)
{
maincharacter = piece.GetComponent<Character>();
break;
}
}
}
// 数敌我双方棋子数
void SetCount()
{
groupCount = new int[3];
foreach (var piece in pieces)
{
Character character = piece.GetComponent<Character>();
groupCount[character.groupNumber] ++ ;
//Debug.Log("gruopCount[" + character.groupNumber + "] = " + groupCount[character.groupNumber]);
}
}
public bool GetExploreMode()
{
return exploreMode;
}
// 当敌人数量为0时状态切换为探索模式
public void SetExploreMode()
{
if(groupCount[1] == 0)
{
if(selected != null)
selected.Cancel();
exploreMode = true;
//Debug.Log("exploreMode");
currentGroup = 0;
foreach (var piece in pieces)
{
piece.GetComponent<Character>().buffManager.RemoveAllBuffs();
piece.GetComponent<Character>().ReSet();
}
}
}
// 战斗结算
void MakeSettlement()
{
for (int i = 0; i < enemyNumber; i++)
{
maincharacter.money += 10;
maincharacter.exp += 10;
while (maincharacter.exp >= maincharacter.levelUp[maincharacter.level - 1])
{
maincharacter.exp -= maincharacter.levelUp[maincharacter.level - 1];
maincharacter.level++;
maincharacter.points += 5;
}
}
}
// 显示结算界面
void ShowSettlement()
{
if (settlementFlag) // 初始状态有敌人才需要结算
{
if (exploreMode) // 战斗模式结束时显示结算界面
{
MakeSettlement(); // 击杀所有敌人后获得经验和金钱
gameSettlement.SetActive(true);
// 是否显示加点系统
if(maincharacter.points > 0)
{
strAdd.SetActive(true);
dexAdd.SetActive(true);
sanAdd.SetActive(true);
inteAdd.SetActive(true);
defAdd.SetActive(true);
vigAdd.SetActive(true);
}
settlementFlag = false; // 此场景中不再需要结算界面
}
}
}
void ShowTurn() // 显示战斗UI
{
if (exploreMode)
turnObject.SetActive(false);
else
{
if (currentGroup != 0)
turnText.GetComponent<TMP_Text>().text = "敌方回合";
else
turnText.GetComponent<TMP_Text>().text = "我方回合";
turnObject.SetActive(true);
}
}
void ShowBag() // 是否显示背包
{
isOpen = myBag.activeSelf; // 防止鼠标点击退出背包后按两次I才能再次打开
if(Input.GetKeyDown("i")) // 按I键打开背包
{
isOpen = !isOpen;
myBag.SetActive(isOpen);
InventoryManager.RefreshItem();
}
}
public void ChangeCellInformation(int x, int y)
{
cellCost.text = x.ToString();
cellDamage.text = y.ToString();
}
public void ChangeCharaterInformation(int x, int y)
{
characterHealth.text = x.ToString();
characterPoise.text = y.ToString();
}
public void CheckDetailInformation(int str,int inte, int dex, int san,int vig, int def, int currentHealth,
int maxHealth, int currentPoise, int maxPoise, int currentMana, int maxMana)
{
STR.text = str.ToString();
INT.text = inte.ToString();
DEX.text = dex.ToString();
SAN.text = san.ToString();
VIG.text = vig.ToString();
DEF.text = def.ToString();
CurrentHealth.text = currentHealth.ToString();
MaxHealth.text = maxHealth.ToString();
CurrentPoise.text = currentPoise.ToString();
MaxPoise.text = maxPoise.ToString();
CurrentMana.text = currentMana.ToString();
MaxMana.text = maxMana.ToString();
detailInformation.SetActive(true);
//Debug.Log("!!");
}
public void RefreshCharacterUIs()
{
foreach(var piece in pieces)
{
Character character = piece.GetComponent<Character>();
character.RefreshAllPointsBars();
}
}
// 保存数据
private Save CreateSaveGameObject()
{
Save save = new Save();
// 保存当前场景号
save.curSceneNumber = SceneManager.GetActiveScene().buildIndex;
// 保存每个棋子
foreach(GameObject piece in pieces)
{
if(piece != null)
{
Character character = piece.GetComponent<Character>();
// 保存棋子的信息
save.characterId.Add(character.id);
save.characterGroupNumber.Add(character.groupNumber);
save.characterHealth.Add(character.GetCurrentHealth());
save.characterMana.Add(character.GetCurrentMana());
save.characterMovement.Add(character.GetCurrentMovement());
save.characterLevel.Add(character.level);
save.characterPoint.Add(character.points);
save.characterMoney.Add(character.money);
save.characterExp.Add(character.exp);
save.characterStr.Add(character.str);
save.characterDex.Add(character.dex);
save.characterSan.Add(character.san);
save.characterInte.Add(character.inte);
save.characterDef.Add(character.def);
save.characterVig.Add(character.vig);
// 保存棋子所拥有武器的信息
save.weaponMax.Add(character.weaponManager.maximum);
for(int i = 0; i < character.weaponManager.maximum; i++)
{
Weapon weapon = character.weaponManager.weapons[i];
if(weapon.name == "knife")
save.weaponType.Add(0);
if(weapon.name == "sword")
save.weaponType.Add(1);
if(weapon.name == "greatsword")
save.weaponType.Add(2);
if(weapon.name == "lance")
save.weaponType.Add(3);
save.weaponLevel.Add(weapon.level);
}
// 保存棋子的位置
save.positionsX.Add(Convert.ToInt32(piece.transform.position[0]));
save.positionsY.Add(Convert.ToInt32(piece.transform.position[1]));
}
}
// 保存地图上的物品
GameObject[] items;
items = GameObject.FindGameObjectsWithTag("Item");
foreach(GameObject item in items)
{
if(item.name == "Crystal")
save.itemType.Add(0);
if(item.name == "Health")
save.itemType.Add(1);
if(item.name == "Mana")
save.itemType.Add(2);
}
// 保存是否需要进行结算
save.settlement = settlementFlag;
return save;
}
// IEnumerator LoadScene(Save save)
// {
// SceneManager.LoadScene(save.curSceneNumber);
// yield return null;
// }
// private IEnumerator SetGame(Save save)
private void SetGame(Save save)
{
// 读取场景
// yield return StartCoroutine(LoadScene(save));
// yield return null;
// SceneManager.LoadScene(save.curSceneNumber);
GameObject[] pieces_;
pieces_ = GameObject.FindGameObjectsWithTag("Pieces");
// 读取每个棋子
foreach(GameObject piece in pieces_)
{
int temp = 0; // 储存读取save.weapons与save.weaponLevel列表的下表
bool flag = false; // 判断棋子是否还存在
Character character = piece.GetComponent<Character>();
for(int i = 0; i < save.characterId.Count; i++)
{
if(character.id == save.characterId[i] && character.groupNumber == save.characterGroupNumber[i])
{
// 读取棋子的信息
character.ChangeHealth(save.characterHealth[i] - character.GetMaxHealth());
character.ChangeMana(save.characterMana[i]);
character.ChangeMovement(save.characterMovement[i] - character.GetMaxMovement());
character.level = save.characterLevel[i];
character.points = save.characterPoint[i];
character.money = save.characterMoney[i];
character.exp = save.characterExp[i];
character.str = save.characterStr[i];
character.dex = save.characterDex[i];
character.san = save.characterSan[i];
character.inte = save.characterInte[i];
character.def = save.characterDef[i];
character.vig = save.characterVig[i];
// 读取棋子所拥有武器的信息
character.weaponManager.maximum = save.weaponMax[i];
character.weaponManager.weapons = new Weapon[9];
for(int j = 0; j < character.weaponManager.maximum; j++)
{
if(save.weaponType[temp] == 0)
{
character.weaponManager.transform.Find("knife").GetComponent<Weapon>().valid = true;
character.weaponManager.weapons[j] = character.weaponManager.transform.Find("knife").GetComponent<Weapon>();
}
if(save.weaponType[temp] == 1)
{
character.weaponManager.transform.Find("sword").GetComponent<Weapon>().valid = true;
character.weaponManager.weapons[j] = character.weaponManager.transform.Find("sword").GetComponent<Weapon>();
}
if(save.weaponType[temp] == 2)
{
character.weaponManager.transform.Find("greatsword").GetComponent<Weapon>().valid = true;
character.weaponManager.weapons[j] = character.weaponManager.transform.Find("greatsword").GetComponent<Weapon>();
}
if(save.weaponType[temp] == 3)
{
character.weaponManager.transform.Find("lance").GetComponent<Weapon>().valid = true;
character.weaponManager.weapons[j] = character.weaponManager.transform.Find("lance").GetComponent<Weapon>();
}
character.weaponManager.weapons[j].level = save.weaponLevel[temp];
temp++;
}
// 读取棋子的位置
RaycastHit2D hit = Physics2D.Raycast(piece.transform.position, Vector2.up, 1.0f, LayerMask.GetMask("Cells"));
hit.collider.GetComponent<Cell>().SetOccupied(false);
hit.collider.GetComponent<Cell>().SetCurrentCharacter(null);
piece.transform.position = new Vector2(save.positionsX[i], save.positionsY[i]);
hit = Physics2D.Raycast(piece.transform.position, Vector2.up, 1.0f, LayerMask.GetMask("Cells"));
hit.collider.GetComponent<Cell>().SetOccupied(true);
hit.collider.GetComponent<Cell>().SetCurrentCharacter(character);
flag = true;
}
else
{
temp += save.weaponMax[i];
}
}
// 若不存在则将血量置为0
if(!flag)
character.ChangeHealth(0- character.GetMaxHealth());
}
// 读取地图上的物品
GameObject[] items;
items = GameObject.FindGameObjectsWithTag("Item");
foreach(GameObject item in items)
{
bool flag = false; // 判断物品是否还存在
for(int i = 0; i < save.itemType.Count; i++)
{
if(item.name == "Crystal" && save.itemType[i] == 0)
flag = true;
if(item.name == "Health" && save.itemType[i] == 1)
flag = true;
if(item.name == "Mana" && save.itemType[i] == 2)
flag = true;
}
// 若不存在则摧毁物品
if(!flag)
{
RaycastHit2D hit = Physics2D.Raycast(item.transform.position, Vector2.up, 1.0f, LayerMask.GetMask("Cells"));
hit.collider.GetComponent<Cell>().SetOccupied(false);
Destroy(item);
}
}
// 读取是否需要进行结算
settlementFlag = save.settlement;
}
// Json方法存档
private void SaveByJson()
{
if(!Directory.Exists(Application.dataPath + "/StreamingFile"))
Directory.CreateDirectory(Application.dataPath + "/StreamingFile");
// 存储角色、武器和地图数据
Save save = CreateSaveGameObject();
string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
string saveJsonStr = JsonMapper.ToJson(save);
StreamWriter sw = new StreamWriter(filePath);
sw.Write(saveJsonStr);
sw.Close();
// 存储背包数据
filePath = Application.dataPath + "/StreamingFile" + "/MyInventory.txt";
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(filePath);
var saveJsonVar = JsonUtility.ToJson(myInventory);
bf.Serialize(file, saveJsonVar);
file.Close();
Debug.Log("保存成功");
}
// Json方法读档
private void LoadByJson()
{
// 检测文件路径
if(!Directory.Exists(Application.dataPath + "/StreamingFile"))
{
Debug.Log("文件路径不存在");
return;
}
// 读取角色、武器和地图数据
string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
if(File.Exists(filePath))
{
StreamReader sr = new StreamReader(filePath);
string jsonStr = sr.ReadToEnd();
sr.Close();
Save save = JsonMapper.ToObject<Save>(jsonStr);
// StartCoroutine(SetGame(save));
SetGame(save);
}
else
Debug.Log("文件不存在");
// 读取背包数据
filePath = Application.dataPath + "/StreamingFile" + "/MyInventory.txt";
BinaryFormatter bf = new BinaryFormatter();
if(File.Exists(filePath))
{
FileStream file = File.Open(filePath, FileMode.Open);
JsonUtility.FromJsonOverwrite((string)bf.Deserialize(file), myInventory);
file.Close();
Debug.Log("读档成功");
}
else
Debug.Log("文件不存在");
}
// 保存游戏
public void SaveGame()
{
SaveByJson();
}
// 加载游戏
public void LoadGame()
{
LoadByJson();
}
}