2015-02-08 5 views
0

Предположим, у нас есть игрок, который управляет символом с именем 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. Обратите внимание, что Weapon 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, я должен addmore классы для проекта.

Мне интересно, как сделать шаблон для стратегии пожирателей, как показано ниже:

interface IPlayer() 
{ 

} 

Я не знаю, какие методы будут размещены в Iplayer? Как создать вложенные шаблоны проектирования стратегии?

+3

Я думаю, что ваши игроки не должны даже иметь "PlayerXWeapon", просто IEnumerable из IWeapons. –

+0

Да, не называть предмет после игрока, который будет его использовать. Представьте себе, если ваша игра позволила одному игроку сбросить оружие, а другой игрок поднял его. Это было бы странно. Оружие может существовать независимо от человека, который мог бы его удерживать. – MickyD

+0

@ MickyDuncan, да, но какое решение? –

ответ

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
Ножа Teh присоска

+0

спасибо, хороший ответ, но я должен проанализировать это. –

0

При использовании Strategy шаблона, ваша конструкция может выглядеть на UML диаграмме ниже.

Player1 делегаты исполняют Fire() операцию по одному из различных классов оружия Weapon1, 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; 
    } 
} 
Смежные вопросы