---
key: lesson/state-machines
type: lesson
id: state-machines
lang: ru
title: Состояния и переходы
summary: >-
  Описываем допустимые состояния персонажа, приоритет событий и проверяем
  переходы без хаоса из флагов.
updatedAt: '2026-10-20'
status: active
url: 'https://gamemechanics.pro/ru/lessons/state-machines/'
jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/lesson/state-machines.json'
markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/lesson/state-machines.md'
aliases: []
tags:
  - state-machines
  - architecture
  - testing
sourceIds:
  - source-3817d420df0baa92
sources:
  - id: source-3817d420df0baa92
    title: 'Robert Nystrom: State (author repository)'
    url: >-
      https://github.com/munificent/game-programming-patterns/blob/master/book/state.markdown
    verifiedAt: null
relations:
  - type: requires
    direction: outgoing
    label: Перед началом
    key: lesson/input-and-feedback
    title: Ввод и обратная связь
    url: 'https://gamemechanics.pro/ru/lessons/input-and-feedback/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/ru/lesson/input-and-feedback.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/ru/lesson/input-and-feedback.md
  - type: requires
    direction: incoming
    label: Продолжить изучение
    key: lesson/agent-workflow
    title: Разработка игры с ИИ-агентом
    url: 'https://gamemechanics.pro/ru/lessons/agent-workflow/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/lesson/agent-workflow.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/lesson/agent-workflow.md'
  - type: requires
    direction: incoming
    label: Продолжить изучение
    key: lesson/npc-perception
    title: Восприятие NPC и память о цели
    url: 'https://gamemechanics.pro/ru/lessons/npc-perception/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/lesson/npc-perception.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/lesson/npc-perception.md'
  - type: requires
    direction: incoming
    label: Продолжить изучение
    key: lesson/gameplay-acceptance
    title: Проверка игрового поведения
    url: 'https://gamemechanics.pro/ru/lessons/gameplay-acceptance/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/ru/lesson/gameplay-acceptance.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/ru/lesson/gameplay-acceptance.md
  - type: explains
    direction: outgoing
    label: Применение принципа
    key: mechanic/boss-fight-atlas--boss-wind-up
    title: Подготовка
    url: >-
      https://gamemechanics.pro/ru/knowledge/mechanic/boss-fight-atlas--boss-wind-up/
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/ru/mechanic/boss-fight-atlas--boss-wind-up.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/ru/mechanic/boss-fight-atlas--boss-wind-up.md
  - type: related
    direction: incoming
    label: Связанные материалы
    key: lesson/gameplay-acceptance
    title: Проверка игрового поведения
    url: 'https://gamemechanics.pro/ru/lessons/gameplay-acceptance/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/ru/lesson/gameplay-acceptance.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/ru/lesson/gameplay-acceptance.md
  - type: related
    direction: incoming
    label: Связанные материалы
    key: lesson/npc-perception
    title: Восприятие NPC и память о цели
    url: 'https://gamemechanics.pro/ru/lessons/npc-perception/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/lesson/npc-perception.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/lesson/npc-perception.md'
  - type: contains
    direction: incoming
    label: Учебные маршруты
    key: path/first-prototype
    title: Первый проверяемый прототип
    url: 'https://gamemechanics.pro/ru/learn/first-prototype/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/path/first-prototype.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/path/first-prototype.md'
  - type: requires
    direction: incoming
    label: Продолжить изучение
    key: path/npc-behavior
    title: Поведение NPC
    url: 'https://gamemechanics.pro/ru/learn/npc-behavior/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/path/npc-behavior.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/path/npc-behavior.md'
  - type: requires
    direction: incoming
    label: Продолжить изучение
    key: path/game-verification
    title: Проверка игры
    url: 'https://gamemechanics.pro/ru/learn/game-verification/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/path/game-verification.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/path/game-verification.md'
  - type: uses
    direction: outgoing
    label: Источники в подборке
    key: resource/state-pattern
    title: 'Состояния: Game Programming Patterns'
    url: 'https://gamemechanics.pro/ru/resources/#resource-state-pattern'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/ru/resource/state-pattern.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/ru/resource/state-pattern.md'
placements: []
supersededBy: []
attributes:
  category: foundations
  level: beginner
  minutes: 6
endsAt: null
provenance: >-
  Авторский материал gamemechanics.pro. Учебные примеры требуют проверки в своём
  проекте.
license: CC-BY-4.0
codeLicense: MIT
attribution: gamemechanics.pro contributors
---
# Состояния и переходы

id: state-machines
type: lesson
key: lesson/state-machines
lang: ru
status: active
url: https://gamemechanics.pro/ru/lessons/state-machines/

Описываем допустимые состояния персонажа, приоритет событий и проверяем переходы без хаоса из флагов.

## Что нужно знать

Нужны условия, функции и простые перечисления. Для упражнения достаточно персонажа, который ходит, выполняет рывок и погибает. Результат урока: таблица переходов, из которой видно, какое поведение разрешено в каждый момент.

## Принцип

Набор флагов `isDashing`, `isDead`, `canMove` легко допускает противоречия. Конечный автомат хранит одно состояние выбранной системы и меняет его по явно заданным событиям. Переход может иметь условие допуска, а вход и выход могут выполнять разовые действия. Основа подхода разобрана автором Game Programming Patterns в [главе State](https://github.com/munificent/game-programming-patterns/blob/master/book/state.markdown).

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

<span id="пример-короткий-рывок"></span>

## Практический пример

### Короткий рывок

Предположим, рывок длится 0,18 секунды, а смерть немедленно его прерывает. Это параметры учебного примера, которые нужно подобрать для своей игры.

| Текущее состояние | Событие и условие            | Следующее состояние       |
| ----------------- | ---------------------------- | ------------------------- |
| ready             | dashPressed и заряд доступен | dashing                   |
| dashing           | время рывка истекло          | ready                     |
| ready или dashing | здоровье стало нулевым       | dead                      |
| dead              | restart                      | ready после сброса данных |

```text
update(dt, events):
    if state == dead and events.restart:
        resetCharacterData()
        transitionTo(ready)
        return
    if health <= 0:
        transitionTo(dead)
        return
    if state == ready and events.dashPressed and chargeReady:
        transitionTo(dashing)
    else if state == dashing:
        dashRemaining -= dt
        if dashRemaining <= 0:
            transitionTo(ready)
```

Функция `transitionTo` ничего не делает, если новое состояние равно текущему. При настоящем переходе она вызывает выход, меняет состояние, затем выполняет вход. Заряд списывается при входе в `dashing`, а не на каждом кадре. Направление рывка можно зафиксировать тогда же.

Обратите внимание на порядок. Проверка смерти выполняется первой и завершает обновление. Это делает ответ на одновременные события определённым. Другой игре может требоваться другой приоритет, но его необходимо записать.

## Частые ошибки

Анимация не должна случайно воскрешать персонажа, отправляя запоздалое событие завершения рывка. Принимайте событие только в подходящем состоянии; для отложенных callback (функций, вызываемых после события) полезно также проверять идентификатор действия.

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

При рестарте недостаточно присвоить `ready`: нужно восстановить здоровье, заряд, таймеры и подписки. Составьте явный список сбрасываемых данных и проверьте его вторым запуском сцены.

## Проверка результата

- Один запрос рывка расходует ровно один заряд.
- Смерть прерывает рывок и запрещает новые действия.
- Позднее событие анимации не меняет состояние погибшего персонажа.
- Каждая строка таблицы проверяется отдельно.
- Недопустимые события имеют определённый результат: игнорирование или диагностическое сообщение.
- Рестарт возвращает полный начальный набор данных.

## Задание для ИИ-агента

> Найди флаги, управляющие рывком и смертью. Сначала составь таблицу допустимых переходов и приоритет одновременных событий. Затем предложи небольшой автомат без общего фреймворка. Проверь двойное нажатие, смерть в середине рывка, запоздалый callback и повторный старт. Объясни, какие данные автомат хранит отдельно от состояния.

## Связанные материалы

- Перед началом: [Ввод и обратная связь](https://gamemechanics.pro/ru/lessons/input-and-feedback/) (key: lesson/input-and-feedback)
- Продолжить изучение: [Разработка игры с ИИ-агентом](https://gamemechanics.pro/ru/lessons/agent-workflow/) (key: lesson/agent-workflow)
- Продолжить изучение: [Восприятие NPC и память о цели](https://gamemechanics.pro/ru/lessons/npc-perception/) (key: lesson/npc-perception)
- Продолжить изучение: [Проверка игрового поведения](https://gamemechanics.pro/ru/lessons/gameplay-acceptance/) (key: lesson/gameplay-acceptance)
- Применение принципа: [Подготовка](https://gamemechanics.pro/ru/knowledge/mechanic/boss-fight-atlas--boss-wind-up/) (key: mechanic/boss-fight-atlas--boss-wind-up)
- Связанные материалы: [Проверка игрового поведения](https://gamemechanics.pro/ru/lessons/gameplay-acceptance/) (key: lesson/gameplay-acceptance)
- Связанные материалы: [Восприятие NPC и память о цели](https://gamemechanics.pro/ru/lessons/npc-perception/) (key: lesson/npc-perception)
- Учебные маршруты: [Первый проверяемый прототип](https://gamemechanics.pro/ru/learn/first-prototype/) (key: path/first-prototype)
- Продолжить изучение: [Поведение NPC](https://gamemechanics.pro/ru/learn/npc-behavior/) (key: path/npc-behavior)
- Продолжить изучение: [Проверка игры](https://gamemechanics.pro/ru/learn/game-verification/) (key: path/game-verification)
- Источники в подборке: [Состояния: Game Programming Patterns](https://gamemechanics.pro/ru/resources/#resource-state-pattern) (key: resource/state-pattern)

## Источники и происхождение

Авторский материал gamemechanics.pro. Учебные примеры требуют проверки в своём проекте.

- [Robert Nystrom: State (author repository)](https://github.com/munificent/game-programming-patterns/blob/master/book/state.markdown) (id: source-3817d420df0baa92)

CC-BY-4.0 · gamemechanics.pro contributors
