Можно ли избежать приведения в этом сценарии? - PullRequest
0 голосов
/ 23 февраля 2020

Я пытаюсь внедрить систему Status Effect в моей игре. Я буду называть Status Effect SE, чтобы держать его коротким.

Основное внимание в игре уделяется системе magi c, и, конечно же, SE должен применяться к врагам, которых вы поражаете определенными заклинаниями. , Присутствуют обычные вещи, такие как Slow, Stun, Snare и др. c, но должны быть специальные SE с уникальными взаимодействиями (например, «Замораживание врага, когда он замедлен ниже порогового процента», запуск взрывов, когда вы поражаете противника огненным заклинанием и другие сумасшедшие вещи, которые вы можете себе представить).

Поскольку некоторые типы SE (например, медленные) требуют знания всех других SE этого типа для правильного применения эффекта на движение актера, SE применяются к IManager. Конкретные примеры использования IManager: SE применяют декораторы к определенному компоненту актера, и когда один эффект заканчивается, вещи должны быть восстановлены и применены повторно, чтобы избежать ошибок. Увеличение и понижение скорости движения применяются следующим образом: сначала происходит плоский ход, затем - процент, а процент - накапливается (замедление 10% сейчас + замедление 10% позже приводит к общему замедлению на 20%, если оба SE активны)

В коде интерфейсы выглядят так:

public interface IReceiveStatusEffect
{
    Dictionary<string, IStatusManager> StatusManagers { get; set; } //ID of the effect and the Manager for that Effect
    void ReceiveEffect(IStatusEffect effect);
}

public interface IStatusEffect
{
    IStatusManager Manager { get; set; }
    GameObject Target { get; set; }
    float Duration { get; set; }
    string ID { get; } //The ID is Used on concrete implementations to get the SpellManager from IReceiveStatusEffect
    void ApplyEffect();
    void RemoveEffect();
}
public interface IStatusManager
{
    List<IStatusEffect> AllEffects { get; set; }
    void ProcessEffects(); // Called when an Effect is removed and some things needs to be recalculated. Sometimes call Apply again from the remaining AllEffects
}

Актор, который может получить SE, должен иметь IReceiveStatusEffect, поэтому поток выглядит так:

ConcreteStatusEffect status = new ConcreteStatusEffect(target, duration, IReceiveStatusEffect.StatusManagers);
// Constructor gets the correct manager from StatusManagers or create it if there's none
IReceiveStatusEffect.ReceiveEffect(status)//ReceiveEffect calls status.ApplyEffect()

Со всем (более) объясненным, вот проблема, с которой я сталкиваюсь: поскольку SE довольно разнообразны, для некоторых потребуется знание конкретных реализаций чего-либо (например, конкретных реализаций IStatusManager), как пример Slow SE, который я привел ранее. Я пробовал просто кастовать, и это сработало, но почти везде я смотрю, все говорят, что кастинга нужно избегать любой ценой; Что если вам нужно сыграть, возможно, там плохой дизайн; Этот кастинг является анти-паттерном, и т. Д. c

Но я просто не представляю, как я могу получить нужную информацию прямо сейчас, без кастинга. Я думал и думал, но этот поток кажется лучшим (если не для кастинга) для того, что мне нужно в данный момент, и не могу придумать другой шаблон проектирования для этой проблемы, поэтому я пытаюсь найти решение, которое делает не используйте отливки, так как кажется, что они собраны.

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