引入了Controller之后,我们就需要分离之前View层的一些逻辑。

StartView逻辑转移

删除StartViewInit方法,以及InitChild内部的逻辑。

删除UIUtil的Button相关引用和AddListener方法

将方法转移到StartController当中,删除这里之前的Init方法

1
2
3
4
5
6
7
8
9
10
11
[BindPrefab(Path.START_VIEW,Consts.BIND_PREFAB_PRIORITY_CONTROLLER)]
public class StartController : ControllerBase
{
protected override void InitChild()
{
transform.ButtonAction("Start",() =>
{
UIMgr.Instance.Show(Path.SELECT_HERO_VIEW);
});
}
}

SelectedHeroView逻辑转移

修改SelectedHeroView,在它的BindPrefab特性中添加上View的优先级参数,删除里面报错的UIUtil.AddListener的逻辑

在Controller文件夹中新建SelectedHeroController文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[BindPrefab(Path.SELECT_HERO_VIEW,Consts.BIND_PREFAB_PRIORITY_CONTROLLER)]
public class SelectedHeroController : ControllerBase
{
protected override void InitChild()
{
transform.ButtonAction("OK/Start",() =>
{
//TODO: 切换到选择关卡界面
});
transform.ButtonAction("Exit",() =>
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.ExitPlaymode();
#endif
UnityEngine.Application.Quit();
});
transform.ButtonAction("Strengthen",() =>
{
UIMgr.Instance.Show(Path.STRENGTHEN_VIEW);
});
}
}

StrengthenView逻辑转移

修改StrengthenView,在它的BindPrefab特性中添加上View的优先级参数,别的不需要修改。

在Controller文件夹中新建StrengthenControllerSwitchPlayerControllerPlanePropertyController文件,

StrengthenController

1
2
3
4
5
6
7
8
9
[BindPrefab(Path.STRENGTHEN_VIEW,Consts.BIND_PREFAB_PRIORITY_CONTROLLER)]
public class StrengthenController : ControllerBase
{
protected override void InitChild()
{
transform.Find("Switchplayer").gameObject.AddComponent<SwitchPlayerController>();
transform.Find("Property").gameObject.AddComponent<PlanePropertyController>();
}
}

SwitchPlayer逻辑转移

PlaneSpritesModel

由于SwitchPlayer需要先缓存所有的飞机Sprite,而飞机的数量和id的更新息息相关,我们先把飞机的部分使用Model缓存下来,便于后面更好地分离View和Controller。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System.Collections.Generic;
using UnityEngine;

public class PlaneSpritesModel : NormalSingleton<PlaneSpritesModel>, IInit
{
private Dictionary<int, List<Sprite>> _planeSprites;
public int Count
{
get
{
if (_planeSprites == null) return 0;
return _planeSprites.Count;
}
}
public Sprite this[int id, int level]
{
get
{
return GetPlaneSprite(id, level);
}
}
public void Init()
{
LoadSprite();
}

private void LoadSprite()
{
_planeSprites = new Dictionary<int, List<Sprite>>();
Sprite[] sprites = LoadMgr.Instance.LoadAll<Sprite>(Path.PLAYER_PICTURE_FOLDER);
foreach (Sprite sprite in sprites)
{
string[] idData = sprite.name.Split('_');
int playerId = int.Parse(idData[0]);
if (!_planeSprites.ContainsKey(playerId))
{
_planeSprites.Add(playerId, new List<Sprite>());
}
_planeSprites[playerId].Add(sprite);
}
}
private Sprite GetPlaneSprite(int id, int level)
{
if (!_planeSprites.ContainsKey(id) || level >= _planeSprites[id].Count)
{
Debug.LogErrorFormat("当前指定的飞机Sprite的id或等级错误:id:{0} level:{1}", id, level);
return null;
}
return _planeSprites[id][level];
}
}

这里的Model并没有指定Init方法初始化的位置,我们在下一节介绍Manager生命周期时说明初始化的地方

修改SwitchPlayer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class SwitchPlayer : ViewBase
{

protected override void InitChild()
{

}

public override void Show()
{
base.Show();
UpdateSprite();
}

public override void UpdateFun()
{
UpdateSprite();
}
private void UpdateSprite()
{
int id = GameStateModel.Instance.SelectedPlaneId;
string key = KeysUtil.GetPropertyKeys(DataKeys.LEVEL);//这个方法在后面修改过,这里是补充
int level = DataMgr.Instance.Get<int>(key);//从存档获取当前等级
UIUtil.Get("Icon").SetSprite(PlaneSpritesModel.Instance[id,level]);
}
}

SwitchPlayerController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class SwitchPlayerController : ControllerBase
{
private int _id;//标记当前正在选择中的飞机id
protected override void InitChild()
{
GameStateModel.Instance.SelectedPlaneId = DataMgr.Instance.Get<int>(DataKeys.PLANE_ID);
_id = GameStateModel.Instance.SelectedPlaneId;
transform.ButtonAction("Left",() => { Switch(ref _id, -1); });
transform.ButtonAction("Right",() => { Switch(ref _id, 1); });
}
private void Switch(ref int id, int direction)
{
UpdateId(ref id, direction);
GameStateModel.Instance.SelectedPlaneId = id;
}
private void UpdateId(ref int id, int direction)
{
int min = 0;
int max = PlaneSpritesModel.Instance.Count;
id += direction;
id = id < 0 ? min : id >= max ? max - 1 : id;
}
}

PlaneProperty逻辑转移

PlaneProperty没什么要修改的

PlanePropertyController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PlanePropertyController : ControllerBase
{
protected override void InitChild()
{
AddComponent();
}
private void AddComponent()
{
for(PlaneProperty.Property i = 0; i < PlaneProperty.Property.COUNT; i++)
{
var item = transform.GetChild((int)i).gameObject.AddComponent<PropertyItemController>();
item.Init(i.ToString());
}
}
}

PropertyItem逻辑转移

修改PropertyItem,删除掉GetPropertyKey方法,将InitButtonActionAddActionGetValue方法都转移到PropertyItemController中,将UpdateSlider中报错的部分使用下面的KeysUtil.GetPropertyItemKey解决。

删除掉Init方法内的InitButtonAction,修改Show方法

1
2
3
4
5
6
7
8
9
10
11
private void UpdateSlider()
{
Slider slider = transform.Find("Slider").GetComponent<Slider>();
slider.minValue = 0.0f;
slider.maxValue = DataMgr.Instance.Get<int>(KeysUtil.GetPropertyItemKey(ItemKey.maxValue, _key));//+++
slider.value = DataMgr.Instance.Get<int>(KeysUtil.GetPropertyItemKey(ItemKey.value, _key));//+++
}
public void Show()
{
UpdatePlaneId(GameStateModel.Instance.SelectedPlaneId);
}

在Controller文件夹中新建PropertyItemController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using static PropertyItem;

public class PropertyItemController : ControllerBase
{
private string _key;
public void Init(string key)
{
_key = key;
}
protected override void InitChild()
{
InitButtonAction();
}
private void InitButtonAction()
{
transform.ButtonAction("Add", AddAction);
}
private void AddAction()
{
string valueKey = KeysUtil.GetPropertyItemKey(ItemKey.value,_key);
int value = GetValue(valueKey);
string grouthKey = KeysUtil.GetPropertyItemKey(ItemKey.grouth, _key);
int grouth = GetValue(grouthKey);
value += grouth;

DataMgr.Instance.SetObject(valueKey, value);//注意这里,如果之前value是Int会被修改为Float,这是PlayerPrefs的机制
}
private int GetValue(string key)
{
return DataMgr.Instance.Get<int>(key);
}
}

PropertyItemGetPropertyKey逻辑转移到KeysUtil中,更名为GetPropertyItemKey

1
2
3
4
5
6
7
8
9
public class KeysUtil
{
//...
public static string GetPropertyItemKey(PropertyItem.ItemKey itemKey,string propertyName)
{
int planeId = GameStateModel.Instance.SelectedPlaneId;
return GetPropertyKeys(planeId, propertyName + itemKey);
}
}