Menu
CoddyTech

Перетащи ящик

Часть раздела Игровой цикл путешествия по Pygame на Coddy. Урок 16 из 32.

Перетаскивание состоит из трёх событий. Кнопка нажимается на ящике (MOUSEBUTTONDOWN), указатель перемещается (MOUSEMOTION, много раз), а затем кнопка отпускается (MOUSEBUTTONUP). Переменная запоминает, выполняется ли перетаскивание в данный момент:

elif event.type == pygame.MOUSEBUTTONDOWN:
    if crate.collidepoint(event.pos):
        dragging = True
elif event.type == pygame.MOUSEBUTTONUP:
    dragging = False
elif event.type == pygame.MOUSEMOTION and dragging:
    crate.move_ip(event.rel)

В event.rel события MOUSEMOTION указано, на какое расстояние переместился указатель с момента предыдущего события, в виде (x, y). crate.move_ip(event.rel) перемещает ящик на такое же расстояние, поэтому место, за которое вы его схватили, остаётся под указателем.

Ящик рисуется после самоцвета, поэтому может его закрыть. Нажатие на ящик не должно собирать скрытый под ним самоцвет: сначала проверьте ящик, а самоцвет — с помощью elif, чтобы нажатие обрабатывалось только для одного из них.

challenge icon

Задание

Средне
  1. Перед циклом создайте crate = pygame.Rect(40, 230, 60, 60) и dragging = False.
  2. При MOUSEBUTTONDOWN установите dragging = True, если щелчок пришёлся по ящику; в противном случае (elif) проверьте самоцвет, как и раньше.
  3. Установите dragging = False при MOUSEBUTTONUP. При MOUSEMOTION, пока перетаскивание активно, перемещайте ящик на величину event.rel.
  4. После контура самоцвета нарисуйте ящик коричневым цветом (150, 100, 50) с краем цвета (110, 70, 35) шириной 3 пикселя.

Попробуйте сами

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Gem Hunt")
clock = pygame.time.Clock()

gem = pygame.Rect(225, 165, 30, 30)
score = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if gem.collidepoint(event.pos):
                score += 1
                gem.x = random.randint(15, 435)
                gem.y = random.randint(55, 315)

    screen.fill((30, 30, 46))
    gem_points = [gem.midtop, gem.midright, gem.midbottom, gem.midleft]
    pygame.draw.polygon(screen, (80, 220, 255), gem_points)
    if gem.collidepoint(pygame.mouse.get_pos()):
        pygame.draw.rect(screen, (255, 196, 0), gem.inflate(10, 10), 2)
    for i in range(score):
        pygame.draw.rect(screen, (240, 110, 180), (10 + 10 * i, 14, 8, 8))
    mouse_x, mouse_y = pygame.mouse.get_pos()
    pygame.draw.circle(screen, (240, 240, 240), (mouse_x, mouse_y), 10, 2)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Все уроки раздела Игровой цикл

Потренируйтесь самостоятельно: Песочница Pygame