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
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);
|
|
}
|
|
}
|
|
}
|