События мыши
В Pygame обрабатываются три типа событий мыши:
-
нажатие кнопки (значение свойства
type
события соответствует константеpygame.MOUSEBUTTONDOWN
), -
отпускание кнопки (
MOUSEBUTTONUP
), -
перемещение мыши (
MOUSEMOTION
).
Какая именно кнопка была нажата, записывается в другое свойство события – button
. Для левой кнопки это число 1, для средней – 2, для правой – 3, для прокручивания вперед – 4, для прокручивания назад – 5. У событий MOUSEMOTION
вместо button
используется свойство buttons
, в которое записывается состояние трех кнопок мыши (кортеж из трех элементов).
Другим атрибутом мышиных типов событий является свойство pos
, в которое записываются координаты происшествия (кортеж из двух чисел).
Таким образом, если вы нажали правую кнопку мыши точно в середине окна размером 200x200, то будет создан объект типа Event
с полями event.type = pygame.MOUSEBUTTONDOWN
, event.button = 3
, event.pos = (100, 100)
.
У событий MOUSEMOTION
есть еще один атрибут – rel
. Он показывает относительное смещение по обоим осям. С помощью него, например, можно отслеживать скорость движения мыши.
Код ниже создает фигуры в местах клика мыши. Нажатие средней кнопки очищает поверхность.
import pygame as pg import sys WHITE = (255, 255, 255) RED = (225, 0, 50) GREEN = (0, 225, 0) BLUE = (0, 0, 225) sc = pg.display.set_mode((400, 300)) sc.fill(WHITE) pg.display.update() while 1: for i in pg.event.get(): if i.type == pg.QUIT: sys.exit() if i.type == pg.MOUSEBUTTONDOWN: if i.button == 1: pg.draw.circle(sc, RED, i.pos, 20) pg.display.update() elif i.button == 3: pg.draw.circle(sc, BLUE, i.pos, 20) pg.draw.rect(sc, GREEN, (i.pos[0] - 10, i.pos[1] - 10, 20, 20)) pg.display.update() elif i.button == 2: sc.fill(WHITE) pg.display.update() pg.time.delay(20)
В функции модуля draw
вместо координат передается значение поля pos
события. В pos
хранятся координаты клика. В случае с функцией rect()
извлекаются отдельные элементы кортежа pos
. Вычитание числа 10 используется для того, чтобы середина квадрата, сторона которого равна 20-ти пикселям, точно соответствовала месту клика. Иначе в месте клика будет находиться верхний левый угол квадрата.
Функцию update()
не обязательно вызывать три раза в ветках if-elif-elif. Ее можно вызвать в основном теле главного цикла. Однако в этом случае, когда кликов не происходит, она будет выполнять зря.
Также как в случае с клавиатурой в pygame есть свой модуль для событий мыши. Если нужно отслеживать длительное зажатие ее кнопок, следует воспользоваться функцией get_pressed()
модуля pygame.mouse
. Здесь же есть функция для считывания позиции курсора – get_pos()
. Следующий код рисует синий круг в местах клика левой кнопкой мыши:
import pygame as pg import sys WHITE = (255, 255, 255) BLUE = (0, 0, 225) sc = pg.display.set_mode((400, 300)) sc.fill(WHITE) pg.display.update() while 1: for i in pg.event.get(): if i.type == pg.QUIT: sys.exit() pressed = pg.mouse.get_pressed() pos = pg.mouse.get_pos() if pressed[0]: pg.draw.circle(sc, BLUE, pos, 5) pg.display.update() pg.time.delay(20)
Функция mouse.get_pressed()
возвращает трехэлементный кортеж. Первый элемент (с индексом 0) соответствует левой кнопке мыши, второй – средней, третий – правой. Если значение элемента равно True
, значит, кнопка нажата. Если False
, значит – нет. Так выражение pressed[0]
есть истина, если под нулевым индексом содержится True
.
Чтобы скрыть курсор (например, в игре, где управление осуществляется исключительно клавиатурой), надо воспользоваться функцией pygame.mouse.set_visible()
, передав в качестве аргумента False
.
Так можно привязать графический объект к курсору (в данном случае привязывается квадрат):
import pygame as pg import sys WHITE = (255, 255, 255) BLUE = (0, 0, 225) pg.init() sc = pg.display.set_mode((400, 300)) sc.fill(WHITE) pg.display.update() pg.mouse.set_visible(False) while 1: for i in pg.event.get(): if i.type == pg.QUIT: sys.exit() sc.fill(WHITE) if pg.mouse.get_focused(): pos = pg.mouse.get_pos() pg.draw.rect( sc, BLUE, (pos[0] - 10, pos[1] - 10, 20, 20)) pg.display.update() pg.time.delay(20)
Функцией get_pos()
мы можем считывать позицию курсора, даже если он не виден. Далее в этой позиции рисуем фигуру на каждой итерации цикла.
Функция get_focused()
проверяет, находится ли курсор в фокусе окна игры. Если не делать эту проверку, то при выходе курсора за пределы окна, квадрат будет постоянно прорисовываться у края окна, где произошел выход, т. е. не будет исчезать.
Практическая работа
Напишите код в котором имитируется полет снаряда (пусть его роль сыграет круг) в место клика мышью. Снаряд должен вылетать из нижнего края окна и лететь вверх, т. е. изменяться должна только координата y. Пока летит один, другой не должен появляться. Когда снаряд достигает цели, должен имитировать взрыв, например, в этом месте прорисовываться квадрат.
Курс с примерами решений практических работ:
pdf-версия