pygame event get что это
События клавиатуры
Человек может управлять объектами в игре в основном с помощь клавиатуры, мыши, джойстика. Когда на «манипуляторах» что-то двигается или нажимается, то возникают события определенных типов. Обработкой событий занимается модуль pygame.event, который включает ряд функций, наиболее важная из которых уже ранее рассмотренная pygame.event.get(), которая забирает из очереди произошедшие события.
В pygame, когда фиксируется то или иное событие, создается соответствующий ему объект от класса Event. Уже с этими объектами работает программа. Экземпляры данного класса имеют только свойства, у них нет методов. У всех экземпляров есть свойство type. Набор остальных свойств события зависит от значения type.
События клавиатуры могут быть двух типов (иметь одно из двух значений type) – клавиша была нажата, клавиша была отпущена. Если вы нажали клавишу и отпустили, то в очередь событий будут записаны оба. Какое из них обрабатывать, зависит от контекста игры. Если вы зажали клавишу и не отпускаете ее, то в очередь записывается только один вариант – клавиша нажата.
Событию типа «клавиша нажата» в поле type записывается числовое значение, совпадающее со значением константы pygame.KEYDOWN. Событию типа «клавиша отпущена» в поле type записывается значение, совпадающее со значением константы pygame.KEYUP.
У обоих типов событий клавиатуры есть атрибуты key и mod. В key записывается конкретная клавиша, которая была нажата или отжата. В mod – клавиши-модификаторы (Shift, Ctrl и др.), которые были зажаты в момент нажатия или отжатия обычной клавиши. У событий KEYDOWN также есть поле unicode, куда записывается символ нажатой клавиши (тип данных str).
Рассмотрим, как это работает. Пусть в центре окна имеется круг, который можно двигать по горизонтали клавишами стрелок клавиатуры:
В цикле обработки событий теперь проверяется не только событие выхода, но также нажатие клавиш. Сначала необходимо проверить тип, потому что не у всех событий есть атрибут key. Если сразу начать проверять key, то сгенерируется ошибка по той причине, что могло произойти множество событий. Например, движение мыши, у которого нет поля key. Соответственно, попытка взять значение из несуществующего поля (i.key) приведет к генерации исключения.
Часто проверку и типа и клавиши записывают в одно логическое выражение ( i. type == pygame. KEYDOWN and i. key == pygame. K_LEFT ). В Python так можно делать потому, что если первая часть сложного выражения возвращает ложь, то вторая часть уже не проверяется.
Если какая-либо клавиша была нажата, то проверяется, какая именно. В данном случае обрабатываются только две клавиши. В зависимости от этого меняется значение координаты x.
Проблема данного кода в том, что при выполнении программы, чтобы круг двигался, надо постоянно нажимать и отжимать клавиши. Если просто зажать их на длительный период, то объект не будет постоянно двигаться. Он сместиться только одноразово на 3 пикселя.
Так происходит потому, что событие нажатия на клавишу происходит один раз, сколь долго бы ее не держали. Это событие было забрано из очереди функцией get() и обработано. Его больше нет. Поэтому приходится генерировать новое событие, еще раз нажимая на клавишу.
Как быть, если по логике вещей надо, чтобы шар двигался до тех пор, пока клавиша зажата? Когда же она отпускается, шар должен останавливаться. Первое, что надо сделать, – это перенести изменение координаты x в основную ветку главного цикла while. В таком случае на каждой его итерации координата будет меняться, а значит шар двигаться постоянно.
Во-вторых, в цикле обработки событий нам придется следить не только за нажатием клавиши, но и ее отжатием. Когда клавиша нажимается, какая-либо переменная, играющая роль флага, должна принимать одно значение, когда клавиша отпускается эта же переменная должна принимать другое значение.
В основном теле while надо проверять значение этой переменной и в зависимости от него менять или не менять значение координаты.
На самом деле существует способ по-проще. В библиотеке pygame с событиями работает не только модуль event. Так модуль pygame.key включает функции, связанные исключительно с клавиатурой. Здесь есть функция pygame.key.get_pressed(), которая возвращает кортеж двоичных значений. Индекс каждого значения соответствует своей клавиатурной константе. Само значение равно 1, если клавиша нажата, и 0 – если не нажата.
Эта функция подходит не для всех случаев обработки клавиатурных событий, но в нашем подойдет. Поэтому мы можем упростить код до такого варианта:
Можно сказать, вызов get_pressed() снимает «маску» зажатых клавиш. Мы ее снимаем на каждой итерации главного цикла. Это даже не регистрация событий как таковых.
Выражение типа keys[pygame.K_LEFT] извлекает значение из кортежа по индексу, значение которого записано в константе K_LEFT. Если извлеченное значение True, то координата меняется.
Если необходимо, чтобы событие обрабатывалось при нажатии двух и более клавиш, то работает такое логическое выражение: keys [ pygame. K_LEFT ] and keys [ pygame. K_a ] (одновременное нажатие стрелки ‘влево’ и буквы ‘a’). Однако если нужно задействовать не обычные клавиши, а модификаторы, то данный номер не проходит.
В таком случае можно вернуться к первому варианту – перебирать события в цикле for:
Здесь при if будет True, если перед нажатием стрелки был зажат левый Shift. Причем обратная последовательность: сначала зажать стрелку, потом Shift не сработает. Видимо модификаторы обрабатываются библиотекой pygame несколько отлично от обычных клавиш. Допустим, если при зажатии обычных клавиш генерируется только одно событие, то для модификаторов они генерируются постоянно или хранятся до отпускания в другой очереди.
Таким образом, если первым зажимается K_LEFT, то событие сразу обрабатывается. При этом в i.mod записывается отсутствие модификатора. Поэтому условие не срабатывает.
Если же первым зажимается модификатор, то это событие не теряется и позволяет условию при if выполнится в случае нажатия при этом обычной клавиши.
Весь перечень констант pygame, соответствующих клавишам клавиатуры, смотрите в документации: https://www.pygame.org/docs/ref/key.html
Практическая работа
Измените приведенную в уроке программу так, чтобы круг с той же скоростью, т. е. постепенно, возвращался назад в исходную точку, когда клавиша отпускается.
Шапошникова С. (plustilino) © 2020
Pygame. Введение в разработку игр на Python
PyGame Основы часть 3. Анимация и события
В этой статье мы разберём как происходит анимация в PyGame и также не много затроним работу с события ми в библиотеки.
Также перед прочтением этой стать, рекомендую прочитать предыдущие, чтобы лучше понимать здесь написанное:
Как сделать анимацию в PyGame:
Для начала, чтобы всё наиболее наглядно показать, сделаем несколько переменных, вот они:
Как вы видите, в начале мы сделали переменные для назначения позиции по осям X и Y, потом назначили скорость при которой будет у нас перемешаться объект.
Также назначили ширину и высоту окна, это для удобства, так как он нам ещё пригодиться, создали окно и назначили таймер, он нам пригодиться для назначения FPS.
Вот основной код программы:
Как видите в начале мы назначаем FPS, потом весь экран заливаем чёрным цветом, это нужно, так как суть анимации будет в том, что мы весь экран заливаем чёрным и потом рисуем объект с новой позицией, тем самым он перемешается.
Потом идёт несколько условий, зависимо от него, мы будем увеличивать или уменьшать определённую переменную которая отвечает за позицию. Условия таковы, что круг у нас будет двигаться по часовой стрелки, по квадратному пути и он должен быть не ближе к краям окна чем на 50 пикселей.
Потом создаём шар, как это делать вы узнает ев прошлой части, также переменную для цвета назначали тоже в прошлой.
Потом идёт проверка событий, у нас она пока отвечает только за закрытие программы, но об этом ниже.
Последние обновляем весь экран, или всё прорисовываем, теперь запускаем программу и шар должен перемешаться как показано ниже:
Если у вас всё работает так же, то значит всё сделано правильно. Как вы наверное уже поняли, суть создания анимации, что мы просто меняем параметр объекта и всё перерисовываем заново, не забыв перед этим всё стереть.
Обработка событий в PyGame:
Чтобы показать более наглядно обработчик событий в PyGame, немного изменю основной код программы, который был показан выше.
Как видите мы убрали условия и рендеринг шара поставили в низ, перед обновлением экрана.
В этих условиях мы проверяем, что были нажаты именно стрелки, и как видите, при нажатие стрелок мы меняем координаты нашего шара.
Вывод:
В этой статье вы прочитали про как происходит анимация в PyGame, и немного узнали про работу с событиями. Эта была заключительная часть из цикла статей, про основы PyGame, этих знаний должно хватить, чтобы сделать простую игру.
PyGame — шпаргалка для использования
Основные модули пакета Pygame
Модуль | Назначение |
---|---|
pygame.cdrom | Доступ к CD-приводам и управление ими |
pygame.cursors | Загружает изображения курсора |
pygame.display | Доступ к дисплею |
pygame.draw | Рисует фигуры, линии и точки |
pygame.event | Управление внешними событиями |
pygame.font | Использует системные шрифты |
pygame.image | Загружает и сохраняет изображение |
pygame.joystick | Использует джойстики и аналогичные устройства |
pygame.key | Считывает нажатия клавиш с клавиатуры |
pygame.mixer | Загружает и воспроизводит мелодии |
pygame.mouse | Управляет мышью |
pygame.movie | Воспроизведение видеофайлов |
pygame.music | Работает с музыкой и потоковым аудио |
pygame.overlay | Доступ к расширенным видеоизображениям |
pygame | Содержит функции Pygame высокого уровня |
pygame.rect | Управляет прямоугольными областями |
pygame.sndarray | Манипулирует звуковыми данными |
pygame.sprite | Управление движущимися изображениями |
pygame.surface | Управляет изображениями и экраном |
pygame.surfarray | Манипулирует данными пикселей изображения |
pygame.time | модуль pygame для управления временем и частотой кадров |
pygame.transform | Изменение размера и перемещение изображений |
Окно Pygame
Цикл игры, выход из игры
Рисование базовых элементов
модуль pygame.draw
pygame.draw.rect | нарисовать прямоугольную форму |
pygame.draw.polygon | фигуру с любым количеством сторон |
pygame.draw.circle | круг вокруг точки |
pygame.draw.ellipse | нарисовать круглую форму внутри прямоугольника |
pygame.draw.arc | нарисовать секцию эллипса |
pygame.draw.line | нарисовать сегмент прямой линии |
pygame.draw.lines | для рисования нескольких смежных отрезков |
pygame.draw.aaline | рисовать тонкую линию |
pygame.draw.aalines | нарисовать связанную последовательность сглаженных линий |
Загрузка изображения
Объект Rect
pygame.Rect
Pygame использует объекты Rect для хранения и манипулирования прямоугольными областями. Rect может быть создан из комбинации значений слева, сверху, ширины и высоты. Rect также могут быть созданы из объектов python, которые уже являются Rect или имеют атрибут с именем «rect».
Методы работы с Rect
pygame.Rect.copy | Возвращает новый прямоугольник, имеющий ту же позицию и размер, что и оригинал. |
pygame.Rect.move | Возвращает новый прямоугольник, перемещаемый данным смещением. Аргументы x и y могут быть любым целочисленным значением, положительным или отрицательным. |
pygame.Rect.move_ip | То же, что и метод Rect.move (), но работает на месте. |
pygame.Rect.inflate | увеличивать или уменьшать размер прямоугольника, на месте |
pygame.Rect.inflate_ip | увеличивать или уменьшать размер прямоугольника, на месте |
pygame.Rect.clamp | перемещает прямоугольник внутри другого |
pygame.Rect.clamp_ip | перемещает прямоугольник внутри другого, на месте |
pygame.Rect.clip | обрезает прямоугольник внутри другого |
pygame.Rect.union | соединяет два прямоугольника в один |
pygame.Rect.union_ip | соединяет два прямоугольника в один, на месте |
pygame.Rect.unionall | объединение многих прямоугольников |
pygame.Rect.unionall_ip | объединение многих прямоугольников, на месте |
pygame.Rect.fit | изменить размер и переместить прямоугольник учмиывая соотношение сторон |
pygame.Rect.normalize | корректировать отрицательные размеры |
pygame.Rect.contains | проверить, находится ли один прямоугольник внутри другого |
pygame.Rect.collidepoint | проверить, находится ли точка внутри прямоугольника |
pygame.Rect.colliderect | тест, пересекаются ли два прямоугольника |
pygame.Rect.collidelist | проверить, пересекается ли хоть один прямоугольник в списке |
pygame.Rect.collidelistall | пересекаются ли все прямоугольники в списке |
pygame.Rect.collidedict | проверить, если один прямоугольник в словаре пересекается |
pygame.Rect.collidedictall | пересекаются ли все прямоугольники в словаре |
Обработка событий
Событие — это то, как Pygame сообщает о том, что что-то случилось за пределами кода программы. События создаются, например, при нажатии клавиш клавиатуры, мыши и размещаются в очереди, дожидаясь обработки.
Функция get в модуле pygame.event возвращает последнее событие, ожидающее в очереди и удаляет его из очереди.
Объект event
Модуль pygame.event для обработки очереди событий
pygame.event.pump | Если вы не используете другие функции событий в своей игре, вы должны вызвать pygame.event.pump (), чтобы позволить pygame обрабатывать внутренние действия |
pygame.event.get | получает события из очереди |
pygame.event.poll | получить одно событие из очереди |
pygame.event.wait | ждёт одиночного события из очереди |
pygame.event.peek | проверить, ждут ли очереди события определённого типа |
pygame.event.clear | удалить все события из очереди |
pygame.event.event_name | возвращает имя для типа события. Строка находится в стиле WordCap |
pygame.event.set_blocked | проверяет, какие события не разрешены в очереди |
pygame.event.set_allowed | проверяет, какие события разрешены в очереди |
pygame.event.get_blocked | проверить, заблокирован ли тип события из очереди |
pygame.event.set_grab | проверяет совместное использование устройств ввода с другими приложениями |
pygame.event.get_grab | проверить, работает ли программа на устройствах ввода данных |
pygame.event.post | поместить новое событие в очередь |
pygame.event.Event | создать новый объект события |
pygame.event.EventType | Объект Python, представляющий событие SDL. Экземпляры пользовательских событий создаются с вызовом функции Event. Тип EventType не может быть напрямую вызван. Экземпляры EventType поддерживают назначение и удаление атрибутов. |
Pygame отслеживает все сообщения о событиях через очередь событий. Процедуры в этом модуле помогают управлять этой очередью событий. Входная очередь сильно зависит от модуля отображения (display) pygame. Если дисплей не был инициализирован и видеорежим не установлен, очередь событий не будет работать.
Существует множество способов доступа к очереди событий. Просто проверять существование событий, захватывать их непосредственно из стека.
Модуль pygame.mouse для работы с мышью
pygame.mouse.get_pressed | получить состояние кнопок мыши |
pygame.mouse.get_pos | получить позицию курсора мыши |
pygame.mouse.get_rel | получить количество движений мыши |
pygame.mouse.set_pos | установить позицию курсора мыши |
pygame.mouse.set_visible | скрыть или показать курсор мыши |
pygame.mouse.get_focused | проверяет, принимает ли дисплей ввод мыши |
pygame.mouse.set_cursor | установить изображение для курсора мыши |
pygame.mouse.get_cursor | получить изображение для курсора мыши |
Функции мыши можно использовать для получения текущего состояния устройства мышь. Эти функции также могут изменять курсор мыши.
Пример. Нарисовать курсор под текущей позицией мыши.
Определить какая кнопка была нажата на мышке можно используя значение event.button:
Пример. Перемещать картинку курсором мыши.
Клавиатура
Модуль pygame.key
Этот модуль содержит функции для работы с клавиатурой.Очередь событий получает события pygame.KEYDOWN и pygame.KEYUP при нажатии и отпускании клавиш клавиатуры.
Оба события имеют ключевой атрибут, который представляет собой целочисленный идентификатор, представляющий каждую клавишу на клавиатуре.Событие pygame.KEYDOWN имеет дополнительные атрибуты: unicode и scancode. unicode представляет собой одну символьную строку, которая соответствует введённому символу. Scancode представляет собой код для конкретной платформы.
Получить код клавиши:
Существует много клавиатурных констант, они используются для представления клавиш на клавиатуре. Ниже приведен список всех клавиатурных констант:
KeyASCII | ASCII | CommonName |
---|---|---|
K_BACKSPACE | \b | backspace |
K_TAB | \t | tab |
K_CLEAR | clear | |
K_RETURN | \r | return |
K_PAUSE | pause | |
K_ESCAPE | ^[ | escape |
K_SPACE | space | |
K_EXCLAIM | ! | exclaim |
K_QUOTEDBL | « | quotedbl |
K_HASH | # | hash |
K_DOLLAR | $ | dollar |
K_AMPERSAND | & | ampersand |
K_QUOTE | quote | |
K_LEFTPAREN | ( | leftparenthesis |
K_RIGHTPAREN | ) | rightparenthesis |
K_ASTERISK | * | asterisk |
K_PLUS | + | plussign |
K_COMMA | , | comma |
K_MINUS | — | minussign |
K_PERIOD | . | period |
K_SLASH | / | forwardslash |
K_0 | 0 | 0 |
K_1 | 1 | 1 |
K_2 | 2 | 2 |
K_3 | 3 | 3 |
K_4 | 4 | 4 |
K_5 | 5 | 5 |
K_6 | 6 | 6 |
K_7 | 7 | 7 |
K_8 | 8 | 8 |
K_9 | 9 | 9 |
K_COLON | : | colon |
K_SEMICOLON | ; | semicolon |
K_LESS | less-thansign | |
K_EQUALS | = | equalssign |
K_GREATER | > | greater-thansign |
K_QUESTION | ? | questionmark |
K_AT | @ | at |
K_LEFTBRACKET | [ | leftbracket |
K_BACKSLASH | \ | backslash |
K_RIGHTBRACKET | ] | rightbracket |
K_CARET | ^ | caret |
K_UNDERSCORE | _ | underscore |
K_BACKQUOTE | ` | grave |
K_a | a | a |
K_b | b | b |
K_c | c | c |
K_d | d | d |
K_e | e | e |
K_f | f | f |
K_g | g | g |
K_h | h | h |
K_i | i | i |
K_j | j | j |
K_k | k | k |
K_l | l | l |
K_m | m | m |
K_n | n | n |
K_o | o | o |
K_p | p | p |
K_q | q | q |
K_r | r | r |
K_s | s | s |
K_t | t | t |
K_u | u | u |
K_v | v | v |
K_w | w | w |
K_x | x | x |
K_y | y | y |
K_z | z | z |
K_DELETE | delete | |
K_KP0 | keypad0 | |
K_KP1 | keypad1 | |
K_KP2 | keypad2 | |
K_KP3 | keypad3 | |
K_KP4 | keypad4 | |
K_KP5 | keypad5 | |
K_KP6 | keypad6 | |
K_KP7 | keypad7 | |
K_KP8 | keypad8 | |
K_KP9 | keypad9 | |
K_KP_PERIOD | . | keypadperiod |
K_KP_DIVIDE | / | keypaddivide |
K_KP_MULTIPLY | * | keypadmultiply |
K_KP_MINUS | — | keypadminus |
K_KP_PLUS | + | keypadplus |
K_KP_ENTER | \r | keypadenter |
K_KP_EQUALS | = | keypadequals |
K_UP | uparrow | |
K_DOWN | downarrow | |
K_RIGHT | rightarrow | |
K_LEFT | leftarrow | |
K_INSERT | insert | |
K_HOME | home | |
K_END | end | |
K_PAGEUP | pageup | |
K_PAGEDOWN | pagedown | |
K_F1 | F1 | |
K_F2 | F2 | |
K_F3 | F3 | |
K_F4 | F4 | |
K_F5 | F5 | |
K_F6 | F6 | |
K_F7 | F7 | |
K_F8 | F8 | |
K_F9 | F9 | |
K_F10 | F10 | |
K_F11 | F11 | |
K_F12 | F12 | |
K_F13 | F13 | |
K_F14 | F14 | |
K_F15 | F15 | |
K_NUMLOCK | numlock | |
K_CAPSLOCK | capslock | |
K_SCROLLOCK | scrollock | |
K_RSHIFT | rightshift | |
K_LSHIFT | leftshift | |
K_RCTRL | rightcontrol | |
K_LCTRL | leftcontrol | |
K_RALT | rightalt | |
K_LALT | leftalt | |
K_RMETA | rightmeta | |
K_LMETA | leftmeta | |
K_LSUPER | leftWindowskey | |
K_RSUPER | rightWindowskey | |
K_MODE | modeshift | |
K_HELP | help | |
K_PRINT | printscreen | |
K_SYSREQ | sysrq | |
K_BREAK | break | |
K_MENU | menu | |
K_POWER | power | |
K_EURO | Euro |
Направленное движение с помощью клавиш
Можно перемещать изображение на экране с клавиатуры, назначая клавиши для перемещений: вверх, вниз, влево, вправо.
Создать картинку, например:
Проверить очередь событий:
Проверить, является ли полученное событие нажатием на клавиши со стрелками:
Если — да, то получмить код нажатой клавиши и сформировать новые координаты для картинки:
И нарисовать картинку в новом месте:
Объект Surface
pygame.Surface — объект pygame для представления изображений
Наложение поверхностей, прозрачность.
Управление временем
Модуль pygame.time содержит объект Clock, который можно использовать для отслеживания
времени. Чтобы создать объект типа: время, вызывается конструктор pygame.time.Clock:
clock = pygame.time.Clock()
Когда создан объект clock, можно вызвать его функцию tick один раз за кадр,
которая возвращает время, прошедшее со времени предыдущего вызова в миллисекундах:
time_passed = clock.tick ()
Функция tick может использовать необязательный параметр для установления максимальной частоты кадров. Этот параметр нужен, если игра запущена на рабочем компьютере и необходимо контролировать, чтобы она не использовала всю его вычислительная мощность на 100%:
# Игра будет работать со скоростью не более 30 кадров в секунду
time_passed = clock.tick (30)
Звуки
Загружаем звуковой файл в формате *.wav
sound = pygame.mixer.Sound(«sound.wav»)
(загружаем до игрового цикла, т.к. это очень долгая операция)
Столкновения (collisions)
При написании игр часто возникает необходимость проверять взаимное расположение объектов на экране, отслеживать моменты их столкновений, пересечений.
Эта задача может быть реализована разными способами.
Например, используя объект Rect
Или используя поверхности — surface