Topic 4 of 6

Course materials are currently available in Russian only.

Клавиатура и мышь

События клавиатуры

from pyglet.window import key

@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.SPACE:
        shoot()
    elif symbol == key.ESCAPE:
        window.close()

@window.event
def on_key_release(symbol, modifiers):
    ...

symbol — код клавиши: key.A, key.LEFT, key.SPACE, key.ENTER… modifiers — зажатые Shift, Ctrl, Alt: if modifiers & key.MOD_SHIFT:.

Какие клавиши зажаты сейчас

Для плавного движения удобнее спрашивать «зажата ли клавиша прямо сейчас»:

keys = key.KeyStateHandler()
window.push_handlers(keys)          # keys сам следит за нажатиями и отпусканиями

def update(dt):
    if keys[key.LEFT]:
        hero.x -= 200 * dt

push_handlers(obj) подписывает объект на события окна: pyglet будет вызывать его методы on_key_press, on_mouse_press и другие с такими же именами.

Движение по диагонали

Если сложить «вправо» и «вверх», получится вектор (1, 1) длиной √2 ≈ 1.41 — по диагонали игрок побежит быстрее. Направление нормализуют — делят на длину:

length = math.hypot(dx, dy)
if length:                           # (0, 0) делить нельзя
    dx, dy = dx / length, dy / length

True и False в Python ведут себя как 1 и 0, поэтому keys[key.RIGHT] - keys[key.LEFT] даёт 1, -1 или 0.

Мышь

@window.event
def on_mouse_press(x, y, button, modifiers):
    if button == pyglet.window.mouse.LEFT:
        ...

@window.event
def on_mouse_drag(x, y, dx, dy, buttons, modifiers):   # движение с зажатой кнопкой
    ...

@window.event
def on_mouse_motion(x, y, dx, dy):                     # движение без кнопок
    ...

Координаты мыши — в той же системе, что и рисование: (0, 0) внизу слева.

Попадание по фигуре

  • Круг: (x - c.x) ** 2 + (y - c.y) ** 2 <= c.radius ** 2 — квадраты, чтобы не считать корень.
  • Прямоугольник: r.x <= x < r.x + r.width and r.y <= y < r.y + r.height.

Если фигуры перекрываются, клик получает верхняя — та, что нарисована последней. Поэтому список перебирают с конца.

Итог

  • on_key_press, on_key_release, коды key.…;
  • key.KeyStateHandler() и window.push_handlers(...) — какие клавиши зажаты;
  • диагональ нормализуют делением на math.hypot(dx, dy);
  • on_mouse_press, on_mouse_drag; попадание — с верхней фигуры; при перетаскивании хранят смещение.