Паттерны программирования игр
— Другой взгляд на паттерны проектирования
123
isJumping_
и
isDucking_
никогда не должны при-
нимать значение
true
одновременно. Если у вас есть
небольшой набор флагов, где только один может при-
нимать значение
true
в момент времени, то это под-
сказка: надо использовать
enum
(перечисление).
В этом случае
enum
представляет собой набор состоя-
ний нашего конечного автомата. Давайте определим его
так:
enum State
{
STATE_STANDING,
STATE_JUMPING,
STATE_DUCKING,
STATE_DIVING
};
Вместо кучи флагов у
Heroine
будет единое поле
state_
. Мы также слегка изменим порядок ветвления.
В предыдущем фрагменте кода мы сначала учитывали
ввод, а уже
затем
состояние. При этом код был разде-
лен на блоки с учетом нажимаемых кнопок, одно состоя-
ние могло быть разделено по нескольким таким блокам.
Теперь мы хотим сделать наоборот, поэтому будем сна-
чала учитывать текущее состояние. Вот что получается:
void Heroine::handleInput(Input input)
{
switch (state_)
{
case STATE_STANDING:
if (input == PRESS_B)
{
state_ = STATE_JUMPING;
yVelocity_ = JUMP_VELOCITY;
setGraphics(IMAGE_JUMP);
}
else if (input == PRESS_DOWN)
{
state_ = STATE_DUCKING;
setGraphics(IMAGE_DUCK);
}
124
Состояние (State) —
Паттерны программирования игр
break;
// …
}
}
Мы можем использовать другие состояния следую-
щим образом:
void Heroine::handleInput(Input input)
{
switch (state_)
{
// q " "…
case STATE_JUMPING:
if (input == PRESS_DOWN)
{
state_ = STATE_DIVING;
setGraphics(IMAGE_DIVE);
}
break;
case STATE_DUCKING:
if (input == RELEASE_DOWN)
{
state_ = STATE_STANDING;
setGraphics(IMAGE_STAND);
}
break;
}
}
Решение кажется очень простым, но на самом деле
оно намного лучше, чем в предыдущем примере. У нас
все еще есть условное ветвление, но мы упростили из-
меняемое состояние до единого поля. Весь код, отве-
чающий за обработку состояния, сейчас удачно сгруп-
пирован в одном месте. Это самый простой способ
реализовать конечный автомат, и в принципе его впол-
не достаточно для решения многих задач.
Хотя ваша задача может выходить за рамки этого
решения. Скажем, мы хотим добавить нашей героине
способность прижиматься к земле на некоторое время,
В частности, героиня
сейчас не может нахо-
диться в
недопустимом
состоянии. При исполь-
зовании флагов логиче-
ского типа комбинация
некоторых значений
была возможна, но абсо-
лютно не имела смысла.
При использовании
enum
все допустимые
комбинации корректны.
Do'stlaringiz bilan baham: |