Menu
CoddyTech

Kéo thùng hàng

Thuộc phần Vòng lặp trò chơi trong hành trình Pygame của Coddy. Bài học 17 trên 35.

Một thao tác kéo cần ba sự kiện. Nút chuột được nhấn trên thùng hàng (MOUSEBUTTONDOWN), con trỏ di chuyển (MOUSEMOTION, nhiều lần), rồi nút chuột được nhả ra (MOUSEBUTTONUP). Một biến ghi nhớ liệu thao tác kéo có đang diễn ra trong khoảng thời gian đó hay không:

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 của sự kiện MOUSEMOTION cho biết con trỏ đã di chuyển bao xa kể từ lần trước, dưới dạng (x, y). crate.move_ip(event.rel) di chuyển thùng hàng một khoảng tương ứng, vì vậy vị trí bạn nắm vẫn nằm bên dưới con trỏ.

challenge icon

Thử thách

Trung bình

Hãy để người chơi kéo thùng.

  1. Trước vòng lặp, tạo crate = pygame.Rect(40, 230, 60, 60) và dragging = False.
  2. Khi có MOUSEBUTTONDOWN, đặt dragging = True nếu crate.collidepoint(event.pos). Khi có MOUSEBUTTONUP, đặt biến này thành False.
  3. Khi có MOUSEMOTION trong lúc kéo, gọi crate.move_ip(event.rel).
  4. Trước khi vẽ viên ngọc, vẽ crate màu nâu (150, 100, 50).

Nhấn Chơi rồi kéo thùng: thùng sẽ đi theo con trỏ. Sau đó nhấn Kiểm tra.

Tự làm thử

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()

Tất cả bài học trong Vòng lặp trò chơi

Tự luyện tập: Playground Pygame