[Лог #7] Класс рисовальщика.

Темой этого лога станет рендер. Расскажу немного о том как я себе представляю виртуального художника и почему лучше реализовать интерфейс IRender и класс-реализацию CRenderOGL, наример.
80 28 875
15
Вот помню как-то спрашивал на gamedev.ru про компонентную систему объектов ( хотя вопрос был в другом, но немного и этот задели ). И был у меня такой пример - планируется игры типа Twisted Metal какой-нибудь (гонки на выживание). Как будет выглядеть класс-объявление машины и взрывной бочки и их "взаимоотношение"(столкновение, например ).
Имхо, дробление игрового объекта - спорная вещь, ведь можно так разделить, что аж жуть и вместо тройки классов будет 100500. Возможно сможете меня переубедить ? )
29
Kozinaka, дык да, я знаю что такое MVC, просто практика построения MVC архитектуры еще не очень прокачена
14
модель ничего не должна знать о контроллере и о вьюхе, контроллер ничего не знает о вьюхе, он только управляет данными в модели, ну а вьюха сама берет модель и по данным из нее уже рисует объект
Ага! То, что доктор прописал: ru.wikipedia.org/wiki/Model-View-Controller
prog, согласен. Но я даже не стал выбирать между способами реализации связи модели и представления, а просто отказался от отдельных объектов представления и в жирном отрисовщике жестко распределяю кого как рисовать. Дёшево и сердито. :)
24
Kozinaka, если гнаться за производительностью и позволяет архитектура, то можно вобще параллельные списки/массивы использовать. Впрочем, архитектура позволяет далеко не всегда, особенно если логическому объекту может и не быть назначено графического объекта (объект полностью невидим или, например, его графика выгружена т.к. объект очень далеко от камеры, но просчитывать его еще нужно), а хуже всего когда у обьекта то есть вьюха, то нет её.
29
Kozinaka, кст, я немного разобрался с мыслями. Model - хранит данные игрового объекта, Controller - реакция на различные события, ну а View - соответсвенно отрисовка. Соответсвенно сама модель ничего не должна знать о контроллере и о вьюхе, контроллер ничего не знает о вьюхе, он только управляет данными в модели, ну а вьюха сама берет модель и по данным из нее уже рисует объект
14
alexprey, ага, понял. Ты как хранилку его и задумывал. Меня абстрактность сбила. Самое интересное как раз в том, как его собрать - как сопоставить модели с остальными потрохами, если они динамически появляются и исчезают в процессе игры.
>Хотя на самом деле я считаю, что модель и вьюха этого игрового объекта не разделима.
Гради Буч смотрит на тебя с укором. :)
29
Kozinaka, нее, не понимаешь, AGameObject сам ничего не умеет делать, он просто хранит данные, на самом деле его можно и не делать абстрактным. А в основном цикле уже можно будет пробегаться, смотреть что объект умеет делать и передавать управление уже в эти контроллеры. Как видишь тут как раз таки логика полностью разделена. Хочешь повесил отрисовку червя, хочешь повесил отрисовку жука, хочешь поставил управление клавиатурой, хочешь мышью, хочешь повесил ИИ. В общем то вот. Хотя на самом деле я считаю, что модель и вьюха этого игрового объекта не разделима. Управление, физика, ИИ это да, можно навешивать из-вне уже
14
alexprey, потому что это перемешивание логики и представления. Разнос этого всего по интерфейсам делает перемешивание ещё более явным, AGameObject говорит нам прямым текстом: я и модель, и отрисовщик, и даже пользовательский ввод разбирать умею! Плевал я на вашу инкапсуляцию с четвёртого этажа. :)
...впрочем что-то такое вполне можно использовать в качестве сборной хранилки данных об объекте из разных мест. Т.е. после того, как мы сопоставили модель и её отрисовщик, можно положить это всё в подобную структурку. Но, конечно, не абстрактную, без публичных сеттеров и без разбора объектом конкретных нажатых кнопок клавиатуры - этим должен заниматься кто-то другой.
Map во внешнем менеджере. Это более ресурсоемкий вариант, зато позволяет полностью абстрагировать логику от представления.
Боюсь, при отрисовке придётся шерстить этот несчастный map'а для получения каждого объекта. Линейный рост трудоёмкости с увеличением количества объектов умножается на логарифмический рост сложности выборки из map'а. Я бы предпочёл за это не платить вовсе, сопоставив модель и представление только один раз при создании представления.
29
Почитал, подумал о вашей логике разделения и пришел вот к такой вот мысли, а почему бы не сделать вот так?
public interface IDrawer {
    // Методы для рисования
}
// Этот интерфейс отвечает за отрисовку объекта
public interface IObjectView {
    public void Draw(IDrawer drawer);
}
// Этот интерфейс отвечает за игровую логику объекта
public interface IObjectModel {
    public void OnTick(float dt);
    // Другие различные события игрового мира
}
// Этот интерфейс отвечает за обработку пользовательского ввода для заданного объекта
public interface IObjectController {
    public void OnKeyPress(char keyCode);
    // Другие события пользовательского ввода
}
// Этот класс представляет собой игровой объект с тремя сущностями, отвечающими за рендер, логику и управление этим объектом
public abstract class AGameObject {
    public IDataStorage Data { get; set; } // Область для хранения данных игрового объекта, которая должна быть общая между компонентами
    public IObjectView View { get; set; }
    public IObjectModel Model { get; set; }
    public IObjectController Controller { get; set; }
    // Другие сущности игрового объекта, например сущность физики
}
public interface IDataStorage {
    public object Get(string key);
    public void Set(string key, object value);
}
// А тут типа универсальная такая штука для базовых объектов
public static class GameObjectDataStorageExtension {
    public static T Get<T>(this IDataStorage storage, string key) {
        return (T)storage.Get(key);
    }
    public static void Set<T>(this IDataStorage storage, string key, T value) {
        storage.Set(key, value);
    }
    public static float GetX(this IDataStorage storage) {
        return storage.Get<float>("position.X");
    }
    public static float GetY(this IDataStorage storage) {
        return storage.Get<float>("position.Y");
    }
    // и т.д.
}
24
Kozinaka, более того, бывает достаточно создать не прямую ссылку от объекта логики к объекту отрисовки, а связать их, например, через какой-нибудь Map во внешнем менеджере. Это более ресурсоемкий вариант, зато позволяет полностью абстрагировать логику от представления.