Ввод с клавиатуры и мыши
Эта страница объясняет, как считывать ввод с клавиатуры и мыши при создании интерактивного рисунка с помощью DrawZero. Она использует простой язык и много примеров, чтобы вы могли понять каждый шаг.
Зачем нам нужен цикл событий
Программы реального времени должны проверять наличие новых событий много раз в секунду. Вы можете увидеть этот шаблон почти в каждой игре или анимации. Основной цикл выглядит так:
from drawzero import *
while True:
tick() # обновляем анимацию, таймеры, физику
# обрабатываем события # здесь считываем состояние клавиатуры и мыши
tick() — это функция-помощник из DrawZero (см. страницу Основы анимации
). Она продвигает время и собирает новые события ввода. После
каждого вызова tick() вы можете безопасно считывать состояние клавиатуры и мыши, как описано на этой
странице.
Если вы перестанете вызывать tick(), окно зависнет, и новые данные ввода не поступят.
Вот почему вы должны поддерживать работу цикла, даже когда ничего не происходит.
Понимание функций ввода
DrawZero записывает два вида информации:
- Текущее состояние – какие клавиши или кнопки мыши нажаты прямо сейчас.
- Очереди событий – история того, что изменилось за последний кадр.
Функции для получения состояния хороши для непрерывных действий (например, удержание левой стрелки для перемещения спрайта). Очереди событий лучше подходят, когда вам нужны одноразовые действия (например, обнаружение однократного нажатия клавиши для открытия меню).
Все эти функции и списки доступны сразу после импорта from drawzero import *.
Функции для получения снимка состояния
get_keys_pressed()
Возвращает набор строк с именами всех клавиш, которые в данный момент удерживаются нажатыми. Используйте эту функцию, когда вас волнует только то, нажата ли клавиша, а не то, сколько раз она была нажата.
from drawzero import *
# в вашем главном цикле
pressed = get_keys_pressed()
if "LEFT" in pressed:
player_x -= 5
if "SPACE" in pressed:
player_jump()
get_keys_pressed() пересчитывается при каждом вызове, поэтому запрашивайте ее после
tick().
keys_mods_pressed()
Возвращает набор имен модификаторов, таких как "SHIFT", "CTRL" или "ALT". Это
полезно, когда вы хотите поддерживать сочетания клавиш, такие как Ctrl+S.
from drawzero import *
# в вашем главном цикле
if "CTRL" in keys_mods_pressed() and "S" in get_keys_pressed():
save_project()
Модификаторы отделены от обычных клавиш, поэтому вы можете быстро их проверить, не выполняя поиск по всему набору клавиш.
get_mouse_pressed()
Возвращает набор имен кнопок мыши, таких как "LEFT", "MIDDLE" и
"RIGHT". Комбинируйте его с текущим положением мыши.
from drawzero import *
# в вашем главном цикле
if "LEFT" in get_mouse_pressed():
draw_circle(mouse_pos(), radius=10)
Помните: эта функция сообщает только о кнопках, которые удерживаются в последнем кадре. Вам все еще нужны очереди событий, чтобы определить точный момент щелчка.
Очереди событий
Очереди событий — это списки, которые сбрасываются при каждом tick(). Они сохраняют порядок
входящих событий, чтобы вы могли воспроизвести то, что произошло за последний кадр.
Каждый элемент в очереди — это небольшой объект с полями, такими как key, mod, button, pos или rel.
keysdown
Список событий нажатия клавиш. Каждое событие срабатывает, когда клавиша переходит из состояния "отпущена" в "нажата". Используйте его для одиночных нажатий.
from drawzero import *
# в вашем главном цикле
for event in keysdown:
if event.key == "SPACE":
spawn_bullet()
Этот список пуст, если в текущем кадре не было новых нажатий клавиш.
keysup
Список событий отпускания клавиш. Эти события срабатывают, когда клавиша отпускается. Они полезны для переключателей или для прекращения действия именно тогда, когда игрок отпускает клавишу.
from drawzero import *
# в вашем главном цикле
for event in keysup:
if event.key == "LEFT":
stop_moving()
mousemotions
Список событий движения мыши. Каждое событие имеет атрибут pos
с текущим положением курсора в логических (виртуальных) координатах.
from drawzero import *
# в вашем главном цикле
for event in mousemotions:
trail.add_point(event.pos)
mousebuttonsdown
Список событий нажатия кнопок мыши. Они срабатывают, когда пользователь нажимает любую кнопку мыши. События включают имя кнопки и положение мыши.
from drawzero import *
# в вашем главном цикле
for event in mousebuttonsdown:
if event.button == "LEFT":
start_drag(event.pos)
mousebuttonsup
Список событий отпускания кнопок мыши. Они срабатывают, когда пользователь отпускает любую кнопку мыши. Используйте их для завершения действий, таких как рисование линии или подтверждение выбора.
from drawzero import *
# в вашем главном цикле
for event in mousebuttonsup:
if event.button == "LEFT":
end_drag(event.pos)
Собираем все вместе
Вот полный цикл, который использует как функции состояния, так и очереди событий.
from drawzero import *
# player - это вымышленный объект с методами move(), jump() и shoot()
# player = ...
while True:
tick()
# непрерывное движение
pressed = get_keys_pressed()
if "LEFT" in pressed:
player.move(-5, 0)
if "RIGHT" in pressed:
player.move(5, 0)
# одноразовые действия
for event in keysdown:
if event.key == "SPACE":
player.jump()
for event in mousebuttonsdown:
if event.button == "LEFT":
player.shoot(event.pos)
# обновите холст здесь (см. Основы анимации для вызовов рисования)
Вы можете сравнить этот шаблон с примером 16_keyboard_and_mouse.py, указанным
в Обзоре примеров. Этот скрипт также демонстрирует,
как комбинировать ввод с клавиатуры с обратной связью на экране.
Советы по плавному взаимодействию
- Регулярно вызывайте
tick(). Типичная анимация DrawZero работает 30 раз в секунду. - Избегайте длительного блокирующего кода (например,
time.sleep(5)) внутри цикла. - Если вам нужно только последнее положение мыши, используйте функцию
mouse_pos(). - Всегда тестируйте на реальном оборудовании. Тачпады, игровые мыши и клавиатуры с раскладками, отличными от английской, могут отправлять разные имена кнопок. Распечатывайте события во время разработки, чтобы увидеть фактические данные.
- Комбинируйте проверки модификаторов (
keys_mods_pressed()) с обычными клавишами для создания сочетаний клавиш, которые кажутся пользователям естественными.
Где узнать больше
- Основы анимации объясняет, как
tick()вписывается в конвейер рисования. - Обзор примеров указывает на готовые скрипты, которые вы можете запускать и изменять.
С помощью этих инструментов вы можете надежно захватывать события клавиатуры и мыши и создавать отзывчивые, интерактивные сцены в DrawZero.