Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 嵌套策略设计模式_C#_Design Patterns_Unity3d - Fatal编程技术网

C# 嵌套策略设计模式

C# 嵌套策略设计模式,c#,design-patterns,unity3d,C#,Design Patterns,Unity3d,假设我们有一个玩家控制一个名为Player1的角色。要在运行时启用武器切换,我有以下代码: public interface IWeapon { void Fire(); } public class Player1Weapon1 : IWeapon { ... void Fire() { //do actions of Weapon1 } ... } public class Player1Weapon2 : IWeapon

假设我们有一个玩家控制一个名为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的角色。 请注意,玩家2的武器与玩家1不同。因此,我们可以添加如下类:

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中放置哪些方法?如何创建嵌套的策略设计模式?

不确定我是否得到了您的要求,或者您是否不知道如何/如何提出要求。在这里,战略模式不是您最需要的。我试着给我的两分钱

首先,我认为在玩家中设置具体的类不是一个好主意,比如
player1wearm
。它应该只包含
IWeapon
s。这样你就不需要特别定义你的玩家使用的武器,也不需要为每一个变体创建新的玩家等级

考虑以下几点。在
SomeNamespace
命名空间中有这些
IWeapons

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");
    }
}
现在,您的
播放器
类可以如下所示。只要添加您可能需要的任何抽象级别,这里我假设您不需要

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;
    }
}
公共类PlayerFactory
{
//键=玩家姓名,值=武器
公共播放器创建(KeyValuePair参数)
{
var primary=Activator.CreateInstance(Type.GetType(args.Value[0]),作为IWeapon;
var secondary=Activator.CreateInstance(Type.GetType(args.Value[1])作为IWeapon;
var player=新玩家(args.Key、primary、secondary);
返回球员;
}
}
现在如果你运行下面的“初始化”

//这将来自配置文件或类似文件
var config=新列表
{
新的KeyValuePair(
“Player1”,新[]{“SomeNamespace.Shotgun”,“SomeNamespace.Knife”}),
新的KeyValuePair(
“Player2”,新[]{“SomeNamespace.NuclearBomb”,“SomeNamespace.Knife”})
};
var factory=新的PlayerFactory();
foreach(配置中的var条目)
{
var player=factory.Create(条目);
player.Fire();
player.Switch();
player.Fire();
}
。。。您将得到以下控制台日志

玩家“玩家1”产生
鸟枪发出隆隆声
刺伤吸盘

玩家“玩家2”产生
游戏结束了!!1
刺伤吸盘


不确定我是否明白你的要求,或者你是否不知道如何/问什么。在这里,战略模式不是您最需要的。我试着给我的两分钱

首先,我认为在玩家中设置具体的类不是一个好主意,比如
player1wearm
。它应该只包含
IWeapon
s。这样你就不需要特别定义你的玩家使用的武器,也不需要为每一个变体创建新的玩家等级

考虑以下几点。在
SomeNamespace
命名空间中有这些
IWeapons

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");
    }
}
现在,您的
播放器
类可以如下所示。只要添加您可能需要的任何抽象级别,这里我假设您不需要

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;
    }
}
公共类PlayerFactory
{
//键=玩家姓名,值=武器
公共播放器创建(KeyValuePair参数)
{
var primary=Activator.CreateInstance(Type.GetType(args.Value[0]),作为IWeapon;
var secondary=Activator.CreateInstance(Type.GetType(args.Value[1])作为IWeapon;
var player=新玩家(args.Key、primary、secondary);
返回球员;
}
}
现在如果你运行下面的“初始化”

//这将来自配置文件或类似文件
var config=新列表
{
新的KeyValuePair(
“Player1”,新[]{“SomeNamespace.Shotgun”,“SomeNamespace.Knife”}),
新的KeyValuePair(
“Player2”,新[]{“SomeNamespace.NuclearBomb”,“SomeNamespace.Knife”})
};
var factory=新的PlayerFactory();
foreach(配置中的var条目)
{
var player=factory.Create(条目);
player.Fire();
player.Switch();
player.Fire();
}
。。。您将得到以下控制台日志

玩家“玩家1”产生
鸟枪发出隆隆声
刺伤吸盘

玩家“玩家2”产生
游戏结束了!!1
刺伤吸盘


使用
策略
模式时,您的设计可能如下 下面是UML图

Player1
将执行
Fire()
操作的学员分配到不同的武器类别之一
Weapon1
Weapon2

有关进一步的讨论,请参见策略设计模式 在


使用
策略
模式时,您的设计可能如下 下面是UML图

Player1
将执行
Fire()
操作的学员分配到不同的武器类别之一
Weapon1
Weapon2

有关进一步的讨论,请参见策略设计模式 在


我认为你的玩家甚至不应该有“玩家X武器”,只是一个IWeapons的IEnumerable。是的,不要以将使用它的玩家的名字命名物品。想象一下,如果游戏允许一名玩家放下武器,另一名玩家拿起武器。这会让人困惑。武器可以独立于持有它的人而存在。@MickyDuncan,是的,但解决方案是什么?@S.A.Parkhid,通过实现一个玩家类,将Fire()操作委托给不同的武器类之一。可以动态指定和更改要使用的武器。查看我的UML图