Menu
CoddyTech

موسيقى لكل حالة

جزء من قسم الصوت وإحساس اللعب في رحلة Pygame على Coddy. الدرس 6 من 23.

يمكن أن تكون لكل حالة من حالات اللعبة موسيقاها الخاصة: لحن هادئ في القائمة، ومقطوعة حيوية أثناء اللعب، ونغمة قصيرة عند الفوز أو الخسارة. للتبديل، حمّل المقطوعة الجديدة وشغّلها. تحميل مقطوعة جديدة يوقف القديمة. تحافظ دالة صغيرة على السطرين معًا:

def play_music(path, loops=-1):
    pygame.mixer.music.load(path)
    pygame.mixer.music.play(loops)

بدّل الموسيقى لحظة تغيّر الحالة، في السطر الذي يعيّن state:

if player.colliderect(goal):
    state = "win"
    play_music("assets/music/win.ogg", 0)

يُنفَّذ هذا السطر مرة واحدة، لذا تبدأ المقطوعة مرة واحدة. لا تبدّل الموسيقى داخل if state == "win": في جزء الرسم: فهذا يُنفَّذ في كل إطار ويعيد تشغيل المقطوعة 60 مرة في الثانية.

نغمتا الفوز والخسارة قصيرتان وتنتهيان من تلقاء نفسيهما، لذا تكون قيمة loops لهما 0. أما لحن القائمة ومقطوعة المستوى فيتكرران باستخدام -1.

challenge icon

التحدي

متوسط

يبدأ الضغط على Enter اللعبة؛ ويفوز المربع الأزرق عند الهدف الأخضر ويخسر في الحمم. خصّص موسيقى لكل حالة:

  1. اكتب play_music(path, loops=-1) لتحميل مقطع موسيقي وتشغيله.
  2. قبل الحلقة، شغّل assets/music/theme.ogg.
  3. عندما تصبح الحالة "play"، شغّل assets/music/level.ogg.
  4. عندما تصبح الحالة "win"، شغّل assets/music/win.ogg مرة واحدة (loops 0)؛ وبالنسبة إلى "lose"، شغّل assets/music/lose.ogg مرة واحدة.
  5. عندما يعيدك Enter إلى "menu"، شغّل theme.ogg مجددًا.

جرّب بنفسك

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Lava Run")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)

player = pygame.Rect(40, 160, 30, 30)
goal = pygame.Rect(420, 160, 30, 30)
lava = pygame.Rect(0, 320, 480, 40)
state = "menu"

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
            if state == "menu":
                state = "play"
                player.topleft = (40, 160)
            elif state in ("win", "lose"):
                state = "menu"

    if state == "play":
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            player.x -= 4
        if keys[pygame.K_RIGHT]:
            player.x += 4
        if keys[pygame.K_UP]:
            player.y -= 4
        if keys[pygame.K_DOWN]:
            player.y += 4
        player.clamp_ip(screen.get_rect())
        if player.colliderect(goal):
            state = "win"
        elif player.colliderect(lava):
            state = "lose"

    screen.fill((30, 30, 46))
    if state == "menu":
        title = font.render("Press Enter to start", True, (240, 240, 240))
        screen.blit(title, title.get_rect(center=(240, 180)))
    else:
        pygame.draw.rect(screen, (230, 90, 40), lava)
        pygame.draw.rect(screen, (90, 200, 120), goal)
        pygame.draw.rect(screen, (80, 160, 255), player)
        if state == "win":
            message = font.render("You win!", True, (240, 240, 240))
            screen.blit(message, message.get_rect(center=(240, 100)))
        elif state == "lose":
            message = font.render("Game over", True, (240, 240, 240))
            screen.blit(message, message.get_rect(center=(240, 100)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

جميع دروس الصوت وإحساس اللعب

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