Четверг, 30 марта 2017, 05:33

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [298]
Статьи об общих понятиях связанных с созданием игр.
Программирование [66]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [120]
Статьи о программах для создания игр, уроки и описания.
Софт [27]
Различные программы, в том числе в помощь игроделам.
2D-графика [7]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [8]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [4]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [65]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [53]
Статьи, которые не вошли в определённые разделы.
Наш опрос
Какую графическую систему API вы используете?
Всего ответов: 9773
Главная » Статьи » Движки и Гейммейкеры

Основы PyGame. Введение в события
Основы PyGame. Введение в события.

Доброго времени суток, уважаемые участники ресурса GcUp!
В этой статье рассмотрим события в PyGame.

Перед изучением статьи читатель должен знать следующие вещи:

  • Знание синтаксиса и семантики языка Python ветки 2.х. (Если знаете С/С++, Java, PHP и т.д но не знаете Python то лучше не начинать изучать эти статьи, это разные языки и ничего общего у Python’a с ними нет).
  • Знание основ работы в IDLE(Python GUI) или умение запускать и редактировать программы на языке Python в других средах разработки.
  • Знание основных типов данных языка Python ветки 2.х. (числа, строки, последовательности/списки, словари, кортежи).
  • Умение работать в операционной системе Windows.
  • Знание информации, которая выложена в предыдущих статьях.

    Логически эта статья будет разделена на следующие блоки:

  • Введение в события PyGame.
  • Анализ методов для работы над очередью событий в PyGame.
  • Заключение
    На этом все, приступим к изучению библиотеки PyGame.

    Часть первая. Введение в события.

    Все события в PyGame при их появлении сразу же добавляются в очередь событий. Очередь событий это обычный стек со структурой “последний вошел - первый вышел”. В модуле Event определенные некоторые методы для управления очередью событий, вот весь список методов и их короткое описание:

  • pygame.event.pump – обработка внутренних событий PyGame
  • pygame.event.get – Получить все события из очереди событий.
  • pygame.event.poll – Получить одно событие из очереди событий.
  • pygame.event.wait - Ждать первого события в очереди.
  • pygame.event.peek – Узнать находится ли событие в очереди.
  • pygame.event.clear – Удалить все события в очереди.
  • pygame.event.event_name – Получить имя события.
  • 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 –Создать новое событие.

    Очередь событий зависит от модуля Display, если дисплей не был инициализирован и видео режим не установлен, очередь событий будет некорректно работать. Если приложение использует джойстик, то события связанные с этим устройством будут добавляться в очередь только после инициализации этого устройства.
    Программа на PyGame должна принять меры по сохранению очереди от переполнения, при переполнении возникает исключение.
    Объект Event содержит идентификатор типа события и доступные только для чтения данные, которые определяются по типу события. Идентификатор типа события содержится в свойстве Event.type, а набор атрибутов данных можно получить через метод Event.dict. События поддерживают сравнение на равенство. Два события равны, если они одного типа и имеют одинаковое значение атрибута.
    Ниже описана таблица с набором типов событий и их атрибутов данных:

  • QUIT - none
  • ACTIVEEVENT - gain, state
  • KEYDOWN - unicode, key, mod
  • KEYUP - key, mod
  • MOUSEMOTION - pos, rel, buttons
  • MOUSEBUTTONUP - pos, button
  • MOUSEBUTTONDOWN - pos, button
  • JOYAXISMOTION - joy, axis, value
  • JOYBALLMOTION - joy, ball, rel
  • JOYHATMOTION - joy, hat, value
  • JOYBUTTONUP - joy, button
  • JOYBUTTONDOWN - joy, button
  • VIDEORESIZE - size, w, h
  • VIDEOEXPOSE - none
  • USEREVENT – code

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

    Часть вторая. Анализ методов для работы над очередью событий в PyGame.

    Первым методом будет pygame.event.get(): return Eventlist, где Eventlist – список объектов Event. Этот метод представлен в трех реализациях:

  • pygame.event.get(): return Eventlist
  • pygame.event.get(type): return Eventlist
  • pygame.event.get(typelist): return Eventlist

    Первая реализация не имеет параметров и возвращает список всех объектов Event из очереди. Во втором методе есть параметр type – тип события, если использовать этот вариант метода, то список будет содержать только объекты Event, тип которых будет равен параметру type. Третий вариант метода принимает список типов событий, этот метод возвратит все объекты Event, тип которых равен типам, указанных в параметре метода. Этот метод мы уже использовали в шаблоне программы на PyGame, вот кусок кода этого шаблона:

    Code
    for event in pygame.event.get():

    Как видно для того чтобы пройтись по всему списку объектов возвращенных методом pygame.event.get мы ввели итератор event. В теле цикла мы можем сравнивать тип события и таким образом можем обрабатывать связанные с этим типом события.
    Для примера давайте обработаем тип события MOUSEBUTTONDOWN. Для начала откроем созданный нами раньше шаблон pygame_template.py и сохраним его под именем pygame_event.py и изменим значение заголовка окна на “PyGame Event”. Теперь надо разобраться с тем как мы будем обрабатывать событие, из названия MOUSEBUTTONDOWN понятно, то, что это событие связано с нажатием кнопки мыши, для обработки этого события мы будем рисовать красный круг там, где пользователь нажал левую кнопку мыши, для этого введем три переменные: circle_radius – радиус круга, circle_color – цвет круга, circle_pos – позиция центра круга, для этого в блоке инициализации пишем следующих код:
    Code
    circle_pos = (0,0)
    circle_color = (255, 0, 0)
    circle_radius = 10

    Теперь в телецикла с итератором event надо сравнить тип события с MOUSEBUTTONDOWN, если тип события равен MOUSEBUTTONDOWN то этого события есть атрибут button, теперь уже надо сравнить этот атрибут к значением левой кнопки мыши, левая кнопка мыши имеет значение 1, если значение атрибута button равно 1, то можно присвоить переменной circle_pos значение атрибута позиции мыши pos, вот весь код обработки события MOUSEBUTTONDOWN:
    Code
    if event.type == MOUSEBUTTONDOWN:
      if event.button == 1:
      circle_pos = event.pos

    Осталось только нарисовать круг в блоке формирования кадра, рисовать круг будет методом pygame.draw.circle, этот метод мы с вами уже разобрали в предыдущей статье, собственно вот весь код формирования кадра:
    Code
    pygame.draw.circle(screen, circle_color, circle_pos, circle_radius);

    Теперь можно запустить код и проверить что получилось. Как видно круг красного цвета рисуется на том месте, где пользователь последний раз нажал левую кнопку мыши.

    Ну а теперь давайте обработаем событие, связанное с клавиатурой, давайте обработаем тип события KEYDOWN, давайте сделаем, так что при нажатии на клавишу “Esc” программа закрывалась. Первое что нам надо это узнать является ли событие типа KEYDOWN, в блоке цикла с итератором event пишем:
    Code
    if event.type == KEYDOWN:

    Условие готово, осталось только сравнить атрибут key с клавишей “Esc”, код этой клавиши в PyGame равен константе “K_ESCAPE” (набор всех констант клавиш можно узнать в модуле Key), если атрибут key равен “K_ESCAPE” то снимаем флаг mainLoop, если этот фланг не установлен то программа закроется, вот код из блока предыдущего условия:
    Code
    if event.key == K_ESCAPE:
      mainLoop = False

    Теперь можно проверить обрабатывается ли событие или нет, запускаем программу, как видно если нажать на клавишу “Esc” то программа закроется, а это значит то, что все работает хорошо.
    Следующий метод работы над очередью событий это pygame.event.set_blocked, этот метод блокирует добавление событий определенного типа в очередь событий. Он имеет следующие реализации:
  • pygame.event.set_blocked(type): return None
  • pygame.event.set_blocked(typelist): return None
  • pygame.event.set_blocked(None): return None
    Все три реализации возвращают None, то есть ничего не возвращают. В первой реализации используется параметр type, это тип события, добавление которого запрещено в очередь. Во второй реализации используется список типов события – typelist, которым запрещено добавляться в очередь. Следующий вариант является противоположным по отношению к двум предыдущим если в параметре ничего не указано, то все типы события могут быть добавлены в очередь событий. По умолчанию если не использовать эти методы, добавление в очередь событий доступно всем типам событий.
    Давайте попробуем заблокировать какое-то событие, для примера давайте заблокирует событие, которые мы обрабатываем, это позволит узнать заблокировали ли мы событие или нет, выбор в этом случае упал на тип события MOUSEBUTTONDOWN, добавим следующий код в блок инициализации данных:
    Code
    pygame.event.set_blocked(MOUSEBUTTONDOWN)

    Теперь можно проверить заблокировано событие или нет, запускаем и пробуем нажимать правую кнопку мыши, как видно ничего не происходит, код обработка события есть, но оно не обрабатывается, так как типа этого события нет в очереди событий.
    Давайте теперь проверим, как работает вторая реализация этого метода, передадим в этот метод список из двух элементов MOUSEBUTTONDOWN и KEYDOWN, изменим код выше на этот код:
    Code
    pygame.event.set_blocked([MOUSEBUTTONDOWN, KEYDOWN])

    По идеи этот метод должен заблокировать тип событий MOUSEBUTTONDOWN и KEYDOWN, то есть обработчик нажатий клавиш, и обработчик нажатий клавиш мыши работать не будет, давайте запустим программу и узнаем это. Действительно, нажатие на клавишу “Esc”, не дает ни какого результата, также нет и результата при нажатии на левую кнопку мыши.
    Мы уже рассмотрели метод, который блокирует добавление событий в очередь, давайте теперь рассмотрим метод, который разблокирует добавление событий в очередь - pygame.event.set_allowed, этот метод чем-то похож на предыдущий метод, он тоже имеет три реализации:
  • pygame.event.set_allowed(type): return None
  • pygame.event.set_allowed(typelist): return None
  • pygame.event.set_allowed(None): return None
    Тут практически ничего рассказывать, это полная копия метода pygame.event.set_blocked только выполняет все наоборот, параметры у него такие же, как и в первом методе, если параметра нет, то не один тип событий не может попасть в очередь событий.
    Давайте перейдем к практике и попробуем изменить нашу программу, пусть при нажатии на клавишу Space блокировалось или разблокировалось добавление событий MOUSEBUTTONDOWN. Для начала уберем код блокировки событий в блоке инициализации данных и вместо этого определим флаг блокировки/разблокировки события block_flag, вот его инициализация:
    Code
    block_flag = False

    Теперь надо сравнить атрибут key с клавишей Space, сам блок обработки события KEYDOWN уже есть, теперь надо сравнить атрибут, так что пишем код в блоке обработки события KEYDOWN:
    Code
    if event.key == K_SPACE:

    Далее следует присвоит флагу block_flag отрицание, то есть если флаг содержал значение True то теперь он будет содержать False и наоборот если содержал False то теперь будет содержать True:
    Code
    block_flag = not block_flag

    Можно еще вывести в терминал интерпретатора данные строку, по которым можно узнать заблокировано событие или нет:
    Code
    print 'MOUSEBUTTONDOWN is block: ', block_flag

    Теперь в зависимости от значения флага block_flag будем блокировать или разблокировать событие MOUSEBUTTONDOWN:
    Code
    if block_flag:
      pygame.event.set_blocked(MOUSEBUTTONDOWN)
      else:
      pygame.event.set_allowed(MOUSEBUTTONDOWN)

    Ну а теперь настал момент проверки, запускаем, как видим все работает, жмем на Space и блокируем/разблокируем добавление события MOUSEBUTTONDOWN в очередь событий, в терминал интерпретатора также выводится информация о том заблокировано событие MOUSEBUTTONDOWN или нет.
    Давайте теперь рассмотрим метод, по которому мы можем узнать заблокирован тип события или нет, рассмотрим метод pygame.event.get_blocked(type): return bool, тут type – тип события, метод возвращает логическое значение в зависимости от того заблокировано событие или нет.
    Давайте используем его на практике, удалим следующий код, в котором выводим в терминал информацию о том, заблокировано событие или нет:
    Code
    print 'MOUSEBUTTONDOWN is block: ', block_flag

    И заменим его на код с методом pygame.event.get_blocked:
    Code
    print 'MOUSEBUTTONDOWN is block: ', pygame.event.get_blocked(MOUSEBUTTONDOWN)

    Запустим и протестируем, как видим ничего не произошло, а это хорошо и значит, то, что все работает как надо.
    В целом у нас должен получится следующий код в файле pygame_event.py:

    Ну а теперь займемся методом pygame.event.pump. Этот метод используется в том случае, если не требуется писать обработчиков событий, например если мы проигрываем анимацию передвижения объекта с одного места в другое, то писать обработчики событий нет смысла, но если мы не будем очищать очередь событий или передавать эту очередь другим программам, то наша программа зависнет, так как выполняется бесконечный цикл. Для этого чтобы программа не зависла надо отправить очередь другим программам. На помощь нам приходит следующий метод pygame.event.pump. Этот метод ничего не принимает в качестве параметров и ничего не возвращает.
    Давайте попробуем этот метод на практике, открываем шаблон pygame_template.py и сохраняем его под именем pygame_event_1.py и поменяем заголовок окна на “PyGame Event”. Теперь настало время, удалить цикл, в котором итератор event проходит по всем событиям, возвращаемых методом pygame.event.get. Если сейчас запустить программу то она зависнет, попробуйте это сделать. Как видно программа действительно зависает, для того чтобы убрать завившею программу надо перезагрузить интерпретатор через меню “Shell”.
    Теперь давайте добавим место цикла метод pygame.event.pump:
    Code
    pygame.event.pump()

    Сам метод pygame.event.pump(): return None используется для обработки внутренних событий PyGame, таких как обрисовка окна, взаимодействие программы с системными событиями и т.д. Если в программе используется любой метод работы над очередью событий модуля Event, то можно не использовать pygame.event.pump.
    Теперь запустим программу и посмотрим, зависает программа или нет, как видно не зависает, но выйти из программы не можем, для этого нам понадобится следующие два метода.
    Метод pygame.event.peek возвращает логическое значение в зависимости от того имеется тип события в очереди или нет, метод реализовать в двух реализациях:
  • pygame.event.peek(type): return bool
  • pygame.event.peek(typelist): return bool
    В первом используется параметр type – определяющий тип события, если тип этого события есть в очереди, то метод возвратит True. Во втором варианте параметр typelist – это список типов событий, если одно из этих событий есть в очереди, то метод вернет True.
    Следующий метод это pygame.event.clear, этот метод очищает очередь событий, метод реализован в трех реализациях:
  • pygame.event.clear(): return None
  • pygame.event.clear(type): return None
  • pygame.event.clear(typelist): return None
    Во всех реализациях метод ничего не возвращает, но имеет разные параметры. В первом случае, когда метод не имеет параметра, очищается полностью очередь. Во втором случае удаляются только события, тип которых соответствует параметру type. В третьем случае удаляются все события, которые входят в список типов typelist.
    Имея эти два метода, мы теперь можем обработать события выхода из программы. Вначале мы узнаем, есть ли событие QUIT в очереди событий, если есть, то выйдем из главного цикла, так же придется очистить очередь чтобы не допустить переполнения очереди, так что удаляем метод pygame.event.pump и пишем следующий код:
    Code
    if pygame.event.peek(QUIT):
      mainLoop = False
      pygame.event.clear()

    Как видно из кода, мы вначале узнали, есть ли данный тип события в очереди, если он есть, то убираем флаг главного цикла, а после условия очищаем очередь, так как нам надо заботится о переполнении очереди.
    Можно запустить и проверить работает закрытие программы или нет. Как видно работает, в итоге должен быть написан следующий код в файле pygame_event1.py:

    Теперь настало время разобрать методы которые очень редко используются для работы над очередью событий, первый метод это pygame.event.wait(). Этот метод представлен в одном экземпляре и ничего не возвращает. Сам метод дожидается, когда в очереди памяти будет хотя бы одно событие, если в очереди нет событий, то программа ждет, когда оно там появится, хоть программа и будет ждать, но она будет находиться в состояние простоя, это очень важно если программа должна делится процессорным временем с другими программами и системой.
    Следующий метод это pygame.event.event_name(type): return string, метод принимает в качестве параметра тип события и возвращает его название в качестве строки, по сути метод используется для отладки программ, когда требуется узнать строковое имя типа события.
    Теперь пришло время рассмотреть методы, которые работают с устройствами ввода, их всего два, pygame.event.set_grab(bool): return None и pygame.event.get_grab(): return bool. Первый метод pygame.event.set_grab(bool): return None используется для того чтобы разрешать/запрещать другим программа пользоваться устройствами ввода когда фокус программы стоит на вашей программе. Он имеет всего один логический параметр, если он установлен в True, то другим программам запрещено получать события связанные с устройствами ввода. Второй метод pygame.event.get_grab(): return bool возвращает логической значение исходя от того запрещено ли другим программам пользоваться устройствами ввода.
    Ну а теперь рассмотрим метод, который очень редко используется, это метод pygame.event.poll(): return Event, как уже понятно из его название метод возвращает последнее событие в очереди, если очередь пустая то возвращается событие с типом NOEVENT, все возвращенные события удаляются из очереди. Метод используется редко и только на этапе отладки программы.
    Ну и на последок, в PyGame можно создавать и свои события, для этого есть конструктор pygame.event.Event(type, dict): return Event, где type – тип события, dict – словарь с содержанием атрибут/значение. В целом он используется для создания событий пользователей и часто типом такого события является тип USEREVENT, но его можно использовать и для программного создания событий, которые связаны с устройствами ввода/вывода. Созданное событие можно поместить в очередь событий через метод pygame.event.post(Event): return None, где Event – объект событие. Этот метод вставляет в конец очереди событие, созданное программным или другим путем.

    Часть третья. Заключение.

    Вот и все, мы с вами рассмотрели все методы модуля Event библиотеки PyGame для работы над очередью событий в PyGame, в целом эта статья является введением в события и поэтому некоторые методы были с примерами, а некоторые без них. Ну а следующей статье мы разберем полностью модуль Rect .
    Если есть, вопросы или проблемы по статье обращайтесь ко мне в Л.С.
    Все всем пока, желаю удачи в геймдеве. Спасибо за внимание с вами был noTformaT.

    P.S.

    Если вы просто скопируете программный код с этой статьи то он возможно не запустится, связано это с тем что табуляций и пробелы в Python имеют определенный смысл. Если это произошло, и программа зависла, то требуется перезагрузить терминал интерпретатора открыв в терминале меню «Shell» и выбрав пункт «Restart Shell».

  • Категория: Движки и Гейммейкеры | Добавил: noTformaT (22 февраля 2011) | Автор: Евгений Карпенко
    Просмотров: 9944 | Комментарии: 1 | Рейтинг: 4.7/7 |
    Теги: Pygame, основы
    Дополнительные опции:
    Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

    Игровые объявления и предложения:
    Если вас заинтересовал материал «Основы PyGame. Введение в события», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

    Всего комментариев: 1
    +0-
    1 Механки   (22 февраля 2014 15:00)
    Механкиbiggrin biggrin спасибо классный статья

    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Поиск
    10 случайных движков
  • PopCap Games Framework
  • HPL1 Engine
  • IceCream
  • Smile Game Builder
  • 001 Game Creator
  • Doomsday
  • Jet3D
  • ezRPG
  • Vicious Engine
  • PointJS
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    GameDev, Уроки OpenGL, Программирование, Создать Minecraft
    Все права сохранены. GcUp.ru © 2008-2017 | Free GIF Animator Рейтинг