Game Programming Patterns / Паттерны программирования в играх: 1.6. State

← →
Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

В нашем случае это: стоит, прыгает, приседает и ныряет.

MrSmith33 06.05.14 в 17:18

0

Автомат может находиться только в одном из состояний.

MrSmith33 06.05.14 в 17:18

0

Наша героиня не может одновременно стоять и прыгать.

MrSmith33 06.05.14 в 17:19

0

Это одна из причин, по которой мы будем использовать конечные автоматы.

MrSmith33 06.05.14 в 17:20

0

Последовательность вводов или событий посылается автомату.

MrSmith33 06.05.14 в 17:22

0

В нашем случае это простые нажатия и отпускание кнопок.

MrSmith33 06.05.14 в 17:22

0

Каждое состояние имеет набор переходов, каждый из которых связан с соответствующим вводом и указывает на другое состояние.

MrSmith33 06.05.14 в 17:23

0

Если при подаче ввода находится соответствующий переход из текущего состояния, то автомат переходит в него.

MrSmith33 06.05.14 в 17:25

0

Например, при нажатии кнопки "вниз", если мы находимся в стоячем состоянии, происходит переход в состояние приседания.

MrSmith33 06.05.14 в 17:26

0

Когда игрок нажимает "вниз" пока мы в прыжке, происходит переход в нырок.

MrSmith33 06.05.14 в 17:27

0

Если не найдено ни одного перехода по данному вводу, то ввод игнорируется.

MrSmith33 06.05.14 в 17:28

0

По сути, в этом вся соль автоматов: состояния, вводы и переходы.

MrSmith33 06.05.14 в 17:29

0

Можно представить это как диаграмму.

MrSmith33 06.05.14 в 17:29

0

К сожалению компилятор не поймет наши каракули, так что как же мы реализуем это?

MrSmith33 06.05.14 в 17:30

0

Паттерн "Состояние" Банды Четырех - это один из вариантов того, как мы можем поступить, но можно и проще.

MrSmith33 06.05.14 в 17:31

0

Моя любимая аналогия для КА это старые приключенческие игры типа Zork.

MrSmith33 06.05.14 в 17:32

0

Мир состоит из комнат, каждая из которых соединена с другими проходами.

MrSmith33 06.05.14 в 17:33

0

Вы исследуете мир вводя команды, типа "идти на север".

MrSmith33 06.05.14 в 17:34

0

Выглядит прямо, как конечный автомат: каждая комната - это состояние.

MrSmith33 06.05.14 в 17:34

0

Комната в который вы сейчас находитесь - это текущее состояние.

MrSmith33 06.05.14 в 17:35

0

Входы каждой комнаты - это переходы.

MrSmith33 06.05.14 в 17:35

0

Команды перехода - это вводы.

MrSmith33 06.05.14 в 17:36

0

Enum и Switch

MrSmith33 06.05.14 в 17:38

0

Проблема нашей героини в том, что некоторые комбинации флагов не должны существовать. Например: isJumping_ и isDucking_ не должны быть true одновременно.

MrSmith33 06.05.14 в 17:42

0

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

MrSmith33 06.05.14 в 17:43

0

В нашем случае, перечисление идеально подойдет для представления состояний нашего КА и мы определим его так:

MrSmith33 06.05.14 в 17:48

0

enum State

MrSmith33 06.05.14 в 17:48

0

{

MrSmith33 06.05.14 в 17:48

0

STATE_STANDING,

MrSmith33 06.05.14 в 17:48

0

STATE_JUMPING,

MrSmith33 06.05.14 в 17:48

0

STATE_DUCKING,

MrSmith33 06.05.14 в 17:49

0

STATE_DIVING

MrSmith33 06.05.14 в 17:49

0

};

MrSmith33 06.05.14 в 17:49

0

Вместо кучи флагов у героини будет только поле state_.

MrSmith33 06.05.14 в 17:50

0

Также, мы поменяли порядок ветвления.

MrSmith33 06.05.14 в 17:51

0

До этого мы сначала делали проверку ввода, а потом состояния.

MrSmith33 06.05.14 в 17:52

0

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

bubenok 17.05.14 в 05:58

0

Нам необходимо собрать все это вместе, поэтому сначала мы проверим состояние.

bubenok 17.05.14 в 05:59

0

Мы получаем:

bubenok 17.05.14 в 05:59

0

void Heroine::handleInput(Input input)

bubenok 17.05.14 в 05:59

0

{

bubenok 17.05.14 в 06:00

0

switch (state_)

bubenok 17.05.14 в 06:00

0

{

bubenok 17.05.14 в 06:00

0

case STATE_STANDING:

bubenok 17.05.14 в 06:00

0

if (input == PRESS_B)

bubenok 17.05.14 в 06:00

0

{

bubenok 17.05.14 в 06:00

0

state_ = STATE_JUMPING;

bubenok 17.05.14 в 06:00

0

yVelocity_ = JUMP_VELOCITY;

bubenok 17.05.14 в 06:01

0

setGraphics(IMAGE_JUMP)

bubenok 17.05.14 в 06:01

0

;

bubenok 17.05.14 в 06:01

0
Минутку...

← Предыдущая страница

Следующая страница →