ساخت بازی دونده با پایتون (بخش دوم)

Making T-Rex Chrome Dino Game with Python - Part 2

22 آبان 1400
Making-T-Rex-Chrome-Dino-Game-with-Python---Part-2

پیش گفتار

در این بخش بازی دونده را به پایان می بریم. کد بازی و فایل های مربوط به آن را می توانید از نشانی دانلود کنید.

صفحه توقف بازی

در هنگام توقف بازی به خاطر برخورد بازیکن و حلزون دوست داریم که یک صفحه با یک پیام مناسب را به بازیکن نشان دهیم. همچنین دوست داریم امتیاز و تصویر بازیکن را نیز نشان دهیم. برای این کار ابتدا تصویر بازیکن با نام player_stand را وارد برنامه می کنیم و شی rect را برای آن می سازیم:

player_stand=pygame.image.load("graphics/Player/player_stand.png").convert_alpha()
player_stand=pygame.transform.rotozoom(player_stand, 0, 2)
player_stand_rect=player_stand.get_rect(center=(400,200))

به جای نمایش رنگ زرد در هنگام توقف بازی رنگ (94,129,162) را نشان می دهیم:

else:
    SCREEN.fill((94,129,162))
    SCREEN.blit(player_stand,player_stand_rect)

اگر بازی را اجرا کنیم به جای صفحه زرد رنگ تصویر زیر را خواهیم دید:

برای نمایش نام بازی در صفحه توقف کد زیر را می نویسیم:

game_name=game_font.render('Runner ',False,(111,196,169))
game_name_rect=game_name.get_rect(center=(400, 80))

برای نمایش نهایی نام بازی داریم:

else:
    SCREEN.fill((94,129,162))
    SCREEN.blit(player_stand,player_stand_rect)
    SCREEN.blit(game_name,game_name_rect)

با اجرای بازی تصویر زیر را خواهیم دید:

نام بازی در بالای تصویر بازیکن نمایش داده می شود.برای نمایش پیام توقف بازی به بازیکن کد زیر را به برنامه می افزاییم:

game_message=game_font.render('press space to run ',False,(111,196,169))
game_message_rect=game_message.get_rect(center=(400,330))

برای نمایش نهایی این پیغام کد زیر را می نویسیم:

else:
    SCREEN.fill((94,129,162))
    SCREEN.blit(player_stand,player_stand_rect)
    SCREEN.blit(game_name,game_name_rect)
    SCREEN.blit(game_message,game_message_rect)

با اجرای دوباره بازی تصویر زیر را خواهیم دید:

اگر بازیکن هنوز بازی را شروع نکرده باشد دوست داریم پیام press space to run نمایش داده شود و اگر بازی کرده باشد و با حلزون یا پشه برخورد داشته است دوست داریم امتیاز او نشان داده شود. برای انجام این کار ابتدا game_active را False می کنیم:

game_active=False

سپس تغییر زیر را در تابع display_score به وجود می آوریم:

def display_score():
    current_time=int(pygame.time.get_ticks()/1000) - start_time
    score_surface=game_font.render(f'Score : {current_time}',False,(64,64,64))
    score_rect=score_surface.get_rect(center=(400,50))
    SCREEN.blit(score_surface,score_rect)
    return current_time

سپس تغییرهای زیر را در برنامه به کار می بندیم:

if game_active:
    SCREEN.blit(sky_surface,(0,0))
    SCREEN.blit(ground_surface,(0,300))

    score=display_score()

سپس کد زیر را می نویسیم:

else:
    SCREEN.fill((94,129,162))
    SCREEN.blit(player_stand,player_stand_rect)
    SCREEN.blit(game_name,game_name_rect)

    score_surface=game_font.render(f'Your Score is : {score}',False,(111,196,169))
    score_rect=score_surface.get_rect(center=(400,330))

    if score == 0:
        SCREEN.blit(game_message,game_message_rect)
    else:
        SCREEN.blit(score_surface,score_rect)

ساخت مانع ها

تا این جای بازی تنها یک مانع یا حلزون نشان داده می شود.می خواهیم حلزون های متعددی را روی صفحه نمایش بدهیم.برای ساخت حلزون ها یا به طور کلی مانع ها ابتدا به یک زمان سنج یا timer نیاز داریم:

# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer, 1500)

سپس کد زیر را می نویسیم:

if event.type == obstacle_timer and game_active:
    print('test')

با اجرای بازی خواهیم دید که timer کار می کند.برای برقراری اتصال میان timer و مانع ها باید آرایه obstacle_rect_list را بسازیم:

obstacle_rect_list=[]

سپس برای ایجاد مکان های تصادفی باید ماژول random را در ابتدای برنامه وارد کنیم:

from random import randint

سپس تغییر زیر را در کد داریم:

if event.type == obstacle_timer and game_active:
    obstacle_rect_list.append(snail_surface.get_rect(bottomright=(randint(900,1100),300)))

برای ایجاد حرکت در مانع ها تابع obstacle_movement را می نویسیم:

        
# obstacle movement
obstacle_movement(obstacle_rect_list)

سپس باید این تابع را ایجاد کنیم:

def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5

            SCREEN.blit(snail_surface,obstacle_rect)

        return obstacle_list
    else:
        return []

اگر بازی را اجرا کنیم تصویر زیر را خواهیم دید:

کد کامل بازی تا این جا به صورت زیر است:

import pygame,sys
from random import randint

def display_score():
    current_time=int(pygame.time.get_ticks()/1000) - start_time
    score_surface=game_font.render(f'Score : {current_time}',False,(64,64,64))
    score_rect=score_surface.get_rect(center=(400,50))
    SCREEN.blit(score_surface,score_rect)
    return current_time

def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5

            SCREEN.blit(snail_surface,obstacle_rect)

        return obstacle_list
    else:
        return []

pygame.init()

SCREEN=pygame.display.set_mode((800,400))
pygame.display.set_caption("runner game")
Clock=pygame.time.Clock()
game_font=pygame.font.Font('font/Pixeltype.ttf', 50)

sky_surface=pygame.image.load("graphics/Sky.png")
ground_surface=pygame.image.load("graphics/ground.png")

#obstacles
snail_surface=pygame.image.load("graphics/snail/snail1.png").convert_alpha()
snail_rect=snail_surface.get_rect(bottomright=(600,300))

obstacle_rect_list=[]

player_surface=pygame.image.load("graphics/Player/player_walk_1.png").convert_alpha()
player_rect=player_surface.get_rect(midbottom=(80,300))
player_gravity=0

player_stand=pygame.image.load("graphics/Player/player_stand.png").convert_alpha()
player_stand=pygame.transform.rotozoom(player_stand, 0, 2)
player_stand_rect=player_stand.get_rect(center=(400,200))

game_name=game_font.render('Runner ',False,(111,196,169))
game_name_rect=game_name.get_rect(center=(400,80))

game_message=game_font.render('press space to run ',False,(111,196,169))
game_message_rect=game_message.get_rect(center=(400,330))

game_active=False
start_time=0

score=0

# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer, 1500)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if game_active:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and player_rect.bottom >= 300:
                    player_gravity = -20
        else:
                if  event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                    game_active = True
                    snail_rect.left=800
                    start_time=int(pygame.time.get_ticks()/1000)

        if event.type == obstacle_timer and game_active:
            obstacle_rect_list.append(snail_surface.get_rect(bottomright=(randint(900,1100),300)))

    if game_active:
        SCREEN.blit(sky_surface,(0,0))
        SCREEN.blit(ground_surface,(0,300))

        score=display_score()
    
        snail_rect.x -= 4 
        if snail_rect.right <= 0:
            snail_rect.right=800
        SCREEN.blit(snail_surface,snail_rect)

        # player
        player_gravity += 1
        player_rect.y += player_gravity
        if player_rect.bottom >= 300:
            player_rect.bottom=300
        SCREEN.blit(player_surface,player_rect)

        # obstacle movement
        obstacle_rect_list=obstacle_movement(obstacle_rect_list)

        if player_rect.colliderect(snail_rect):
            game_active=False

    else:
        SCREEN.fill((94,129,162))
        SCREEN.blit(player_stand,player_stand_rect)
        SCREEN.blit(game_name,game_name_rect)

        score_surface=game_font.render(f'Your Score is : {score}',False,(111,196,169))
        score_rect=score_surface.get_rect(center=(400,330))

        if score == 0:
            SCREEN.blit(game_message,game_message_rect)
        else:
            SCREEN.blit(score_surface,score_rect)

    pygame.display.update()
    Clock.tick(60)

رفع چند مشکل کوچک

با اجرای بازی خواهیم دید که پس از نخستین برخورد بازیکن و حلزون، دیگر برخوردی بین بازیکن و حلزون رخ نمی دهد و از بازی خارج نمی شویم. مشکل دیگری که داریم این است که پس از خارج شدن حلزون ها از صفحه شی rect آن ها حذف نمی شود. مشکل سوم این است که فقط یک نوع دشمن داریم و دوست داریم که پشه ها را نیز به برنامه اضافه کنیم.

رفع مشکل نخست (حل مشکل برخورد)

برای حل این مشکل تابع collision را ایجاد می کنیم.این تابع در آرایه obstacle_rect_list می گردد و برخورد بازیکن با مانع ها را تشخیص می دهد:

def collisions(player,obstacles):
    if obstacles:
        for obstacle_rect in obstacles:
            if player.colliderect(obstacle_rect):
                return False
    return True

سپس در حلقه بازی داریم:

    # obstacle movement
    obstacle_rect_list=obstacle_movement(obstacle_rect_list)

    game_active=collisions(player_rect,obstacle_rect_list)

else:
    SCREEN.fill((94,129,162))
    SCREEN.blit(player_stand,player_stand_rect)
    SCREEN.blit(game_name,game_name_rect)
    obstacle_rect_list.clear()
    player_rect.midbottom=(80,300)
    player_gravity=0

پس از اجرای بازی خواهیم دید که پس از برخورد بازیکن و حلزون بازی متوقف می شود.

رفع مشکل دوم

برای رفع مشکل دوم یعنی حذف شی rect حلزون ها پس از خروجشان از صفحه داریم: (تغییر زیر را در تابع obstacle_movement انجام می دهیم):

def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5

            SCREEN.blit(snail_surface,obstacle_rect)

        obstacle_list=[obstacle for obstacle in obstacle_list if obstacle.x > 0]

        return obstacle_list
    else:
        return []

رفع مشکل سوم (افزون دشمن جدید)

در پوشه تصاویر یا graphics یک پوشه دیگر به نام Fly داریم که حاوی تصویر دشمن جدیدمان یعنی پشه ها است.در ابتدا تصویر پشه را وارد برنامه می کنیم:

fly_surface=pygame.image.load("graphics/Fly/Fly1.png").convert_alpha()

برای نمایش تصادفی تصویر دشمن ها کدهای زیر را داریم:

if event.type == obstacle_timer and game_active:
    if randint(0,2):
        obstacle_rect_list.append(snail_surface.get_rect(bottomright=(randint(900,1100),300)))
    else:
        obstacle_rect_list.append(fly_surface.get_rect(bottomright=(randint(900,1100),210)))

اگر بازی را اجرا کنیم تصویر پشه نمایش داده نمی شود و به جای آن حلزون نمایش داده  می شود. مانند تصویر زیر:

برای حل این مشکل داریم:

def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5

            if obstacle_rect.bottom == 300:
                SCREEN.blit(snail_surface,obstacle_rect)
            else:
                SCREEN.blit(fly_surface,obstacle_rect)

        obstacle_list=[obstacle for obstacle in obstacle_list if obstacle.x > 0]

        return obstacle_list
    else:
        return []

حالا اگر بازی را اجرا کنیم تصویر زیر را خواهیم دید:

کد بازی تا این لحظه به صورت زیر است:

import pygame,sys
from random import randint

def display_score():
    current_time=int(pygame.time.get_ticks()/1000) - start_time
    score_surface=game_font.render(f'Score : {current_time}',False,(64,64,64))
    score_rect=score_surface.get_rect(center=(400,50))
    SCREEN.blit(score_surface,score_rect)
    return current_time

def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5

            if obstacle_rect.bottom == 300:
                SCREEN.blit(snail_surface,obstacle_rect)
            else:
                SCREEN.blit(fly_surface,obstacle_rect)

        obstacle_list=[obstacle for obstacle in obstacle_list if obstacle.x > 0]

        return obstacle_list
    else:
        return []

def collisions(player,obstacles):
    if obstacles:
        for obstacle_rect in obstacles:
            if player.colliderect(obstacle_rect):
                return False
    return True

pygame.init()

SCREEN=pygame.display.set_mode((800,400))
pygame.display.set_caption("runner game")
Clock=pygame.time.Clock()
game_font=pygame.font.Font('font/Pixeltype.ttf', 50)

sky_surface=pygame.image.load("graphics/Sky.png")
ground_surface=pygame.image.load("graphics/ground.png")

#obstacles
snail_surface=pygame.image.load("graphics/snail/snail1.png").convert_alpha()
fly_surface=pygame.image.load("graphics/Fly/Fly1.png").convert_alpha()

obstacle_rect_list=[]

player_surface=pygame.image.load("graphics/Player/player_walk_1.png").convert_alpha()
player_rect=player_surface.get_rect(midbottom=(80,300))
player_gravity=0

player_stand=pygame.image.load("graphics/Player/player_stand.png").convert_alpha()
player_stand=pygame.transform.rotozoom(player_stand, 0, 2)
player_stand_rect=player_stand.get_rect(center=(400,200))

game_name=game_font.render('Runner ',False,(111,196,169))
game_name_rect=game_name.get_rect(center=(400,80))

game_message=game_font.render('press space to run ',False,(111,196,169))
game_message_rect=game_message.get_rect(center=(400,330))

game_active=False
start_time=0

score=0

# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer, 1500)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if game_active:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and player_rect.bottom >= 300:
                    player_gravity = -20
        else:
                if  event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                    game_active = True
                    # snail_rect.left=800
                    start_time=int(pygame.time.get_ticks()/1000)

        if event.type == obstacle_timer and game_active:
            if randint(0,2):
                obstacle_rect_list.append(snail_surface.get_rect(bottomright=(randint(900,1100),300)))
            else:
                obstacle_rect_list.append(fly_surface.get_rect(bottomright=(randint(900,1100),210)))

    if game_active:
        SCREEN.blit(sky_surface,(0,0))
        SCREEN.blit(ground_surface,(0,300))

        score=display_score()
    
        # snail_rect.x -= 4 
        # if snail_rect.right <= 0:
            # snail_rect.right=800
        # SCREEN.blit(snail_surface,snail_rect)

        # player
        player_gravity += 1
        player_rect.y += player_gravity
        if player_rect.bottom >= 300:
            player_rect.bottom=300
        SCREEN.blit(player_surface,player_rect)

        # obstacle movement
        obstacle_rect_list=obstacle_movement(obstacle_rect_list)

        game_active=collisions(player_rect,obstacle_rect_list)

    else:
        SCREEN.fill((94,129,162))
        SCREEN.blit(player_stand,player_stand_rect)
        SCREEN.blit(game_name,game_name_rect)
        obstacle_rect_list.clear()
        player_rect.midbottom=(80,300)
        player_gravity=0

        score_surface=game_font.render(f'Your Score is : {score}',False,(111,196,169))
        score_rect=score_surface.get_rect(center=(400,330))

        if score == 0:
            SCREEN.blit(game_message,game_message_rect)
        else:
            SCREEN.blit(score_surface,score_rect)

    pygame.display.update()
    Clock.tick(60)

متحرک کردن بازیکن، حلزون و پشه

برای متحرک کردن بازیکن، حلزون و پشه باید تصویر آن ها را ثانیه به ثانیه به روز کنیم. می دانیم که در پویانمایی (انیمیشن) یک تصویر با تصویر دیگر (که اندکی با تصویر اول متفاوت است) در یک چشم به هم زدن جایگزین می شود و این توهم را ایجاد می کند که تصویر حرکت می کند. در این بازی نیز از همین قاعده استفاده می کنیم و تصاویر را با این روش متحرک می کنیم. برای آغاز کار باید همه تصویر های مربوط به بازیکن، حلزون و پشه را وارد برنامه کنیم(تصویر بازیکن را با کدهای زیر جایگزین می کنیم):

player_walk_1=pygame.image.load("graphics/Player/player_walk_1.png").convert_alpha()
player_walk_2=pygame.image.load("graphics/Player/player_walk_2.png").convert_alpha()
player_walk=[player_walk_1,player_walk_2]
player_index=0
player_jump=pygame.image.load("graphics/Player/jump.png").convert_alpha()

player_surface=player_walk[player_index]
player_rect=player_surface.get_rect(midbottom=(80,300))
player_gravity=0

برای متحرک کردن تصویر ها تابع  player_animation را به صورت زیر می سازیم:

def player_animation():
    global player_surface,player_index

    if player_rect.bottom < 300:
        player_surface = player_jump
    else:
        player_index += 0.1
        if player_index >= len(player_walk):
            player_index=0
        player_surface = player_walk[int(player_index)]

اگر بازیکن در حال راه رفتن است باید تصاویر راه رفتن و اگر در حال پریدن است باید تصویر پریدن نمایش داده شود. در بالا این شرط را بررسی می کنیم. سپس باید تابع زیر را برای متحرک کردن تصویر بازیکن فراخوانی می کنیم:

# player
player_gravity += 1
player_rect.y += player_gravity
if player_rect.bottom >= 300:
    player_rect.bottom=300
player_animation()

متحرک کردن دشمنان (پشه ها و حلزون ها)

تصاویر حلزون و پشه ها را وارد به صورت زیر در برنامه وارد می کنیم:

#snail
snail_frame1=pygame.image.load("graphics/snail/snail1.png").convert_alpha()
snail_frame2=pygame.image.load("graphics/snail/snail2.png").convert_alpha()
snail_frames=[snail_frame1,snail_frame2]
snail_frame_index=0
snail_surface=snail_frames[snail_frame_index]

# fly
fly_frame1=pygame.image.load("graphics/Fly/Fly1.png").convert_alpha()
fly_frame2=pygame.image.load("graphics/Fly/Fly2.png").convert_alpha()
fly_frames=[fly_frame1,fly_frame2]
fly_frame_index=0
fly_surface=fly_frames[fly_frame_index]

سپس باید برای آن ها timer (زمان سنج) بسازیم:

# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer, 1500)

snail_animation_timer=pygame.USEREVENT + 2
pygame.time.set_timer(snail_animation_timer, 500)

fly_animation_timer=pygame.USEREVENT + 3
pygame.time.set_timer(fly_animation_timer, 200)

علت استفاده از timer این است که حلزون ها و پشه ها نباید پشت سر هم وارد بازی شوند. ابتدا باید یک حلزون(پشه) وارد شود، اندک زمانی بگذرد سپس حلزون (پشه) بعدی وارد بازی بشود. برای انجام این کار باید timer های مربوط به حلزون و پشه را به روزآوری کنیم. در زیر timer حلزون را به روز می کنیم:

if game_active:
            if event.type == obstacle_timer:
                if randint(0,2):
                    obstacle_rect_list.append(snail_surface.get_rect(bottomright=(randint(900,1100),300)))
                else:
                    obstacle_rect_list.append(fly_surface.get_rect(bottomright=(randint(900,1100),210)))
            if event.type == snail_animation_timer:
                if snail_frame_index == 0:
                    snail_frame_index=1
                else:
                    snail_frame_index=1
                snail_surface=snail_frames[snail_frame_index]

سپس timer مربوط به پشه را به روزآوری می کنیم:

if event.type == fly_animation_timer:
    if fly_frame_index == 0: fly_frame_index = 1
    else: fly_frame_index = 0
    fly_surface = fly_frames[fly_frame_index] 

اگر بازی را اجرا کنیم خواهیم دید که حلزون و پشه متحرک شده اند.کد کامل بازی تا این لحظه به صورت زیر است:

import pygame,sys
from random import randint

def display_score():
    current_time=int(pygame.time.get_ticks()/1000) - start_time
    score_surface=game_font.render(f'Score : {current_time}',False,(64,64,64))
    score_rect=score_surface.get_rect(center=(400,50))
    SCREEN.blit(score_surface,score_rect)
    return current_time

def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5

            if obstacle_rect.bottom == 300:
                SCREEN.blit(snail_surface,obstacle_rect)
            else:
                SCREEN.blit(fly_surface,obstacle_rect)

        obstacle_list=[obstacle for obstacle in obstacle_list if obstacle.x > 0]

        return obstacle_list
    else:
        return []

def collisions(player,obstacles):
    if obstacles:
        for obstacle_rect in obstacles:
            if player.colliderect(obstacle_rect):
                return False
    return True

def player_animation():
    global player_surface,player_index

    if player_rect.bottom < 300:
        player_surface = player_jump
    else:
        player_index += 0.1
        if player_index >= len(player_walk):
            player_index=0
        player_surface = player_walk[int(player_index)]

pygame.init()

SCREEN=pygame.display.set_mode((800,400))
pygame.display.set_caption("runner game")
Clock=pygame.time.Clock()
game_font=pygame.font.Font('font/Pixeltype.ttf', 50)

sky_surface=pygame.image.load("graphics/Sky.png")
ground_surface=pygame.image.load("graphics/ground.png")

# Snail 
snail_frame_1 = pygame.image.load('graphics/snail/snail1.png').convert_alpha()
snail_frame_2 = pygame.image.load('graphics/snail/snail2.png').convert_alpha()
snail_frames = [snail_frame_1, snail_frame_2]
snail_frame_index = 0
snail_surface = snail_frames[snail_frame_index]

# Fly
fly_frame1 = pygame.image.load('graphics/fly/fly1.png').convert_alpha()
fly_frame2 = pygame.image.load('graphics/fly/fly2.png').convert_alpha()
fly_frames = [fly_frame1, fly_frame2]
fly_frame_index = 0
fly_surface = fly_frames[fly_frame_index]

obstacle_rect_list=[]

player_walk_1=pygame.image.load("graphics/Player/player_walk_1.png").convert_alpha()
player_walk_2=pygame.image.load("graphics/Player/player_walk_2.png").convert_alpha()
player_walk=[player_walk_1,player_walk_2]
player_index=0
player_jump=pygame.image.load("graphics/Player/jump.png").convert_alpha()

player_surface=player_walk[player_index]
player_rect=player_surface.get_rect(midbottom=(80,300))
player_gravity=0

player_stand=pygame.image.load("graphics/Player/player_stand.png").convert_alpha()
player_stand=pygame.transform.rotozoom(player_stand, 0, 2)
player_stand_rect=player_stand.get_rect(center=(400,200))

game_name=game_font.render('Runner ',False,(111,196,169))
game_name_rect=game_name.get_rect(center=(400,80))

game_message=game_font.render('press space to run ',False,(111,196,169))
game_message_rect=game_message.get_rect(center=(400,330))

game_active=False
start_time=0

score=0

# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer, 1500)

snail_animation_timer=pygame.USEREVENT + 2
pygame.time.set_timer(snail_animation_timer, 500)

fly_animation_timer=pygame.USEREVENT + 3
pygame.time.set_timer(fly_animation_timer, 200)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if game_active:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if player_rect.collidepoint(event.pos) and player_rect.bottom >= 300: 
                    player_gravity = -20

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and player_rect.bottom >= 300:
                    player_gravity = -20
        else:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                game_active = True
                start_time = int(pygame.time.get_ticks() / 1000)

        if game_active:
            if event.type == obstacle_timer:
                if randint(0,2):
                    obstacle_rect_list.append(snail_surface.get_rect(bottomright = (randint(900,1100),300)))
                else:
                    obstacle_rect_list.append(fly_surface.get_rect(bottomright = (randint(900,1100),210)))

            if event.type == snail_animation_timer:
                if snail_frame_index == 0: snail_frame_index = 1
                else: snail_frame_index = 0
                snail_surface = snail_frames[snail_frame_index] 

            if event.type == fly_animation_timer:
                if fly_frame_index == 0: fly_frame_index = 1
                else: fly_frame_index = 0
                fly_surface = fly_frames[fly_frame_index] 

    if game_active:
        SCREEN.blit(sky_surface,(0,0))
        SCREEN.blit(ground_surface,(0,300))
        score = display_score()
        
        # snail_rect.x -= 4
        # if snail_rect.right <= 0: snail_rect.left = 800
        # SCREEN.blit(snail_surf,snail_rect)

        # Player 
        player_gravity += 1
        player_rect.y += player_gravity
        if player_rect.bottom >= 300: player_rect.bottom = 300
        player_animation()
        SCREEN.blit(player_surface,player_rect)

        # Obstacle movement 
        obstacle_rect_list = obstacle_movement(obstacle_rect_list)

        # collision 
        game_active = collisions(player_rect,obstacle_rect_list)
        
    else:
        SCREEN.fill((94,129,162))
        SCREEN.blit(player_stand,player_stand_rect)
        obstacle_rect_list.clear()
        player_rect.midbottom = (80,300)
        player_gravity = 0

        score_message = game_font.render(f'Your score: {score}',False,(111,196,169))
        score_message_rect = score_message.get_rect(center = (400,330))
        SCREEN.blit(game_name,game_name_rect)

        if score == 0: SCREEN.blit(game_message,game_message_rect)
        else: SCREEN.blit(score_message,score_message_rect)

    pygame.display.update()
    Clock.tick(60)

افزودن موسیقی به بازی

استفاده از موسیقی بسیار ساده است. برای استفاده از موسیقی ابتدا باید آن را وارد برنامه کرده سپس آن را پخش کنیم. در این بازی دو نوع صدا داریم: صدا پرش بازیکن و صدا پشت زمینه بازی. ابتدا صدای پرش را وارد برنامه می کنیم:

jump_sound=pygame.mixer.Sound('audio/jump.mp3')
jump_sound.set_volume(0.5)

برای پخش صدا از pygame.mixer.Sound استفاده می کنیم.این متد یک شی Sound جدید از فایل صوتی ایجاد می کند.از این شی برای پخش صدا استفاده می کنیم. از set_volume برای تنظیم میزان صدا فایل صوتی استفاده می کنیم. در این جا مقدار آن را 0.5 داده ایم. در هنگام پرش بازیکن این صدا باید پخش شود:

if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_SPACE and player_rect.bottom >= 300:
        player_gravity = -20
        jump_sound.play()

سپس باید صدای پشت زمینه را وارد برنامه کنیم:

bg_music=pygame.mixer.Sound('audio/music.wav')
bg_music.play(loops=-1)

با اجرای بازی می توانیم موسیقی پشت زمینه و صدای پرش را بشنویم.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری بازی‌سازی با پایتون توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.