您的位置:首页 > 移动开发 > Unity3D

Unity3D自学笔记——架构应用(十)角色属性

2016-11-04 01:58 891 查看

角色属性

效果图



类图



Attribute

提供公共的参数,每个参数都有两个值

Atk, 基础值,就是白属性

AtkMax, 计算后的值,就是附魔,升级,强化,镶嵌,充人民币后的值

public abstract class Attribute
{
private Attribute m_Parent;
public int Hp { get; set; }
public int Mp { get; set; }
public int Atk { get; set; }
public int Def { get; set; }
public int Spd { get; set; }
public int Hit { get; set; }
public double CriticalRate { get; set; }
public double AtkSpd { get; set; }
public double AtkRange { get; set; }
public double MoveSpd { get; set; }

public int HpMax { get; set; }
public int MpMax { get; set; }
public int AtkMax { get; set; }
public int DefMax { get; set; }
<
4000
span class="hljs-keyword">public int SpdMax { get; set; }
public int HitMax { get; set; }
public double CriticalRateMax { get; set; }
public double AtkSpdMax { get; set; }
public double AtkRangeMax { get; set; }
public double MoveSpdMax { get; set; }

public abstract void Calculate();

protected void SetParent(AttributeNode child)
{
child.m_Parent = this.m_Parent;
}
public Attribute GetParent()
{
return this.m_Parent;
}
}


AttributNode

继承Attribute,递归实现Caculate,然后实现添加节点和删除节点

就是给白属性不断的加各种效果

public class AttributeNode : Attribute
{
private List<Attribute> m_NodeList = new List<Attribute>();
public override void Calculate()
{
this.HpMax = this.Hp;
this.MpMax = this.Mp;
this.AtkMax = this.Atk;
this.DefMax = this.Def;
this.SpdMax = this.Spd;
this.HitMax = this.Hit;
this.CriticalRateMax = this.CriticalRate;
this.AtkSpdMax = this.AtkSpd;
this.AtkRangeMax = this.AtkRange;
this.MoveSpdMax = this.MoveSpd;

foreach (AttributeNode node in m_NodeList)
{
if (node.NodeCount() > 0)
{
node.Calculate();
}

this.HpMax += node.HpMax;
this.MpMax += node.MpMax;
this.AtkMax += node.AtkMax;
this.DefMax += node.DefMax;
this.SpdMax += node.SpdMax;
this.HitMax += node.HitMax;
this.CriticalRateMax += node.CriticalRateMax;
this.AtkSpdMax += node.AtkSpdMax;
this.MoveSpdMax += node.MoveSpdMax;
}
}
public int NodeCount()
{
return m_NodeList.Count;
}
public void AddNode(AttributeNode node)
{
m_NodeList.Add(node);
}
public void RemoveNode(AttributeNode node)
{
m_NodeList.Remove(node);
}
}


AttributeRoot

最顶级节点,就是角色属性

最开始没有Root类的,但是在处理当前血量时卡了很久

按照设计Hp应该是英雄的基础属性(1级的属性),它不能变,不然一执行Caculate就跟开挂样,不断增加,所以还需要一个CurrentHp 来等于 MaxHp。又不想在PlayerInfo里面又单独定义一套属性,所以就提取了Root类,毕竟主角光环,它特殊。可以看到大多方法是和Node一样的,只是多了一个Caculate(bool),作为初始化是将HpCur = HpMax用。不用Root继承Node的原因是,减小类之间的耦合关系,怕到后期变化过大导致不易修改。

public class AttributeRoot : Attribute
{
public int HpCur { get; set; }
public int MpCur { get; set; }
public int AtkCur { get; set; }
public int DefCur { get; set; }
public int SpdCur { get; set; }
public int HitCur { get; set; }
public double CriticalRateCur { get; set; }
public double AtkSpdCur { get; set; }
public double AtkRangeCur { get; set; }
public double MoveSpdCur { get; set; }

private List<Attribute> m_NodeList = new List<Attribute>();
public override void Calculate()
{
this.HpMax = this.Hp;
this.MpMax = this.Mp;
this.AtkMax = this.Atk;
this.DefMax = this.Def;
this.SpdMax = this.Spd;
this.HitMax = this.Hit;
this.CriticalRateMax = this.CriticalRate;
this.AtkSpdMax = this.AtkSpd;
this.AtkRangeMax = this.AtkRange;
this.MoveSpdMax = this.MoveSpd;

foreach (AttributeNode node in m_NodeList)
{
if (node.NodeCount() > 0)
{
node.Calculate();
}

this.HpMax += node.HpMax;
this.MpMax += node.MpMax;
this.AtkMax += node.AtkMax;
this.DefMax += node.DefMax;
this.SpdMax += node.SpdMax;
this.HitMax += node.HitMax;
this.CriticalRateMax += node.CriticalRateMax;
this.AtkSpdMax += node.AtkSpdMax;
this.MoveSpdMax += node.MoveSpdMax;
}
}

public void Calculate(bool isInit)
{
Calculate();
if (isInit)
{
this.HpCur = this.HpMax;
this.MpCur = this.MpMax;
this.AtkCur = this.AtkMax;
this.DefCur = this.DefMax;
this.SpdCur = this.SpdMax;
this.HitCur = this.HitMax;
this.CriticalRateCur = this.CriticalRateMax;
this.AtkSpdCur = this.AtkSpdMax;
this.MoveSpdCur = this.MoveSpdMax;
}
}
public int NodeCount()
{
return m_NodeList.Count;
}
public void AddNode(AttributeNode node)
{
m_NodeList.Add(node);
}
public void RemoveNode(AttributeNode node)
{
m_NodeList.Remove(node);
}
}


PlayerStatus

挂在角色上的

目前实现了当角色在场景中创建成功后,调用Load事件进行初始化。这里把Lv和Exp单独抽出来,是没有考虑装备或者其他技能对LV和经验的变化。而且经验是变化最快的,没杀一个怪就变了,一变就Caculate也太耗性能了。

public class PlayerStatus : MonoBehaviour {
private UserEntity m_User;
public double m_MultipleExp = 1.18;
public int m_StartExp = 40;
public string PlayerName { get; set; }
public int Lv { get; set; }
public int LvMax { get; set; }
public double Exp { get; set; }
public double ExpMax { get; set;}
public double HpRegenTime { get; set; }
public double MpRegenTime { get; set; }

public AttributeNode statusGrowth = new AttributeNode();
public AttributeNode statusEquip = new AttributeNode();
public AttributeNode statusBuff = new AttributeNode();
public AttributeRoot status = new AttributeRoot();

void Start()
{

}

private void InitAllStatus()
{
InitStatusGrowth();
InitStatus();
}

private void InitStatusGrowth()
{
this.statusGrowth.Hp = this.Lv * this.m_User.Hero.HpGrowth;
this.statusGrowth.Mp = this.Lv * this.m_User.Hero.MpGrowth;
this.statusGrowth.Atk = this.Lv * this.m_User.Hero.AtkGrowth;
this.statusGrowth.Def = this.Lv * this.m_User.Hero.DefGrowth;
this.statusGrowth.Spd = this.Lv * this.m_User.Hero.SpdGrowth;
this.statusGrowth.Hit = this.Lv * this.m_User.Hero.HitGrowth;
this.statusGrowth.CriticalRate = this.Lv * this.m_User.Hero.CriticalRateGrowth;
this.statusGrowth.AtkSpd = this.Lv * this.m_User.Hero.AtkSpdGrowth;
this.statusGrowth.AtkRange = this.Lv * this
ca30
.m_User.Hero.AtkRangeGrowth;
this.statusGrowth.MoveSpd = this.Lv * this.m_User.Hero.MoveSpdGrowth;

this.statusGrowth.Calculate();
}

private void InitStatus()
{
this.status.Hp = this.m_User.Hero.Hp;
this.status.Mp = this.m_User.Hero.Mp;
this.status.Atk = this.m_User.Hero.Atk;
this.status.Def = this.m_User.Hero.Def;
this.status.Spd = this.m_User.Hero.Spd;
this.status.Hit = this.m_User.Hero.Hit;
this.status.CriticalRate = this.m_User.Hero.CriticalRate;
this.status.AtkSpd = this.m_User.Hero.AtkSpd;
this.status.AtkRange = this.m_User.Hero.AtkRange;
this.status.MoveSpd = this.m_User.Hero.MoveSpd;

this.status.AddNode(this.statusGrowth);
this.status.AddNode(this.statusEquip);
this.status.AddNode(this.statusBuff);
this.status.Calculate(true);
}

public void Load(UserEntity user)
{
this.m_User = user;
this.Lv = this.m_User.Lv;
this.PlayerName = this.m_User.Name;
this.Exp = this.m_User.Exp;
this.ExpMax = m_StartExp * m_MultipleExp * this.Lv;
this.LvMax = this.m_User.Hero.MaxLv;
this.HpRegenTime = this.m_User.HpRegenTime;
this.MpRegenTime = this.m_User.MpRegenTime;

InitAllStatus();
}
}


UIPlayerInfo

角色属性绑值

public class UIPlayerInfo : UIScene {
private Image m_ImgHead;
private Text m_TxtLv;
private Text m_TxtName;
private Text m_TxtHp;
private Text m_TxtMp;
private Slider m_SldHp;
private Slider m_SldMp;
private Slider m_SldExp;

private PlayerStatus m_PlayerStatus;

protected override void Start()
{
base.Start();
InitWidget();
}

private void InitWidget()
{
this.m_ImgHead = UIHelper.FindChild<Image>(transform, "imgHead");
this.m_TxtLv = UIHelper.FindChild<Text>(transform, "txtLv");
this.m_TxtName = UIHelper.FindChild<Text>(transform, "txtName");
this.m_SldHp = UIHelper.FindChild<Slider>(transform, "sldHp");
this.m_SldMp = UIHelper.FindChild<Slider>(transform, "sldMp");
this.m_SldExp = UIHelper.FindChild<Slider>(transform, "sldExp");
this.m_TxtHp = UIHelper.FindChild<Text>(transform, "sldHp/Text");
this.m_TxtMp = UIHelper.FindChild<Text>(transform, "sldMp/Text");
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
//TODO: this.m_ImgHead
this.m_PlayerStatus = player.GetComponent<PlayerStatus>();
this.m_TxtName.text = this.m_PlayerStatus.PlayerName;
this.m_TxtLv.text = this.m_PlayerStatus.Lv.ToString();
this.m_TxtHp.text = string.Format("{0}/{1}", this.m_PlayerStatus.status.HpCur, this.m_PlayerStatus.status.HpMax);
this.m_TxtMp.text = string.Format("{0}/{1}", this.m_PlayerStatus.status.MpCur, this.m_PlayerStatus.status.MpMax);
this.m_SldHp.value = this.m_PlayerStatus.status.HpCur / this.m_PlayerStatus.status.HpMax;
this.m_SldExp.value = this.m_PlayerStatus.status.MpCur / this.m_PlayerStatus.status.MpMax;
this.m_SldExp.value = (float)(this.m_PlayerStatus.Exp / this.m_PlayerStatus.ExpMax);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: