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

جميع دروس حلقة اللعبة

تدرّب بنفسك: Playground لـ Pygame