策略模式
在策略模式中,一个类的行为或者其算法可以在运行时更改。这种类型的设计模式属于行为模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象而改变的Contenxt(上下文对象),策略对象改变Context对象的执行算法。
意图
通过定义一系列的算法,并将其封装为对象,在运行时,可以更具输入条件的不同,动态更换不同的算法。可以很大程度的解决大量使用if…else 语句来描述算法的问题。
需求描述
在游戏中有一架战斗机,战斗机可以发射子弹和发射导弹,同时,战斗机发动机可以喷射出红色和蓝色的火焰。通过触发键盘的C键可以切换发射导弹的形式;触发键盘的F键可以更换发动机喷出火焰的颜色。下面我们通过策略模式来实现这个需求。
核心类图:
Demo截图:
弹药类的实现
- 定义弹药的接口,IWeapon.cs如下:
public interface IWeapon {
void Shoot (Vector3 pos);
}
- 定义一个枚举来表示当前选择的弹药的类型
public enum WeaponType {
Missile,
Bullet
}
- 定义具体的Bullet(子弹类)并实现Iweapon接口
public class Bullet : IWeapon {
public void Shoot (Vector3 pos) {
Vector3 initialPosition = new Vector3 (pos.x, pos.y + 1f, 0);
GameObject bullet = MonoBehaviour.Instantiate(
Resources.Load ("BulletPrefab", typeof (GameObject))) as GameObject;
bullet.transform.position = initialPosition;
bullet.GetComponent<Rigidbody2D> ().velocity = new Vector2 (0f, 3f);
}
}
- 定义具体的Missile(导弹类)并实现Iweapon接口
public class Missile : IWeapon {
public void Shoot (Vector3 pos) {
Vector3 initialPosition = new Vector3 (pos.x, pos.y + 1f, 0);
GameObject missile = MonoBehaviour.Instantiate (
Resources.Load ("MissilePrefab", typeof (GameObject))) as GameObject;
missile.transform.position = initialPosition;
missile.GetComponent<Rigidbody2D> ().velocity = new Vector2 (0f, 3f);
}
}
火焰类的实现
- 定义火焰的接口IFlame(火焰),IFlame.cs如下:
public interface IFlame{
void ShowFlame();//显示当前颜色的火焰
void DestroyFlame();//销毁当前火焰
}
- 定义一个枚举来表示当前选中火焰的类型
public enum FlameType {
Blue,
Red
}
- 定义具体的BlueFlame(蓝色火焰)并实现IFlame接口
public class BlueFlame:MonoBehaviour,IFlame{
private GameObject flame;
public void ShowFlame(){
if (flame!=null)return;
GameObject blueFlame = Instantiate(Resources.Load("Flame-blue",
typeof(GameObject))) as GameObject;
flame = blueFlame;
blueFlame.transform.parent=transform;
}
public void DestroyFlame(){
Destroy(flame);
}
}
- 定义具体的RedFlame(红色火焰)并实现IFlame接口
public class RedFlame:MonoBehaviour,IFlame{
private GameObject flame;
public void ShowFlame(){
if (flame!=null)return;
GameObject redFlame = Instantiate(Resources.Load("Flame-red",
typeof(GameObject))) as GameObject;
flame = redFlame;
redFlame.transform.parent=transform;
}
public void DestroyFlame(){
Destroy(flame);
}
}
Context类(ShipController.cs)的实现
- 根据用户当前选择的弹药类型,实例化相对应的弹药
private void HandleWeaponType () {
var weponTypeEnumLength=System.Enum.GetNames(weaponType.GetType()).Lengt;
var currentWeaponType=(WeaponType)((seed++)%weponTypeEnumLength);
#region 策略
switch (currentWeaponType) {
case WeaponType.Bullet:
iWeapon =new Bullet () ;
break;
case WeaponType.Missile:
iWeapon = new Missile ();
break;
default:
iWeapon = new Bullet () ;
break;
}
#endregion
}
- 根据用户当前选择的火焰类型,实例化相对应的火焰
public void HandleFlameColor () {
var flameColorEnumLength=System.Enum.GetNames(flameColorType.GetType()).Length;
var currentFlameColor=(FlameType)((seed++)%flameColorEnumLength);
Component c=this.GetComponent<IFlame>() as Component;
if (c!=null){
Destroy(c);
iFlame.DestroyFlame();
}
#region 策略
switch (currentFlameColor) {
case FlameType.Blue:
iFlame = gameObject.AddComponent<BlueFlame> ();
break;
case FlameType.Red:
iFlame = gameObject.AddComponent<RedFlame> ();
break;
default:
iFlame = gameObject.AddComponent<BlueFlame> ();
break;
}
#endregion
}
END
原文参考及Code来源:
http://www.theappguruz.com/blog/learn-strategy-pattern-in-unity-in-less-than-15-minutes
完整Demo
扫码->关注->历史消息->当前文章末尾(获取Demo下载地址)
转载:https://blog.csdn.net/JianZuoGuang/article/details/88234353
查看评论