Как избежать циклических ссылок компонента рендеринга игры? - PullRequest
0 голосов
/ 12 мая 2010

Я работаю над простым игровым дизайном, и я хотел разбить свои игровые объекты на более повторно используемые компоненты. Но я застрял на том, как именно реализовать дизайн, который я имею в виду. Вот пример:

У меня есть объект Logger, задача которого просто хранить список сообщений и отображать их на экране. Вы знаете, ведение журнала. Первоначально Logger просто содержал список, а игровой цикл отображал его содержимое. Затем я переместил логику рендеринга в метод Logger.Draw (), и теперь я хочу переместить ее дальше в объект LoggerRenderer.

По сути, я хочу, чтобы игровой цикл вызывал RenderAll, который затем будет вызывать Logger.Render, который, в свою очередь, вызовет LoggerRenderer.Render и, наконец, выведет текст. Таким образом, Logger должен содержать объект Renderer, но для визуализации Renderer необходим доступ к состоянию Logger (очереди сообщений).

Как мне решить это? Должен ли я передавать в очередь сообщений и другую информацию о состоянии явно в метод Render? Или игровой цикл должен вызывать Renderer напрямую и он связывается с логгером, но метод RenderAll фактически никогда не видит сам объект логгера?

Это похоже на шаблон командования, но я ужасно испортил его.

Ответы [ 3 ]

2 голосов
/ 12 мая 2010

Или игровой цикл должен вызывать Renderer напрямую и он связывается с логгером, но метод RenderAll фактически никогда не видит сам объект логгера?

Этот.

1 голос
/ 13 мая 2010

Каждый раз, когда у вас есть один объект, которому требуется доступ к внутренним объектам другого объекта, вы должны учитывать, что код пахнет Feature Envy . Не делай этого.

Если вам действительно нужен LogRenderer, пусть он просто отображает одно сообщение за раз, и пусть ваш Log вызывает его при необходимости.

например. В журнале написано «для каждого сообщения renderer-> RenderMessage (message)».

Предполагается, что журналу принадлежит LogRenderer. Если у вас есть какая-то другая архитектура, вам, возможно, придется немного перемешать некоторые вещи, но постарайтесь свести к минимуму Feature Envy.

0 голосов
/ 12 мая 2010

Вот как бы я это сделал

class Logger {
    List<Message> messages;
    Message[] getMostRecent(int numMostRecent) { ... }
}

class MyGame {
    void draw() {
        // all my ui stuff
        Message[] messagesToRender = myLogger.getMostRecent(numRowsInLogWindow);
        String formattedMessages = magicalFormattingIfNecessary(messagesToRender);
        logWindow.setText(formattedMessages);
    }
}

Разделение объектов - это хорошо, но для чего-то простого, такого как журнал сообщений, вам будет лучше сохранить его простым и понятным. Я наблюдал за разработкой десятков игр, и большинство проблем были из-за чрезмерного усложнения его дизайна.

Если вы хотите создать объект MessageFormatter, вы можете сделать это, но только если у вас есть несколько форматов, которые вам нужно приспособить.

Примечание. Да, мой псевдокод действительно написан на Java. Адаптируйте по необходимости =)

...