这节主要讲到所有游戏中常运用的技术—MVC实现逻辑与视图的有效分离,其实MVC在做那种休闲游戏的是不单单只是游戏逻辑和UI的分离,也和游戏里面视图的分离。但3D动作类型的游戏很难做到人物视图和游戏逻辑之间的分离,这里我只讲游戏逻辑和UI之间的分离,有时间讲2D休闲游戏的时候再讲游戏逻辑和视图的分离。首先,我们先写UI的数据类:
首先我们得知道我们有什么要显示给用户看到的,这里就主角而言,他有好多东西需要被玩家所看到例如玩家的攻击力,攻击速度,暴击频率,暴击伤害,及当前人物的等级,玩家的血管的总血量,玩家的护甲值,玩家的当前血量,玩家的各种buff属性。这些都是我们需要让我们的玩家直观的看见的。所以这个数据类我们设计成UIData:
public class UIData
{
public AttackData AttackData { set; get; }
public HealthData HealthData { set; get; }
public PropertyData PropertyData { set; get; }
public int KillNum { set; get; }
public void Inilized(AttackData attackData, HealthData healthData, PropertyData propertyData,int killnum)
{
AttackData = attackData;
HealthData = healthData;
PropertyData = propertyData;
KillNum = killnum;
}
}
上面的注释我就不写了,因为根据名字都一清二楚了。接下来就是一个ui显示层,我命名为UiLayer,代码如下:
public class UiLayer : MonoBehaviour
{
public Text GongjiLiText;
public Text GongjiSuduText;
public Text CristrikefreqText;
public Text CritrikedamageText;
public Text LevleText;
public Slider BloodSlider;
public Text HuJiaText;
public Text CurBloodText;
public Text BloodText;
public Toggle GoldToggle;
public Toggle IceToggle;
public Toggle FireToggle;
public Text KillnumText;
}
这个为表现层,上面那个是数据层。现在接下来就是一个控制层,那么这个控制层就是把数据层和显示层结合起来了。我命名为UIHandle代码如下:
public class UIHandle:IUIHandle
{
public UIData _uiData { set; get;}
private UiLayer _uiLayer;
private float _delta;
public UIHandle(UIData uiData,UiLayer uiLayer)
{
_uiLayer = uiLayer;
_uiData = uiData;
UpdateUi();
}
public void SetUiData(UIData data)
{
_uiData = data;
UpdateUi();
}
private void UpdateUi()
{
_uiLayer.GongjiLiText.text = _uiData.AttackData.GongjiLiNum.ToString();
_uiLayer.GongjiSuduText.text = _uiData.AttackData.GongjiSuduNum.ToString();
_uiLayer.CritrikedamageText.text = _uiData.AttackData.CriStrDamageNum.ToString();
_uiLayer.CristrikefreqText.text = _uiData.AttackData.CriStrFrequencyNum.ToString();
_uiLayer.LevleText.text = _uiData.AttackData.Level.ToString();
var numerator = _uiData.HealthData.CurBloodNum;
var denominator = _uiData.HealthData.BloodNum;
_uiLayer.BloodSlider.value = numerator/denominator;
_uiLayer.HuJiaText.text = _uiData.HealthData.HuJiaNum.ToString();
_uiLayer.CurBloodText.text =((int) _uiData.HealthData.CurBloodNum).ToString();
_uiLayer.BloodText.text = _uiData.HealthData.BloodNum.ToString();
_uiLayer.GoldToggle.isOn = _uiData.PropertyData.IsActiveGold;
_uiLayer.FireToggle.isOn = _uiData.PropertyData.IsActiveFire;
_uiLayer.IceToggle.isOn = _uiData.PropertyData.IsActiveIce;
if(_uiLayer.KillnumText)
_uiLayer.KillnumText.text = _uiData.KillNum.ToString();
}
}
当然有可能怪物没有一些属性的,例如killnum,buff属性,所以这里我们要判断一下这里他们是不是为空。这里采用的每当有一个数据发生了变化,我们所有的ui都会更新一次,其实这里我是偷懒了,这里的更新应该拆出来,分开更新。但是这样在人物实体类中就会很分散,不容易管理了,这样我的做法确实有些欠妥,虽然有好多没必要的更新,但是很方便。这里你可以有2中方法可以选择,那根据你的想法来权衡了。对于玩家实体类而言,它根本就不知道这里面有多少UI控件要更新,它只知道一个方法SetUiData。所以这样封装是很有用的。而UIHandle对于玩家实体来说,它也只不过是一个view,所以玩家实体同时是一个modle层也是一个control层。这就是mvc不是很难,在游戏中也会经常被用到。