C ++ шаблон игры и декоратора - PullRequest
2 голосов
/ 28 августа 2009

Я портирую 2D-платформер, и мне нужен хороший способ получить некоторую расширяемость моих тайлов уровня. Я не уверен, что Decorator здесь прав, но больше ничего не приходит на ум. Может быть, мне нужно что-то уникальное.

В любом случае, скажем, у меня есть базовый тайл, в котором есть такие вещи, как его изображение, и может ли игрок пройти через него (фон или передний план). Теперь я хочу добавить к ним свойства, например, заставить некоторые плитки выступать в роли лестниц, или сделать несколько ран или убить игрока при контакте. Может быть, некоторые могут исчезнуть. Некоторые свойства могут быть объединены.

Это звучит как декоратор, но мне действительно не нравится, как для этого требуется, чтобы мой базовый класс реализовывал фиктивные версии всего, например isLadder(), isLethal() и т. Д. Есть ли лучший способ? Я не собираюсь быть парнем, который меняет мой дизайн, просто чтобы он выглядел как нечто из книги GoF.

Извините, если об этом спрашивали миллион раз, я не совсем нашел его в смежных вопросах.

Ответы [ 5 ]

4 голосов
/ 28 августа 2009

То, как вы разрабатываете свои методы класса, может сильно повлиять на сложность реализации Decorator - например, вместо isLadder() и isLethal() и так далее, почему бы не иметь методы, основанные на способах, которыми игрок может взаимодействовать с плиткой (enter(from_dir), exit(to_dir)) и т. д.? Смертельный тайл может переопределить метод enter(), сигнализируя о том, что игрок должен быть убит; лестничная клетка может переопределить либо enter(), либо exit() в зависимости от желаемой функциональности.

2 голосов
/ 28 августа 2009

Я бы представил что-то вроде класса TileTraits. Каждая плитка может вернуть свои черты с помощью метода well ..., getTraits (). TileTraits может быть расширен для поддержки любого количества плиток. Что-то вроде:

class TileTraits
{
public: 
   enum TileTrait{ Walkable  = 1, 
                   Climbable = 1 << 1, 
                   Lethal    = 1 << 2 };
private:
   TileTrait m_TraitSet;
};

class BaseTile
{
public:
   virtual TileTraits getTraits() const;
};

class LadderTile : public BaseTile
{
public:
   TileTraits getTraits() const { 
      return TileTraits( TileTraits::Walkable | TileTraits::Climbable); 
    }
};
2 голосов
/ 28 августа 2009

Дав прав. Это может быть что-то вроде этого:

class Tile
{
    public bool allowsPassThrough()
    {}

    // couldn't find a better name for this method
    public void passThrough(Player player)
    {}
}

class LethalTile extends Tile
{
    public void passThrough(Player player)
    {
        player.kill();
    }
}
1 голос
/ 28 августа 2009

Возможно, вам стоит взглянуть на объекты на основе компонентов. Вот пример: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

1 голос
/ 28 августа 2009

Что ж, если речь идет о наборе is*() функций, вы можете перейти к функции типа isIt(what), возвращающей oh no! реализацию по умолчанию, которая будет использоваться в качестве запасного в производных классах.

...