Шаблон дизайна игрового решения - PullRequest
4 голосов
/ 11 августа 2011

Итак, у меня есть много объектов с материалами, каждый из которых обладает разными свойствами (кирпич, стекло и т. Д.), И каждый из них по-разному подвержен влиянию стихий. Например, на кирпичный материал огонь или кислота воздействуют иначе, чем на цементный материал. Кирпич, который горит или тает, будет действовать по-разному, когда будет применен другой эффект жжения / таяния.

На данный момент в моей игре есть FSM, но это очень просто. Если я уроню огненный элемент на кирпич, он перейдет в состояние горения. Однако, если я затем уроню элемент воды на кирпич, я могу захотеть, чтобы огонь погас, взял / добавил здоровье и изменил текстуры (или не зависит от текущей комбинации).

Суть в том, что у меня много комбинаций, и между ними нет общего, поэтому я не могу создать что-то однородное. Иногда мне нужно изменить текстуру, а иногда нет. Иногда получайте урон, а другие добавляйте здоровье. Иногда мне нужно просто ничего не делать в функции. На данный момент, единственное, что я могу сделать, это создать глобальное отображение, такое как:

FunctionMap [ObjectMaterial] [CurrentObjectState] [ElementBeingApplied]

(т. Е.

FunctionMap [Кирпич] [Горящий] [Кислотный]
FunctionMap [Кирпич] [плавления] [кислота]

)

Проблема в том, что это, очевидно, тонна функций из-за количества комбинаций, доступных с материалами и типами эффектов. Кто-нибудь может порекомендовать маршрут или шаблон для просмотра?

Хотя это не совсем относится к обсуждению, это делается в AS3 и Away3D.

Вот некоторые из моих классов для одного примера:

public class Brick extends AbstractBlock implements IFireable
{
    public function Brick()
    {
        super(this);
        this.material = new BitmapMaterial(_spriteManager.GetBlockMaterial(BlockUtilities.GetMaterialMap["brick_new"]));
        _type = "Brick";
        /*
        RulesManager.StateMap["Brick"]["OnFire"]["Water"] = some function;
        RulesManager.StateMap["Brick"]["OnFire"]["Fire"] = some function;
        RulesManager.StateMap["Brick"]["OnFire"]["Acid"] = some function;
        RulesManager.StateMap["Brick"]["OnFire"]["Ice"] = some function;
        RulesManager.StateMap["Brick"]["OnWater"]["Water"] = some function;
        //and so on...there are nine different materials so I'm not liking this way
        */
    }

    public override function render():void
    {
        super.render();
    }
}   


public class OnFire extends AbstractDamage
{       

    protected var _timeStart:Number = 0;

    private var _damageAccumulated:Number = 0;

    public function OnFire(block:AbstractBlock,bombType:String) 
    {       
        super(block,bombType);                                      
    }

    public override function enter():void        
    {       
        super.enter();  
    }

    public override function exit():void         
    {       
        super.exit();                                       
    }

    public override function update(time:Number):void
    {
        super.update(time);

        if(_timeStart == 0)
            _timeStart = time;

        var time_delta:Number = (time - _timeStart)/_waitTime;

        var damageToSubtract:Number = (time_delta * _damageDone);

        _damageAccumulated += damageToSubtract;

        _self.Integrity = _self.Integrity - _damageAccumulated;


    }
}
* *} Тысяча двадцать-один

Таким образом, огненный элемент может быть применен к группе применений. Один из этих блоков, в настоящее время замороженный, теперь ударил и теперь переходит в состояние OnFire. Каждый блок имеет свой собственный конечный автомат, и состояния, как вы можете видеть, сами являются объектами.

block.FSM.changeState(new OnFire(block));

Ответы [ 3 ]

1 голос
/ 12 августа 2011

Короткий ответ, потому что я считаю, что мистер Линквист отлично объясняет это, но для меня это звучит как работа для шаблона посетителя . Одним словом, все ваши элементы (кирпич, бетон и т. Д.) Позволяют посетителям (огонь, лед, кислота и т. Д.) Приходить и «посещать» их и применять их эффекты.

Надеюсь, это поможет!

1 голос
/ 12 августа 2011

Итак, ваша проблема в том, что у вас есть 9 * 5 * 4 комбинаций эффектов, верно?Иметь отдельные функции для каждой из них было бы не очень интересно.Но даже если данных много, они вам нужны.Я хотел бы сделать эти данные максимально простыми, а затем проанализировать их.Что-то вроде:

var materialProperties = {
  brick: {
    fire: {
      normal: {damage: 10, image: 'brick_fire.jpg'},
    }
    water: {
      fire: {damage: 0, image: 'brick_smoking.jpg'}
    }
  },
  //... a lot more of this ...
}

class Material
{
  public var damage:int = 0;
  public var image:String = '';

  private var properties:Object;
  private var state:String;

  public function Material(properties)
  {
    this.properties = properties;
  }

  public function apply(effect:String):void
  {
    if(properties[effect])
    {
      if(properties[effect][state])
      {
        update(properties[effect][state]);
      }
      else if(properties[effect]['normal'])
      {
        update(properties[effect]['normal']);
      }
    }
    state = effect;
  }

  private function update(properties):void
  {
    damage += properties.damage;
    image = properties.image;
  }
}

var brick = new Material(materialProperties.brick);
brick.apply('fire');
brick.apply('water');
1 голос
/ 11 августа 2011

У вас есть настраиваемые классы? Для меня это звучит как идеальное решение. Как только вы наметите свойства и способности каждого класса, управление объектами должно быть тривиальным.

т.е. класс Brick, который имеет определенные состояния [горение, таяние] и по-разному реагирует [вызовы функций], когда он взаимодействует [сталкивается] с другим классом [Класс воды].

Я надеюсь, что я не лаю не на то дерево .... Если вы можете предоставить немного больше информации о том, что вы ищете, я уверен, что кто-то умнее меня прыгнет;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...