使用Unity3D編寫ARPG遊戲——角色屬性的定義與實現(二)
在上一篇部落格中,已經編寫了人物屬性編輯器的大部分,但是光有一些屬性的定義並沒有什麼卵用,我們還需要新增在角色受到傷害時,反映在人物屬性上的變化,或者狀態的變化。其實說到底,這部分也就是編寫兩個方法來接收值,改變值得概念罷了,並沒有什麼神奇之處。但是,在接收到值之前,值在兩個模組之間進行傳遞的方法則根據不同的設計模式而各有不同,在這篇部落格的內容,sunset也不打算對設計模式進行詳細深究先明白怎麼編寫基礎的函式方法,至於這個方面等以後再特別開一篇部落格仔細介紹,如果對“設計模式”這種東西有特別感情,特別想知道,sunset推薦一本書籍《C++設計模式》,作者是一名老外,名字叫什麼記不清了,可以參閱或者自行度娘。先宣告sunset在這裡使用的設計模式是單例模式,是比較常用也比較簡單易於理解的一種設計模式。
簡單的說,單例模式用法就是:A與B之間只知道對方的存在,但對於對方的資訊全然不知,兩者之間的互動關係僅僅通過第三方進行。也就是說,A不擁有B的資訊,B也不擁有A的資訊,資訊傳遞是通過第三方(Camera)進行的。嗯,先進性簡單大概的瞭解,詳細以後再說。
迴歸正題,先編寫一個角色接收普通傷害的方法,直接給程式碼吧:
public void HeroGetDamage(float Damage)
{
if (CurStatus.CurAgility < EnemyPower)
{
Hit = 100.0f;
}
else if (CurStatus.CurAgility > EnemyPower)
{
Hit = 40;
}
else if (CurStatus.CurAgility == EnemyPower)
{
Hit = 80.0f ;
}
if (Random.Range(0.0f, 100.0f) <= Hit)//決定是否閃避
{
if (CurStatus.CurDefend > EnemyAttack)//根據敵人攻擊力和自己防禦力決定普通傷害
{
Damage = Damage * 0.75f;
}
CurStatus.CurHP -= Damage;
}
}
解釋一下,sunset在編寫這個方法時使用的規則,即個人制定的簡單傷害計算方式:
普通攻擊傷害計算方式:
根據雙方的敏捷與體力進行判斷,
例如A收到傷害:
如果A的敏捷大於B的Power, 那麼擊中值(Hit)為40;
如果A的敏捷等於B 的power, 那麼擊中值(Hit)為80;
如果A的敏捷小於B的power, 那麼擊中值(Hit)為100, 即百分百命中;
之後如果判定命中,再根據雙方的攻擊力和防禦力經行判斷
如果A的防禦力大於B的攻擊力
那麼傷害為原始普通傷害的75%;
通過這種方式進行計算與編寫後就會得出上述的程式碼。但是程式碼中的Damage值不是直接由Enemy攻擊時傳遞過來的,上文已經大概介紹過原理了,不再贅述。同時,在Enemy發出攻擊時,還應將Enemy自身的各項屬性進行傳遞,以利用於進行上述方法。所以還需要這樣一個方法,程式碼:
public void GetParametersFromEnemy(float _EnemyHP, float _EnemyMP, float _EnemyAttack, float _EnemyDefend, float _EnemyStrong, float _EnemyIntelligence, float _EnemyAgility, float _EnemyPower, int _EnemyLv)
{
EnemyHP = _EnemyHP;
EnemyMP = _EnemyMP;
EnemyAttack = _EnemyAttack;
EnemyDefend = _EnemyDefend;
EnemyStrong = _EnemyStrong;
EnemyIntelligence = _EnemyIntelligence;
EnemyAgility = _EnemyAgility;
EnemyPower = _EnemyPower;
}
很簡單,不解釋。
然後是受到某些Debuff技能時,角色屬性的變化,比如受到降低敏捷,攻擊力,防禦力等技能時需要用到的方法,但是首先得先枚舉出所有可能受到降低的屬性,只需要在該指令碼中編寫一個列舉就好了,舉例程式碼:
public enum AddAttribute
{
/// <summary>
/// 直接影響血量上限
/// </summary>
HP,
/// <summary>
/// 直接影響魔法值上限
/// </summary>
MP,
/// <summary>
/// 攻擊力
/// </summary>
Attack,
/// <summary>
/// 防禦力
/// </summary>
Defend,
/// <summary>
/// 力量,影響每秒HP的恢復速率;影響HP上限
/// </summary>
Strong,
/// <summary>
/// 智力,影響魔法值MP上限,以及每秒魔法的恢復速率,
/// </summary>
Intelligence,
/// <summary>
/// 敏捷,影響攻擊速度AttackSpeed;轉身速率RotationSpeed;移動速度MoveSpeed
/// </summary>
Agility,
/// <summary>
/// 體力,影響HP的上限
/// </summary>
Power,
/// <summary>
/// 攻擊範圍
/// </summary>
AttackRange,
}
public void HeroGetDebuff(AddAttribute attribute, float Value)
{
if (attribute == AddAttribute.HP)
{
AddStatus.HP -= Value;
}
if (attribute == AddAttribute.MP)
{
AddStatus.MP -= Value;
}
if (attribute == AddAttribute.Attack)
{
AddStatus.Attack -= Value;
}
if (attribute == AddAttribute.Defend)
{
AddStatus.Defend -= Value;
}
if (attribute == AddAttribute.Strong)
{
AddStatus.Strong -= Value;
}
if (attribute == AddAttribute.Intelligence)
{
AddStatus.Intelligence -= Value;
}
if (attribute == AddAttribute.Agility)
{
AddStatus.Agility -= Value;
}
if (attribute == AddAttribute.Power)
{
AddStatus.Power -= Value;
}
GrowthisAdd = true;
UpdateAttribute ();
}
收到Debuff後,開始相應屬性的變化。然而debuff只可能時暫時性的,不可能一直存在,所以,我們還需要編寫一個方法來設定debuff結束時恢復各項屬性到原值的方法。程式碼:
public void DebuffComplete(AddAttribute attribute, float Value)
{
if (attribute == AddAttribute.HP)
{
AddStatus.HP += Value;
}
if (attribute == AddAttribute.MP)
{
AddStatus.MP += Value;
}
if (attribute == AddAttribute.Attack)
{
AddStatus.Attack += Value;
}
if (attribute == AddAttribute.Defend)
{
AddStatus.Defend += Value;
}
if (attribute == AddAttribute.Strong)
{
AddStatus.Strong += Value;
}
if (attribute == AddAttribute.Intelligence)
{
AddStatus.Intelligence += Value;
}
if (attribute == AddAttribute.Agility)
{
AddStatus.Agility += Value;
}
if (attribute == AddAttribute.Power)
{
AddStatus.Power += Value;
}
GrowthisAdd = true;
UpdateAttribute ();
}
}
同樣,debuff時間結束後,根據相應的屬性進行恢復。其中,什麼該給予debuff,什麼時候該結束debuff,是由發出者進行計算並且判斷的。接收者只負責接收並且做出改變。當角色為發出者,Enemy作為接收者時,也是同樣的道理。
嗯,人物屬性編輯器寫到這裡就差不多了,這個是sunset自己寫的角色屬性編輯器的Inspector面板樣式:
詳細內容:
大致完成後就是這樣的編輯器,是不是有一種在使用外掛感覺呢?
角色屬性編輯器的編寫就差不多到這裡結束了,在明後天,sunset會繼續給出編寫一款ARPG遊戲的流程程式碼,今天就先到這裡為止了吧。