---
id: input-and-feedback
lang: ru
title: Ввод и обратная связь
description: >-
  Превращаем нажатия в игровые намерения и показываем игроку, какое действие
  принято, отклонено или выполнено.
category: foundations
level: beginner
minutes: 6
updatedAt: '2026-10-20'
tags:
  - input
  - feedback
  - accessibility
sources:
  - title: 'Godot: Using InputEvent'
    url: 'https://docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html'
url: 'https://gamemechanics.pro/ru/lessons/input-and-feedback/'
markdownUrl: 'https://gamemechanics.pro/content/ru/input-and-feedback.md'
license: CC-BY-4.0
codeLicense: MIT
attribution: gamemechanics.pro contributors
---

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

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

## Принцип

Разделите физический сигнал, игровое намерение и результат. Клавиша E или кнопка геймпада порождает `interact`. Игровая логика решает, можно ли открыть дверь. Интерфейс сообщает, что произошло. Такой путь проще проверять, чем обработчик клавиши, который сразу двигает дверь, воспроизводит звук и меняет инвентарь.

Система действий позволяет назначать несколько устройств на одно намерение. В Godot эту роль выполняет InputMap; порядок обработки событий также позволяет интерфейсу перехватывать ввод до игрового мира. См. [Using InputEvent](https://docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html).

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

<span id="пример-закрытая-дверь"></span>

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

### Закрытая дверь

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

```text
tryInteract(player, door):
    if distance(player, door) > interactRange:
        return outOfRange
    if door.locked and not player.hasKey:
        return needsKey
    door.open = true
    return opened

onActionPressed(interact):
    result = tryInteract(player, selectedDoor)
    presentInteractionResult(result)
```

В учебной сцене разместите две двери: одну рядом, вторую вне радиуса. Сначала проверьте принятие намерения без эффектов, затем добавьте короткую подпись причины отказа. Не запускайте анимацию успешного открытия до решения игровой логики.

Если в сцене несколько дверей, явно определите выбор цели: ближайшая доступная, объект под прицелом или выделенный объект. Покажите выбранную дверь до нажатия. Это помогает отличить ошибку выбора цели от ошибки проверки ключа.

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

Один и тот же ввод не должен одновременно нажимать кнопку меню и стрелять в мире. Закрытие окна не должно оставлять движение навсегда включённым. При потере фокуса предусмотрите очистку удерживаемых действий: событие отпускания может прийти не туда, где его ожидают.

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

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

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

- Клавиатура и геймпад вызывают одно игровое действие.
- Удержание кнопки не повторяет одиночное действие каждый кадр.
- Меню получает ввод без одновременного действия в мире.
- После потери и возврата фокуса движение не застревает.
- Причина отказа понятна без различения цвета и без звука.
- Выбранная цель видна до подтверждения.

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

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