策略模式在游戏开发中的应用

策略模式

在策略模式中,一个类的行为或者其算法可以在运行时更改。这种类型的设计模式属于行为模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象而改变的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下载地址)


在这里插入图片描述

没有更多推荐了,返回首页