假设我们有一个控制名为Player1的角色的玩家。要在运行时启用切换武器,我有以下代码:
public interface IWeapon
{
void Fire();
}
public class Player1Weapon1 : IWeapon
{
...
void Fire()
{
//do actions of Weapon1
}
...
}
public class Player1Weapon2 : IWeapon
{
...
void Fire()
{
//do actions of Weapon2
}
...
}
public class Player1
{
IWeapon weapon;
Player1Weapon1 w1;
Player1Weapon2 w2;
public Player1()
{
w1 = new Player1Weapon1(this);
w2 = new Player1Weapon2(this);
SetWeapon(w1);
}
void Update()
{
if(SWITCH_BTN_HELD)
{
if(weapon.equals(w1)) SetWeapon(w2);
if(weapon.equals(w2)) SetWeapon(w1);
}
if(FIRE_BTN_HELD)
weapon.Fire();
}
void SetWeapon(w)
{
weapon = w;
}
}
完美无缺。
但现在玩家可以选择另一个名为Player2的角色。 请注意,Player2的武器与Player1不同。所以我们可以像这样添加类:
public class Player2Weapon1 : IWeapon
{
...
void Fire()
{
//do actions of Weapon1
}
...
}
public class Player2Weapon2 : IWeapon
{
...
void Fire()
{
//do actions of Weapon2
}
...
}
public class Player2
{
IWeapon weapon;
Player2Weapon1 w1;
Player2Weapon2 w2;
public Player2()
{
w1 = new Player2Weapon1(this);
w2 =new Player2Weapon2(this);
SetWeapon(w1);
}
void Update()
{
if(SWITCH_BTN_HELD)
{
if(weapon.equals(w1)) SetWeapon(w2);
if(weapon.equals(w2)) SetWeapon(w1);
}
if(FIRE_BTN_HELD)
weapon.Fire();
}
void SetWeapon(w)
{
weapon=w;
}
}
它会再次起作用,但是非常紧张,如果玩家想玩Player3,我应该为项目添加更多类。
我想知道如何为下面的劫掠者制作战略模式:
interface IPlayer()
{
}
我不知道哪些方法会放在IPlayer中?如何创建嵌套的策略设计模式?
答案 0 :(得分:4)
不确定我是否得到您要求的内容,或者您不知道如何/要问什么。战略模式不是你在这里最需要的。我试着给我两分钱。
首先,我认为在你的球员中加入具体的课程并不是一个好主意,比如Player1Weapon
。它应该只包含IWeapon
个。这样你就不需要专门定义你的玩家使用哪种武器,也不需要为每种变化创建新的玩家类。
请考虑以下事项。您在IWeapons
命名空间中拥有这些SomeNamespace
。
public interface IWeapon
{
void Fire();
}
public class Shotgun : IWeapon
{
public void Fire()
{
Console.WriteLine("Shotgun goes boom");
}
}
public class Knife : IWeapon
{
public void Fire()
{
Console.WriteLine("Stabbed teh sucker");
}
}
public class NuclearBomb : IWeapon
{
public void Fire()
{
Console.WriteLine("Game over for everyone!!1");
}
}
现在,您的Player
课程如下所示。只需添加您可能需要的任何抽象级别,这里我假设您没有。
public class Player
{
private IWeapon _wielded;
public Player(string name)
:this(name, null, null)
{}
public Player(string name, IWeapon primary, IWeapon secondary)
{
Name = name;
Primary = _wielded = primary;
Secondary = secondary;
Console.WriteLine(string.Format("Player '{0}' spawned", Name));
}
public void Switch()
{
_wielded = _wielded != Primary ? Primary : Secondary;
}
public void Fire()
{
if (_wielded != null)
_wielded.Fire();
}
public string Name { get; set; }
public IWeapon Primary { get; set; }
public IWeapon Secondary { get; set; }
}
要创建“任何玩家”,您可以拥有一个简单的工厂来“生成”它们,并将所需的属性作为参数。
public class PlayerFactory
{
// key = player name, value = weapons
public Player Create(KeyValuePair<string, string[]> args)
{
var primary = Activator.CreateInstance(Type.GetType(args.Value[0])) as IWeapon;
var secondary = Activator.CreateInstance(Type.GetType(args.Value[1])) as IWeapon;
var player = new Player(args.Key, primary, secondary);
return player;
}
}
现在如果您运行以下“初始化”...
// this would come from config file or similar
var config = new List<KeyValuePair<string, string[]>>
{
new KeyValuePair<string,string[]>(
"Player1", new[] { "SomeNamespace.Shotgun", "SomeNamespace.Knife" }),
new KeyValuePair<string,string[]>(
"Player2", new[] { "SomeNamespace.NuclearBomb", "SomeNamespace.Knife" })
};
var factory = new PlayerFactory();
foreach (var entry in config)
{
var player = factory.Create(entry);
player.Fire();
player.Switch();
player.Fire();
}
...您最终得到以下控制台日志
玩家'Player1'产生了 霰弹枪开始繁荣 刺伤了吸盘
玩家'Player2'产生了 每个人的游戏结束!! 1
刺伤了傻逼
答案 1 :(得分:0)
使用Strategy
模式时,您的设计可能看起来像
下面的UML图。
Player1
个代表对Fire()
,Weapon1
,...... {/ p>之一的不同武器类之一执行Weapon2
操作
有关进一步的讨论,请参阅策略设计模式 在http://w3sdesign.com。
public interface IWeapon
{
void Fire();
}
public class Weapon1 : IWeapon
{
...
void Fire()
{
//do actions of Weapon1
}
...
}
public class Weapon2 : IWeapon
{
...
void Fire()
{
//do actions of Weapon2
}
...
}
public interface IPlayer
{
void Update();
}
public class Player1 : IPlayer
{
private IWeapon weapon;
private IWeapon w1;
private IWeapon w2;
public Player1()
{
w1 = new Weapon1();
w2 = new Weapon2();
SetWeapon(w1);
}
void Update()
{
if(SWITCH_BTN_HELD)
{
if(weapon.equals(w1)) SetWeapon(w2);
if(weapon.equals(w2)) SetWeapon(w1);
}
if(FIRE_BTN_HELD)
weapon.Fire();
}
void SetWeapon(w)
{
weapon = w;
}
}