ورقة مرجعية pygame
آخر تحديث
الإعداد وحلقة اللعبة
كل برنامج pygame يفتح نافذة، ثم يكرر حلقة واحدة حتى يخرج اللاعب.
| العملية | الكود |
|---|---|
| تثبيت pygame-ce | python3 -m pip install pygame-ce |
| استيراد pygame وتشغيلها | import pygame
pygame.init() |
| فتح نافذة | screen = pygame.display.set_mode((640, 480)) |
| تعيين عنوان النافذة | pygame.display.set_caption("My Game") |
| إنشاء ساعة | clock = pygame.time.Clock() |
| حلقة اللعبة | running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill("black")
pygame.display.flip()
clock.tick(60) |
| الإغلاق بعد انتهاء الحلقة | pygame.quit() |
الشاشة
الشاشة هي Surface، ولا يظهر شيء حتى تستدعي flip.
| العملية | الكود |
|---|---|
| عرض الإطار المكتمل | pygame.display.flip() |
| تحديث مناطق محددة فقط | pygame.display.update([rect1, rect2]) |
| مسح الشاشة | screen.fill((30, 30, 46)) |
| حجم النافذة | screen.get_size(), screen.get_width() |
| الشاشة على شكل Rect | screen.get_rect() |
| نافذة قابلة لتغيير الحجم | pygame.display.set_mode((640, 480), pygame.RESIZABLE) |
| ملء الشاشة بحجم سطح المكتب | pygame.display.set_mode((0, 0), pygame.FULLSCREEN) |
الألوان والرسم
دوال pygame.draw تأخذ سطحًا ولونًا وموضعًا. القيمة width=0 تملأ الشكل.
| العملية | الكود |
|---|---|
| اللون بصيغة RGB | (255, 140, 0) |
| اللون بالاسم أو بالصيغة الست عشرية | "tomato", "#ff8c00", pygame.Color("gold") |
| مستطيل | pygame.draw.rect(screen, "red", (x, y, w, h)) |
| إطار وزوايا مستديرة | pygame.draw.rect(screen, "red", rect, width=2, border_radius=8) |
| دائرة (حسب مركزها) | pygame.draw.circle(screen, "blue", (cx, cy), radius) |
| خط | pygame.draw.line(screen, "white", (x1, y1), (x2, y2), 3) |
| مضلع | pygame.draw.polygon(screen, "green", [(0, 0), (40, 0), (20, 30)]) |
| قطع ناقص داخل مستطيل | pygame.draw.ellipse(screen, "purple", (x, y, w, h)) |
Rect
يخزّن Rect موضعًا وحجمًا بأعداد صحيحة.
| العملية | الكود |
|---|---|
| إنشاء Rect | player = pygame.Rect(x, y, width, height) |
| تحديد الموضع بأي نقطة | player.center = (320, 240), player.bottom = 400 |
| الحواف والزوايا | left, right, top, bottom, topleft, midbottom |
| التحريك في المكان | player.move_ip(dx, dy) |
| نسخة محرّكة | moved = player.move(dx, dy) |
| الإبقاء داخل الشاشة | player.clamp_ip(screen.get_rect()) |
| التكبير حول المركز | bigger = player.inflate(20, 20) |
| مواضع عشرية (pygame-ce) | pygame.FRect(10.5, 20.25, 40, 40) |
الصور وSurface وblit
حمّل الصور مرة واحدة قبل الحلقة، ثم ارسمها بـ blit في كل إطار.
| العملية | الكود |
|---|---|
| تحميل صورة مع الشفافية | img = pygame.image.load("player.png").convert_alpha() |
| تحميل صورة بلا شفافية | bg = pygame.image.load("sky.png").convert() |
| رسم صورة | screen.blit(img, (x, y)) |
| الرسم في المنتصف | screen.blit(img, img.get_rect(center=(320, 240))) |
| Surface فارغ جديد | panel = pygame.Surface((200, 100)) |
| Surface شفاف | layer = pygame.Surface((200, 100), pygame.SRCALPHA) |
| جعل Surface كاملًا شبه شفاف | img.set_alpha(128) |
| قص إطار من ورقة sprites | frame = sheet.subsurface((0, 0, 32, 32)) |
| حفظ لقطة شاشة | pygame.image.save(screen, "shot.png") |
التحويل
كل دالة تعيد Surface جديدًا، فحوّل الصورة الأصلية لا آخر نتيجة.
| العملية | الكود |
|---|---|
| تغيير الحجم | pygame.transform.scale(img, (64, 64)) |
| التكبير بمعامل | pygame.transform.scale_by(img, 2) |
| تغيير الحجم بنعومة | pygame.transform.smoothscale(img, (64, 64)) |
| التدوير (عكس عقارب الساعة، بالدرجات) | pygame.transform.rotate(img, 45) |
| التدوير حول المركز | rotated = pygame.transform.rotate(original, angle)
rect = rotated.get_rect(center=rect.center) |
| قلب أفقي | pygame.transform.flip(img, True, False) |
الأحداث ولوحة المفاتيح
استخدم الأحداث للضغطات المفردة، وget_pressed() للمفاتيح التي تبقى مضغوطة.
| العملية | الكود |
|---|---|
| قراءة أحداث هذا الإطار | for event in pygame.event.get(): |
| أُغلقت النافذة | event.type == pygame.QUIT |
| ضُغط مفتاح | event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE |
| أُفلت مفتاح | event.type == pygame.KEYUP |
| الحرف المكتوب | event.unicode |
| المفاتيح المضغوطة الآن | keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= 5 |
| الاتجاه من مفتاحين | dx = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT] |
| المفاتيح المضغوطة في هذا الإطار (pygame-ce) | pygame.key.get_just_pressed()[pygame.K_SPACE] |
| ثوابت المفاتيح | K_a...K_z, K_0...K_9, K_UP, K_RETURN, K_ESCAPE, K_LSHIFT |
| اسم المفتاح | pygame.key.name(event.key) |
| حدث مخصص | HIT = pygame.event.custom_type()
pygame.event.post(pygame.event.Event(HIT)) |
الفأرة
الأزرار: 1 الأيسر، 2 الأوسط، 3 الأيمن.
| العملية | الكود |
|---|---|
| ضُغط زر | event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 |
| مكان الضغط | event.pos |
| موضع المؤشر الآن | x, y = pygame.mouse.get_pos() |
| الأزرار المضغوطة الآن | left, middle, right = pygame.mouse.get_pressed() |
| تحركت الفأرة | event.type == pygame.MOUSEMOTION, event.rel |
| دارت العجلة | event.type == pygame.MOUSEWHEEL, event.y |
| نقر داخل زر | button_rect.collidepoint(event.pos) |
| إخفاء المؤشر | pygame.mouse.set_visible(False) |
الـ Sprites والمجموعات
يحمل الـ sprite قيمتي image وrect، والمجموعة تحدّث الكثير منها وترسمها معًا.
| العملية | الكود |
|---|---|
| صنف sprite | class Coin(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = coin_img
self.rect = self.image.get_rect(center=pos) |
| إنشاء مجموعة | coins = pygame.sprite.Group() |
| الإضافة إلى مجموعة | coins.add(Coin((100, 50))) |
| تحديث كل الـ sprites | coins.update() |
| رسم كل الـ sprites | coins.draw(screen) |
| إزالة sprite من كل المجموعات | coin.kill() |
| مجموعة تحمل sprite واحدًا | player = pygame.sprite.GroupSingle(Player()) |
التصادم
يتصادم Rect مع آخر عندما يتداخلان، أما الحواف المتلامسة فلا تُحسب.
| العملية | الكود |
|---|---|
| مستطيلان | a.colliderect(b) |
| نقطة بالداخل | rect.collidepoint(x, y) |
| الأول من بين عدة مستطيلات | rect.collidelist(walls) # index or -1 |
| sprite مقابل مجموعة | hits = pygame.sprite.spritecollide(player, coins, True) |
| هل حدث أي تصادم | pygame.sprite.spritecollideany(player, enemies) |
| مجموعة مقابل مجموعة | pygame.sprite.groupcollide(bullets, enemies, True, True) |
| بدقة البكسل | pygame.sprite.spritecollide(a, group, False, pygame.sprite.collide_mask) |
| دوائر | pygame.Vector2(a).distance_to(b) < r1 + r2 |
النص والخطوط
ارسم النص على Surface، ثم ضعه على الشاشة بـ blit.
| العملية | الكود |
|---|---|
| الخط الافتراضي | font = pygame.font.Font(None, 36) |
| خط من النظام | font = pygame.font.SysFont("arial", 24) |
| ملف خط | font = pygame.font.Font("pixel.ttf", 32) |
| رسم النص | text = font.render("Score: 10", True, "white") |
| رسمه في المنتصف | screen.blit(text, text.get_rect(center=(320, 40))) |
| التفاف النص الطويل (pygame-ce) | font.render(story, True, "white", None, 400) |
| معرفة الحجم دون رسم | font.size("Hello") |
| الخطوط المثبتة | pygame.font.get_fonts() |
الأصوات والموسيقى
حمّل الأصوات مرة واحدة. الموسيقى تُبث مقطعًا واحدًا من ملفه.
| العملية | الكود |
|---|---|
| تحميل صوت | jump = pygame.mixer.Sound("jump.ogg") |
| تشغيله | jump.play() |
| مستوى صوت المؤثر | jump.set_volume(0.5) |
| تحميل الموسيقى | pygame.mixer.music.load("theme.ogg") |
| تكرار الموسيقى بلا توقف | pygame.mixer.music.play(-1) |
| الإيقاف المؤقت والاستئناف | pygame.mixer.music.pause(), pygame.mixer.music.unpause() |
| إيقاف الموسيقى | pygame.mixer.music.stop() |
الوقت والمؤقتات
تُقاس النبضات (ticks) بالمللي ثانية.
| العملية | الكود |
|---|---|
| تحديد معدل الإطارات | clock.tick(60) |
| الزمن بين الإطارات بالثواني | dt = clock.tick(60) / 1000 |
| معدل الإطارات الحالي | clock.get_fps() |
| المللي ثواني منذ init | pygame.time.get_ticks() |
| حدث مؤقت متكرر | SPAWN = pygame.event.custom_type()
pygame.time.set_timer(SPAWN, 1000) |
| مؤقت لمرة واحدة | pygame.time.set_timer(SPAWN, 2000, loops=1) |
| إيقاف المؤقت | pygame.time.set_timer(SPAWN, 0) |
Vector2
أعداد عشرية للمواضع والسرعات.
| العملية | الكود |
|---|---|
| إنشاء متجه | pos = pygame.Vector2(100, 200) |
| التحريك بالسرعة | pos += velocity * dt |
| الطول | velocity.length() |
| السرعة نفسها على الأقطار | if direction.length() > 0:
direction = direction.normalize() |
| المسافة بين نقطتين | pos.distance_to(target) |
| التدوير | velocity.rotate(90) |
| التقدم نحو نقطة (pygame-ce) | pos.move_towards_ip(target, 5) |
هذه أكواد pygame التي تحتاجها عند صنع لعبة ثنائية الأبعاد بلغة Python، مرتبة حسب المهمة: حلقة اللعبة، والشاشة، والألوان والرسم، وRect، والصور وblit، وتغيير الحجم والتدوير، وإدخال لوحة المفاتيح والفأرة، والـ sprites والمجموعات، والتصادم، والنص، والصوت، والمؤقتات، وVector2. في كل صف مقتطف قصير جاهز للصق، ومعه ما يفعله.
كل ما هنا مكتوب لـ pygame-ce 2.5، وهي النسخة المجتمعية من pygame، وما زلت تستوردها بـ import pygame. الصفوف التي تحمل علامة pygame-ce تستخدم إضافاتها، وكل الصفوف الأخرى تعمل أيضًا في pygame الأصلية. جرّب أي مقتطف في ساحة تجربة pygame، التي تشغّل pygame في متصفحك دون أي تثبيت. هل أنت جديد على Python نفسها؟ ابدأ بـ الورقة المرجعية لـ Python.
أسئلة شائعة عن ورقة pygame المرجعية
هل هذه الورقة المرجعية لـ pygame مجانية؟
نعم. إنها مجانية ولا تحتاج إلى تسجيل. احفظها في المفضلة، أو اطبعها بصيغة PDF من متصفحك، وارجع إليها كلما احتجت إلى الاستدعاء الدقيق لمجموعة sprites أو صوت أو فحص تصادم.
هل تعمل هذه الورقة المرجعية مع pygame وpygame-ce؟
import pygame وتتشاركان الواجهة البرمجية كلها تقريبًا. الصفوف التي تحمل علامة pygame-ce (FRect وscale_by وget_just_pressed والتفاف النص وmove_towards_ip) تحتاج إلى pygame-ce، وكل ما عداها يعمل على أي منهما.لماذا لا تستجيب نافذة pygame عندي؟
pygame.event.get() مرة في كل إطار حتى لو تجاهلت الأحداث، واختم كل إطار بـ pygame.display.flip() وclock.tick(60).هل أستخدم الأحداث أم key.get_pressed() للإدخال؟
KEYDOWN للأفعال التي تحدث مرة واحدة مع كل ضغطة، مثل القفز أو فتح قائمة. واستخدم pygame.key.get_pressed() للأفعال التي تستمر ما دام المفتاح مضغوطًا، مثل المشي.