Тяни или Тяни? Превращение нажатия клавиш в скорость для игровых транспортных средств - PullRequest
4 голосов
/ 28 сентября 2008

Должен ли я нажимать клавиши на транспортных средствах, когда они нажаты, или транспортные средства должны тянуть клавиши нажатыми от двигателя?

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

У меня есть игровой объект, который содержит игровой цикл, который вызывает метод обновления для транспортного средства.

Если игрок управляет транспортным средством с помощью клавиш со стрелками, если при нажатии клавиши задается ускорение (нажатие) и при отпускании клавиши сбрасывается скорость, или если транспортное средство спрашивает игровой движок, нажата ли кнопка ускорения (нажатие) ? Я думаю, что нажатие означало бы, что модуль управления клавиатурой должен был бы знать о транспортных средствах, тогда как нажатие означало бы, что транспортное средство должно знать определенные средства управления клавиатурой.

Я думаю, что связанный с этим вопрос будет выглядеть примерно так: должны ли все объекты знать обо всех других объектах или должна существовать строгая иерархия, чтобы объекты могли задавать вопросы / сообщать вещи другим объектам вверх по дереву, но не вниз (или наоборот)?

Ответы [ 5 ]

8 голосов
/ 28 сентября 2008

Вы должны попытаться следовать шаблону Subscribeing / Observer . Вы помещаете весь код захвата ключа в один singleton InputManager, а затем каждый объект, требующий реакции на ввод, регистрируется в менеджере.

Менеджер хранит список подписанных объектов и отправляет им события при нажатии / нажатии клавиш. Только не забудьте отписаться, когда объект удален или «потерял фокус».

Это позволяет избежать проблемы опроса. Существует очень мало исключений, когда решение для опроса желательно.

2 голосов
/ 29 сентября 2008

IMO, ваш автомобиль не должен ничего знать о клавиатурах, мышах или геймпадах. И ваш код обработки ввода не должен ничего знать о ваших транспортных средствах. Код обработки ввода должен читать ввод для каждого игрока и переводить его в какую-то инструкцию, специфичную для его контекста. Например, если игрок один управляет автомобилем, его инструкция может включать вращение рулевого колеса, ускорение и значения тормозов. В то время как игрок, пилотирующий самолет, может потребовать тангажа, рыскания и т. Д.

Путем перевода ввода геймпада (или чего-либо еще) в соответствующий тип инструкции вы можете отделить механизмы ввода от игровой логики. Одна вещь, которая была бы возможна с этим уровнем разъединения, состояла бы в том, чтобы создать "CarInstruction" из сетевого ввода.

1 голос
/ 02 октября 2008

Вы хотите опросить:

void UpdateVehicleFromInput()
{
   if (InputSystem()->IsKeyDown(key))
      DoSomething();
}

И это, конечно, «где-то в вашем цикле обновления, где это уместно для вашего дизайна». Если вы хотите назвать это конкретное место «частью вашей системы ввода» или «частью вашей игровой логики» или что-то еще, стукните себя вне.

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

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

Вопреки иррациональному распространенному мнению, нет никаких недостатков в опросе. Процессоры делают> 1B вещей в секунду, один ЕСЛИ кадр не имеет значения (в основном единственные соответствующие операции ЦП - это N ^ 2, где N> 100, и вы перегружаете ваш кэш второго уровня и, конечно, заняты ожиданием доступа к диску). Вход опроса O (1).

1 голос
/ 29 сентября 2008

@ Джоэл: Я согласен - транспортные средства не должны знать о конкретных элементах управления оборудованием, а код обработки ввода не должен ничего знать о транспортных средствах. Должен быть некоторый промежуточный класс, который отображает ключи от транспортных средств. Спасибо за вклад!

1 голос
/ 28 сентября 2008

Ответить на этот вопрос сложно без более глубоких знаний о том, как работает ваш игровой движок. Это сказанное, я сделаю удар в это. Подход «нажатия клавиш» читается как стратегия «события» или «обратного вызова». Вы определяете функцию где-то, которая выглядит как def handle_key_event(name_of_key):, которая вызывается всякий раз, когда происходит ключевое событие Преимущество этого в том, что с точки зрения читабельности вы точно знаете, где обрабатываются ключевые события. С другой стороны, каждое нажатие клавиши должно рассматриваться как атомарная операция. Если вам нужно хранить множество переменных состояния для состояния других клавиш, чтобы определить, что делать при каждом нажатии, это может стать немного запутанным.

С другой стороны, если вы нажимаете клавишу, вы вводите задержку при нажатии клавиши. Вы не будете ловить ключевые события быстрее, чем ваш тикрейт / частота кадров. Это хорошо, если ваша игра тикает красиво и быстро, но вы не хотите, чтобы пользовательский интерфейс становился все более скачкообразным или медленным, когда ваша частота кадров замедляется.

Наверное, просто пища для размышлений. Прежде всего, выберите стратегию и придерживайтесь ее. Если события клавиатуры являются обратным вызовом, не используйте, например, подход «тянуть» для событий мыши. Согласованность здесь важнее, чем правильность ИМО.

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