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.

541 lines
19 KiB

using System.Net.Mime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Character : MonoBehaviour
{
public bool isUsingSkill = false;
// 角色等级
public int level = 1;
// 角色可使用加点数
public int points = 0;
// 角色持有金币
public int money = 0;
// 角色经验
public int exp = 0;
// 角色升级所需经验
public int[] levelUp = {20, 50, 100};
// 角色ID设置为public类型以便查找
public int id = 0;
//角色阵营序列号
public int groupNumber;
//角色可加点属性
public int str = 5;
public int dex = 5;
public int san = 5;
public int inte = 5;
public int def = 5;
public int vig = 5;
//角色衍生属性
protected int maxHealth;
protected int maxPoise;
protected int maxMovement ;
protected int maxMana;
protected int currentHealth;
public int currentMovement;
protected int currentPoise;
protected int currentMana;
//角色Buff属性
protected bool execute = false;
protected float attackCofficient = 1;
protected float defenceCofficient = 1;
protected int moveCofficient = 0;
//调用其他类
public WeaponManager weaponManager;
public BuffManager buffManager;
public SkillManager skillManager;
CharacterUIManager characterUIManager;
protected MovementBar movementBar;
protected GameObject currentWeaponObject;
Weapon currentWeapon;
//protected GameManager GameManager.instance;
protected Animator animator;
Vector2 lookDirection = Vector2.down;
public GameObject enterDialog; // 切换场景的对话框
bool isMoving = false;
public GameObject gameoverMenu; // 游戏结束
// 初始化
void Start()
{
animator = GetComponent<Animator>();
GameManager.instance = GameObject.Find("GameManager").GetComponent<GameManager>();
// //初始化角色战斗属性
// maxMovement = (int)(dex * 2 + san * 2 + 8 + level * 0.5);
// maxHealth = 10 + vig * 10 + level * 2;
// maxPoise = (int)(str * 2 + vig * 0.5 + 5);
// maxMana = (int)(inte * 2 + san * 1);
// currentMovement = maxMovement;
// currentHealth = maxHealth;
// currentPoise = maxPoise;
// currentMana = 0;
// 初始化角色位置
RaycastHit2D hit = Physics2D.Raycast(transform.position,Vector2.up,1.0f,LayerMask.GetMask("Cells"));
hit.collider.GetComponent<Cell>().SetOccupied(true);
hit.collider.GetComponent<Cell>().SetCurrentCharacter(this);
}
private void Awake()
{
// 初始化角色战斗属性
maxMovement = (int)(dex * 2 + san * 2 + 8 + level * 0.5);
maxHealth = 10 + vig * 10 + level * 2;
maxPoise = (int)(str * 2 + vig * 0.5 + 5);
maxMana = (int)(inte * 2 + san * 1);
currentMovement = maxMovement;
currentHealth = maxHealth;
currentPoise = maxPoise;
currentMana = 0;
// 初始化角色武器
weaponManager = transform.GetChild(0).GetComponent<WeaponManager>();
// 初始化角色UI
characterUIManager = transform.GetChild(1).GetComponent<CharacterUIManager>();
movementBar = transform.GetChild(1).GetChild(2).GetComponent<MovementBar>();
}
protected virtual void OnMouseOver()
{
if(GameManager.instance.gameMode == GameManager.GameMode.Normal)
{
// 鼠标左键点击选中角色
if(Input.GetMouseButton(0)) Selected();
// 鼠标右键点击查看角色信息
if(Input.GetMouseButton(1) && GameManager.instance.GetSelected() == null)
{
GameManager.instance.CheckDetailInformation(str,inte,dex,san,vig,def,
currentHealth,maxHealth,currentPoise,maxPoise,currentMana,maxMana);
}
}
}
// 选中角色
public virtual void Selected()
{
if(GameManager.instance.selected != null) return;
if(GameManager.instance.currentGroup != groupNumber)
return;
animator.SetFloat("selected", 1);
GameManager.instance.SetSelected(gameObject.GetComponent<Character>());
if(!GameManager.instance.GetExploreMode())
{
weaponManager.SetCurrnetWeaponActive(true);
movementBar.SetMovementActive(true);
}
}
public void AnimatorMoving(bool value)
{
if(value)
{
animator.SetFloat("selected", 1);
if(id == 0)
GameManager.instance.transform.position = transform.position;
}
else
animator.SetFloat("selected", 0);
}
// 取消选中角色
public virtual void Cancel()
{
animator.SetFloat("selected", 0);
GameManager.instance.SetSelected(null);
weaponManager.SetCurrnetWeaponActive(false);
if(!GameManager.instance.GetExploreMode())
movementBar.SetMovementActive(false);
}
// 移动角色
public IEnumerator Move(Vector2 deviation,float time = 0.01f)
{
// 角色朝向
Turn(deviation);
// 判断角色是否能够前进
isMoving = true;
Vector2 temp = new Vector2(deviation.x + transform.position.x, deviation.y + transform.position.y);
RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position,deviation,1.0f,LayerMask.GetMask("Cells"));
if(hits.Length <= 1)
{
Debug.Log("Not Accessed");
}
else
{
Cell currentCell = hits[0].collider.GetComponent<Cell>();
Cell cell = hits[1].collider.GetComponent<Cell>();
if(cell.GetOccupied()) Debug.Log("Not Accessed");
else if(temp.x == cell.transform.position.x && temp.y == cell.transform.position.y)
{
// 判断行动点数是否够用
if(currentMovement >= (cell.cost - moveCofficient))
{
if(!GameManager.instance.GetExploreMode())
ChangeMovement(-(cell.cost - moveCofficient));
// 改变棋子所占用的单元格
yield return MovePosition(cell.transform.position, time);
transform.position = cell.transform.position;
currentCell.SetOccupied(false);
currentCell.SetCurrentCharacter(null);
cell.SetCurrentCharacter(this);
cell.SetOccupied(true);
// 陷阱地形对角色造成伤害
if(cell.damage > 0)
ChangeHealth(-cell.damage);
}
else
{
OutOfMovement();
}
}
}
isMoving = false;
}
public void Move(int order)
{
if(order == 1) StartCoroutine(Move(Vector2.up));
if(order == 2) StartCoroutine(Move(Vector2.down));
if(order == 3) StartCoroutine(Move(Vector2.left));
if(order == 4) StartCoroutine(Move(Vector2.right));
}
IEnumerator MovePosition(Vector2 position, float time)
{
float deltaX = (transform.position.x - position.x)/30;
float deltaY = (transform.position.y - position.y)/30;
for(int i = 0; i < 30; i++)
{
transform.position = new Vector2(transform.position.x - deltaX, transform.position.y - deltaY);
yield return new WaitForSeconds(time/60f);
}
}
public void ForceMove(Vector2 deviation)
{
Vector2 temp = new Vector2(deviation.x + transform.position.x, deviation.y + transform.position.y);
RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position,deviation,1.0f,LayerMask.GetMask("Cells"));
Cell currentCell = hits[0].collider.GetComponent<Cell>();
Cell cell = hits[1].collider.GetComponent<Cell>();
if(cell.GetOccupied()) Debug.Log("Not Accessed");
else if(temp.x == cell.transform.position.x && temp.y == cell.transform.position.y)
{
if(!GameManager.instance.GetExploreMode())
ChangeMovement(-(cell.cost + moveCofficient));
// 改变棋子所占用的单元格
transform.position = cell.transform.position;
currentCell.SetOccupied(false);
currentCell.SetCurrentCharacter(null);
cell.SetCurrentCharacter(this);
cell.SetOccupied(true);
// 陷阱地形对角色造成伤害
if(cell.damage > 0)
ChangeHealth(-cell.damage);
}
}
// 调节生命值,在血量减少或回复时调用
public void ChangeHealth(int amount)
{
currentHealth = Mathf.Clamp(currentHealth + amount, 0 ,maxHealth);
characterUIManager.ChangePoints(amount,currentHealth / (float)maxHealth, 0); //生命值改变后血条显示改变
if(currentHealth == 0)
// 若主角死亡则游戏结束
{
DestoryPiece();
if(id == 0 && groupNumber == 0)
{
gameoverMenu.SetActive(true);
}
}
}
// 调节韧性点数
public void ChangePoise(int amount)
{
currentPoise = Mathf.Clamp(currentPoise + amount, 0 ,maxPoise);
characterUIManager.ChangePoints(amount,currentPoise / (float)maxPoise, 1); //韧性值改变后韧性条显示改变
}
// 调节行动点数
public void ChangeMovement(int amount)
{
currentMovement += amount;
movementBar.ChangeMovement(amount,currentMovement,currentMovement / (float)maxMovement);
}
// 蓝条
public void ChangeMana(int amount)
{
currentMana = Mathf.Clamp(currentMana + amount, 0, maxMana);
//Debug.Log(currentMana);
characterUIManager.ChangePoints(amount, currentMana/ (float)maxMana, 2);
}
// 结束回合时重制角色行动点数
public void ReSet()
{
if(currentPoise <= 0)
{
currentPoise = maxPoise;
characterUIManager.ChangePoints(0, 1, 1);
currentMovement = (int)(maxMovement * 0.5);
}
else
currentMovement = maxMovement;
ChangeMovement(0);
}
// 获取角色状态
public int GetLevel()
{
return level;
}
public int GetCurrentMovement()
{
return currentMovement;
}
public int GetCurrentHealth()
{
return currentHealth;
}
public int GetCurrentPoise()
{
return currentPoise;
}
public int GetCurrentMana()
{
return currentMana;
}
public int GetMaxHealth()
{
return maxHealth;
}
public int GetMaxPoise()
{
return maxPoise;
}
public int GetMaxMana()
{
return maxMana;
}
public int GetMaxMovement()
{
return maxMovement;
}
// 角色转向
public void Turn(Vector2 direction)
{
if(isMoving) return;
lookDirection = direction;
weaponManager.weapons[weaponManager.currentIndex].SetRotation(direction);
//Debug.Log(skillManager.currentSkill);
if(skillManager.currentSkill != null)
{
skillManager.currentSkill.SetRotation(direction);
}
animator.SetFloat("lookX", direction.x);
animator.SetFloat("lookY", direction.y);
}
public void Turn(int order)
{
if(order == 1) Turn(Vector2.up);
if(order == 2) Turn(Vector2.down);
if(order == 3) Turn(Vector2.left);
if(order == 4) Turn(Vector2.right);
}
public void Dialogue()
{
Vector2 position = new Vector2(transform.position.x, transform.position.y); // ** 以Vector2形式保存当前位置 // **
RaycastHit2D hit = Physics2D.Raycast(position + Vector2.up * 0.2f,
lookDirection, 1.5f,LayerMask.GetMask("NPC")); // ** 判断是否接触NPC
if (hit.collider != null) // **
{ // **
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>(); // **
if (character != null) // **
{ // **
character.DisplayDialog(); // **
} // ** // **
} // **
}
// 显示行动点不足 // **
public void OutOfMovement()
{
characterUIManager.OutOfMovement();
}
// 切换武器
public void GetNextWeapon()
{
weaponManager.weapons[weaponManager.currentIndex].gameObject.SetActive(false);
weaponManager.currentIndex += 1;
weaponManager.currentIndex %= weaponManager.maximum;
weaponManager.weapons[weaponManager.currentIndex].gameObject.SetActive(true);
weaponManager.weapons[weaponManager.currentIndex].SetRotation(lookDirection);
}
public void DestoryPiece()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position,Vector2.up,1.0f,LayerMask.GetMask("Cells"));
hit.collider.GetComponent<Cell>().SetOccupied(false);
Destroy(gameObject);
}
private void OnDestroy()
{
GameManager.instance.SearchPieces();
GameManager.instance.groupCount[groupNumber] -= 1;
GameManager.instance.SetExploreMode();
}
public Vector2 GetLookDirection()
{
return lookDirection;
}
// 捡起物品
public void Pickup()
{
Vector2 position = new Vector2(transform.position.x, transform.position.y); // 以Vector2形式保存当前位置 // **
RaycastHit2D hit = Physics2D.Raycast(position + Vector2.up * 0.2f,
lookDirection, 1.5f, LayerMask.GetMask("Item")); // 判断是否接触物品
if (hit.collider != null)
{
ItemInMap item = hit.collider.GetComponent<ItemInMap>();
if (item != null)
{
item.AddNewItem();
}
}
}
// 进入下一场景
public void EnterNextScene()
{
Vector2 position = new Vector2(transform.position.x, transform.position.y); // 以Vector2形式保存当前位置 // **
RaycastHit2D hit = Physics2D.Raycast(position + Vector2.up * 0.2f,
lookDirection, 0.2f, LayerMask.GetMask("Enter")); // 判断是否接触物品
if (hit.collider != null)
{
Cell enterCell = hit.collider.GetComponent<Cell>();
if (enterCell != null)
{
enterDialog.SetActive(true);
if (Input.GetKeyDown("f"))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
enterDialog.SetActive(false);
}
} // **
}
else
enterDialog.SetActive(false);
}
// Buff类函数
public void SetAttackCofficient(float amount)
{
attackCofficient += amount;
}
public float GetAttackCoffcient()
{
return attackCofficient;
}
public void SetDefenceCofficient(float amount)
{
defenceCofficient += amount;
}
public float GetDefenceCofficient()
{
return defenceCofficient;
}
public void SetMoveCofficient(int amount)
{
moveCofficient += amount;
}
public void SetExecute(bool value)
{
execute = value;
}
public bool GetExecute()
{
return execute;
}
// 攻击(调用武器)
public void Attack()
{
weaponManager.weapons[weaponManager.currentIndex].Attack();
}
private void OnMouseEnter()
{
GameManager.instance.ChangeCharaterInformation(currentHealth, currentPoise);
}
public void SetIsUsingSkill(bool value)
{
isUsingSkill = value;
}
public bool GetIsUsingSkill()
{
return isUsingSkill;
}
public void RefreshAllPointsBars()
{
characterUIManager.RefreshHMPPointsBars();
movementBar.RefreshMovementBar();
}
public void CharacterOccur()
{
gameObject.SetActive(true);
//AnimatorMoving(true);
StartCoroutine(SetTransparentizing(false));
}
public void CharacterDisappear()
{
StartCoroutine(SetTransparentizing(true));
}
IEnumerator SetTransparentizing(bool value)
{
Debug.Log("Start");
yield return StartCoroutine(ChangeAlpha(value));
if(value)
GetComponent<SpriteRenderer>().color = new Color(1,1,1,0);
else
GetComponent<SpriteRenderer>().color = new Color(1,1,1,1);
Debug.Log("Finished");
}
IEnumerator ChangeAlpha(bool value)
{
float alpha = 0;
float step = 1/50f;
if(value)
{
step = -1/50f;
alpha = 1;
}
for(int i = 0; i< 50 ; i++)
{
GetComponent<SpriteRenderer>().color = new Color(1,1,1,alpha);
alpha += step;
yield return new WaitForSeconds(0.02f);
}
}
}