در این بخش می خواهیم کمی بیش تر با مستطیل ها کار کنیم و آن ها را با موس و کیبورد حرکت دهیم و با شی Rect نیز بیش تر آشنا می شویم.
مستطیل یک شی بسیار مفید در برنامه نویسی گرافیکی است. کلاس Rect در Pygame برای کارکردن با یک ناحیه مستطیلی شکل استفاده می شود. با داشتن موارد زیر می توان یک شی Rect از کلاس Rect را ایجاد کرد:
Rect(left, top, width, height) Rect(pos, size) Rect(obj)
متد هایی که موقعیت(position) یا اندازه(size) را تغییر می دهند، مانند move و inflate، مستطیل اصلی را دست نخورده باقی می گذارند و یک مستطیل را جدید بازگردانند.
شی Rect دارای ویژگی های دیگری نیز است که می تواند برای جابجایی و ترازبندی مستطیل استفاده شود. به کار گیری این ویژگی ها اندازه مستطیل را تغییر نمی دهد.این ویژگی ها در زیر آمده اند:
x, y top, left, bottom, right topleft, bottomleft, topright, bottomright midtop, midleft, midbottom, midright center, centerx, centery
استفاده از پنج ویژگی زیر، اندازه مستطیل را با حفظ موقعیت بالا چپ (top left) آن تغییر می دهد:
size, width, height, w, h
کد زیر ویژگی های معرفی شده در بالا را، در کنسول نمایش می دهد:
import pygame from pygame.locals import * SIZE = 500, 200 RED = (255, 0, 0) GRAY = (150, 150, 150) pygame.init() screen = pygame.display.set_mode(SIZE) rect = Rect(50, 60, 200, 80) print(f'x={rect.x}, y={rect.y}, w={rect.w}, h={rect.h}') print(f'left={rect.left}, top={rect.top}, right={rect.right}, bottom={rect.bottom}') print(f'center={rect.center}') running = True while running: for event in pygame.event.get(): if event.type == QUIT: running = False screen.fill(GRAY) pygame.draw.rect(screen, RED, rect) pygame.display.flip() pygame.quit()
کلاس Rect دارای چهار نقطه کناری، چهار نقطه میانی و یک نقطه مرکزی است.
کد رسم مستطیل بالا در زیر آمده است:
from rect import * pts = ('topleft', 'topright', 'bottomleft', 'bottomright','midtop', 'midright', 'midbottom', 'midleft', 'center') running = True while running: for event in pygame.event.get(): if event.type == QUIT: running = False screen.fill(GRAY) pygame.draw.rect(screen, GREEN, rect, 4) for pt in pts: pos = eval('rect.'+pt) draw_text(pt, pos) pygame.draw.circle(screen, RED, pos, 3) pygame.display.flip() pygame.quit()
در مثال زیر از سه کلید برای ترازبندی افقی مستطیل استفاده می کنیم:
• L - left
• C - center
• R - right
و از سه کلید دیگر زیر برای ترازبندی عمودی مستطیل استفاده می کنیم:
• T - top
• M - middle
• B - bottom
from rect import * rect = Rect(50, 60, 200, 80) while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_l: rect.left = 0 if event.key == K_c: rect.centerx = width//2 if event.key == K_r: rect.right = width if event.key == K_t: rect.top = 0 if event.key == K_m: rect.centery = height//2 if event.key == K_b: rect.bottom = height screen.fill(GRAY) pygame.draw.rect(screen, BLUE, rect) pygame.display.flip() pygame.quit()
متد move (v) یک مستطیل جدید ایجاد می کند که توسط بردار v حرکت کرده است. متد move_ip (v) یک مستطیل را در جای خود حرکت می دهد. برنامه زیر با استفاده از کلیدهای پیکانی یک مستطیل را به اطراف حرکت می دهد. مستطیل نازک و آبی مستطیل اصلی است، و مستطیل قرمز همان مستطیل آبی است که حرکت کرده است. ما از یک دیکشنری برای مرتبط کردن یک بردار حرکت برای هر یک از 4 کلید پیکانی استفاده می کنیم. در هر جهتی 5 پیکسل حرکت می کنیم:
dir = {K_LEFT: (-5, 0), K_RIGHT: (5, 0), K_UP: (0, -5), K_DOWN: (0, 5)}
from rect import * rect0 = Rect(50, 60, 200, 80) rect = rect0.copy() while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key in dir: v = dir[event.key] rect.move_ip(v) screen.fill(GRAY) pygame.draw.rect(screen, BLUE, rect0, 1) pygame.draw.rect(screen, RED, rect, 4) pygame.display.flip() pygame.quit()
متد inflate (v) یک مستطیل را با بردار v بزرگ یا کوچک می کند و یک مستطیل جدید به وجود می آورد. متد inflate_ip (v) باعث بزرگ یا کوچک شدن یک مستطیل در جای خود می شود. برنامه زیر با استفاده از کلیدهای پیکانی اندازه مستطیل را تغییر می دهد. مستطیل قرمز تغییر یافته مستطیل آبی است.
from rect import * rect0 = rect.copy() while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key in dir: v = dir[event.key] rect.inflate_ip(v) screen.fill(GRAY) pygame.draw.rect(screen, BLUE, rect0, 1) pygame.draw.rect(screen, RED, rect, 4) pygame.display.flip() pygame.quit()
اگر نقطه با مستطیل تماس پیدا کند، تابع rect.collidepoint (pos) مقدار بولین True را برمی گرداند. از این مقدار برگشتی همراه با موقعیت موس استفاده می کنیم تا بفهمیم که آیا موس در داخل مستطیل کلیک کرده است یا نه. اگر کلیک رخ داده باشد، مستطیل را با موس حرکت می دهیم .متغیر moving هنگامی که دکمه موس در داخل مستطیل کلیک می شود، تنظیم می شود.این متغییر تا زمانی که دکمه بالا نرفته است، True می ماند. مستطیل فقط زمانی حرکت می کند که موس در داخل مستطیل کلیک کرده باشد. در حالی که مستطیل در حال حرکت است، یک حاشیه آبی رنگ به دور مستطیل می افزاییم مانند تصویر زیر:
from rect import * moving = False while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == MOUSEBUTTONDOWN: if rect.collidepoint(event.pos): moving = True elif event.type == MOUSEBUTTONUP: moving = False elif event.type == MOUSEMOTION and moving: rect.move_ip(event.rel) screen.fill(GRAY) pygame.draw.rect(screen, RED, rect) if moving: pygame.draw.rect(screen, BLUE, rect, 4) pygame.display.flip() pygame.quit()
کد زیر یک مستطیل را با مقدار v حرکت می دهد:
rect.move_ip(v)
سپس چهار حاشیه مستطیل را بررسی می کند و سرعت حرکت مستطیل را خارج از پنجره برنامه تنظیم می کند.
from rect import * rect = Rect(100, 50, 50, 50) v = [2, 2] while running: for event in pygame.event.get(): if event.type == QUIT: running = False rect.move_ip(v) if rect.left < 0: v[0] *= -1 if rect.right > width: v[0] *= -1 if rect.top < 0: v[1] *= -1 if rect.bottom > height: v[1] *= -1 screen.fill(GRAY) pygame.draw.rect(screen, RED, rect) pygame.display.flip() pygame.quit()
متد rect.collidepoint (p) بررسی می کند که آیا یک مستطیل با نقطه p برخورد می کند یا نه. در برنامه زیر صد نقطه تصادفی ایجاد می کنیم و اگر داخل مستطیل قرار بگیرند آن ها را قرمز رنگ می کنیم. با هر بار فشار دادن کلید R صد نقطه تصادفی جدید ایجاد می شود.
from rect import * points = random_points(100) while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_r: points = random_points(100) screen.fill(GRAY) pygame.draw.rect(screen, GREEN, rect, 1) for p in points: if rect.collidepoint(p): pygame.draw.circle(screen, RED, p, 4, 0) else: pygame.draw.circle(screen, BLUE, p, 4, 0) pygame.display.flip() pygame.quit()
متد rect.colliderect (r) بررسی می کند که آیا یک مستطیل با یک مستطیل دیگر برخورد می کند یا نه. در برنامه زیر پنجاه مستطیل تصادفی ایجاد کرده و در صورت برخورد با مستطیل سبز، آن ها را قرمز رنگ می کنیم. با هر بار فشار دادن کلید R صد مستطیل تصادفی جدید ایجاد می شود.
from rect import * n = 50 rects = random_rects(n) while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_r: rects = random_rects(n) screen.fill(GRAY) pygame.draw.rect(screen, GREEN, rect, 1) for r in rects: if rect.colliderect(r): pygame.draw.rect(screen, RED, r, 2) else: pygame.draw.rect(screen, BLUE, r, 1) pygame.display.flip() pygame.quit()
متد rect.colliderect (r) بررسی می کند که آیا یک مستطیل با مستطیل دیگر برخورد می کند یا نه. اگر بخواهیم بدانیم که دو مستطیل با هم تداخل دارند، باید هر دو مستطیل را با یکدیگر مقایسه کنیم. تعداد مقایسه ها به طور توانی افزایش می یابد. هر بار که کلید R فشار داده می شود، 20 مستطیل تصادفی جدید ایجاد می شود.
from rect import * n = 30 rects = random_rects(n) while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_r: rects = random_rects(n) screen.fill(GRAY) intersecting = [] for i in range(n-1): r0 = rects[i] for j in range(i+1, n): r1 = rects[j] if r0.colliderect(r1): intersecting.append(r0) intersecting.append(r1) break for i, r in enumerate(rects): color = RED if r in intersecting else BLUE pygame.draw.rect(screen, color, r) draw_text(str(i), r.topleft) pygame.display.flip() pygame.quit()
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.