در این آموزش، یاد خواهید گرفت که چگونه با استفاده از کتابخانه PyGame یک بازی توپ پرش ساده و در عین حال خنده دار ایجاد کنید.

چه مبتدی باشید که به دنبال درک اصول توسعه بازی هستید یا یک مشتاق به کشف قابلیت های PyGame، این مقاله راهنمای شما برای ساخت یک بازی ساده و در عین حال جذاب است.

شما فقط باید مراحل را بشکنید، کد را بخوانید و از سواری لذت ببرید!

در پایان این آموزش، بازی شما باید به شکل زیر باشد:

پرش_بازی

فهرست مطالب

  1. روش تنظیم محیط توسعه
  2. تعریف مفهوم بازی
  3. مقداردهی اولیه برنامه
  4. چگونه یک نمونه PyGame ایجاد کنیم
  5. روش ایجاد صفحه نمایش بازی
  6. حلقه اصلی بازی
  7. نتیجه

روش تنظیم محیط توسعه

ابزار و نرم افزار

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

پایتون

شما از Python، یک زبان برنامه نویسی همه کاره و مبتدی استفاده خواهید کرد. نحو تمیز و پشتیبانی گسترده از کتابخانه آن را به یک انتخاب عالی برای توسعه بازی تبدیل کرده است.

اگر پایتون را نصب نکرده اید، به ادامه مطلب بروید python.org برای دانلود و نصب آخرین نسخه.

PyGame

سلاح مخفی شما برای این پروژه PyGame، مجموعه ای از ماژول های پایتون، توسعه بازی را با مدیریت عناصر چند رسانه ای مانند تصاویر و صداها ساده می کند. این موتوری است که به بازی شما نیرو می دهد.

برای نصب PyGame می توانید از دستور زیر در خود استفاده کنید terminal یا خط فرمان:

pip install pygame

ویرایشگر متن

خواه VSCode، PyCharm یا Thonny باشد، این محیط ها ویژگی هایی مانند برجسته سازی نحو و ابزارهای اشکال زدایی را ارائه می دهند. یکی را انتخاب کنید که بیشتر با آن راحت هستید، و بیایید برای نوشتن کد آماده شویم!

من از VSCode استفاده خواهم کرد، اما با خیال راحت از هر کدام که دوست دارید استفاده کنید. اگر احساس ماجراجویی می کنید، می توانید تونی را امتحان کنید!

اکنون که به ابزارهای مناسب مجهز شده اید، بیایید وارد کد شویم و بازی خود را زنده کنیم.

اسکرین شات-1
این تونی است

تعریف مفهوم بازی

مفهوم و مکانیک بازی

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

کنترل پلت فرم:

  • هدف: از کلیدهای جهت دار برای حرکت دادن پلت فرم به چپ یا راست استفاده کنید.
  • پیاده سازی: پلت فرم شما به صورت افقی حرکت می کند روی ورودی کلید
  • محدودیت ها: اطمینان حاصل کنید که پلت فرم در محدوده صفحه نمایش باقی می ماند.

دینامیک توپ پرش:

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

سیستم امتیازدهی:

  • هدف: جمع آوری امتیاز بر اساس روی پرش های موفق
  • پیاده سازی: کدگذاری شما سیستم امتیازدهی را تعیین می کند.
  • چالش: مکانیسم امتیازدهی را برای نمرات بالاتر بهینه کنید.

پیشرفت سطح:

  • هدف: با رسیدن امتیاز شما به نقاط عطف، از طریق سطوح پیشرفت کنید.
  • پیاده سازی: با هر 10 امتیاز، به سطح جدیدی پیشرفت می کنید.
  • چالش: انتظار افزایش سختی و پیچیدگی در هر سطح را داشته باشید.

رنگ پلت فرم پویا:

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

زندگی و پایان بازی:

  • هدف: از افتادن توپ از روی صفحه برای حفظ زندگی خودداری کنید.
  • پیاده سازی: زندگی با پرش های از دست رفته کاهش می یابد. بازی زمانی رخ می دهد که زندگی ها تمام می شود (شما فقط 3 زندگی دارید).
  • راه اندازی مجدد: پس از پایان بازی، با سه زندگی و یک امتیاز تازه شروع مجدد کنید.

روش کدنویسی بازی

مقداردهی اولیه برنامه

در این بخش، ثابت هایی مانند ابعاد صفحه، ویژگی های توپ و پلت فرم و رنگ ها را تعریف می کنید.

همچنین PyGame را مقداردهی اولیه می‌کنید، صفحه نمایش را تنظیم می‌کنید و یک شی ساعت برای کنترل نرخ فریم ایجاد می‌کنید.

سپس متغیرهایی را برای بازی، از جمله موقعیت توپ، سرعت، موقعیت سکو، سرعت، امتیاز، زندگی‌ها و سطح فعلی مقداردهی اولیه می‌کنید.

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

import pygame
import sys
import random

# Constants
WIDTH, HEIGHT = 800, 600
BALL_RADIUS = 20
PLATFORM_WIDTH, PLATFORM_HEIGHT = 100, 10
FPS = 60
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
ORANGE = (255, 165, 0)
LIGHT_BLUE = (173, 216, 230)  # Light blue color for the level indicator

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

واردات کتابخانه ها:

  • import pygame: کتابخانه Pygame را وارد می کند که برای توسعه بازی ها در پایتون استفاده می شود.
  • import sys: ماژول sys را وارد می کند و دسترسی به برخی از متغیرهای مورد استفاده یا نگهداری شده توسط مفسر و توابعی که با مفسر تعامل دارند را فراهم می کند.

ثابت ها:

  • WIDTH, HEIGHT = 800, 600: ابعاد پنجره بازی را مشخص می کند.
  • BALL_RADIUS = 20: شعاع توپ پرش را مشخص می کند.
  • PLATFORM_WIDTH, PLATFORM_HEIGHT = 100, 10: ابعاد سکو را تنظیم می کند.
  • FPS = 60: فریم در ثانیه را تعریف می کند و سرعت بازی را کنترل می کند.
  • ثابت رنگ های مختلف مانند BLACK، WHITE، RED، YELLOW، ORANGE، و LIGHT_BLUE نشان دهنده مقادیر RGB برای رنگ های استفاده شده در بازی است.
پیشنهاد می‌کنیم بخوانید:  مقایسه انواع ناسازگار در پایتون

چگونه یک نمونه PyGame ایجاد کنیم

اکنون می‌خواهید پنجره PyGame را ایجاد کنید و چند متغیر جهانی را تعریف کنید که برای هر سطح از بازی استفاده خواهید کرد:

# Initialize Pygame
pygame.init()

# Create the screen
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Bouncing Ball Game")
font = pygame.font.Font(None, 36)

# Clock to control the frame rate
clock = pygame.time.Clock()

# Initialize variables for the game
ball_pos = [WIDTH // 2, HEIGHT // 2]
ball_speed = [random.uniform(2, 4), random.uniform(2, 4)]  # Faster starting speed
platform_pos = [WIDTH // 2 - PLATFORM_WIDTH // 2, HEIGHT - PLATFORM_HEIGHT - 10]
platform_speed = 10
score = 0
lives = 3
current_level = 1
platform_color = ORANGE  # Initialize platform color

راه اندازی Pygame:

  • pygame.init(): کتابخانه Pygame را راه اندازی می کند.

پنجره بازی را ایجاد کنید:

  • screen = pygame.display.set_mode((WIDTH, HEIGHT)): پنجره بازی را با ابعاد مشخص شده ایجاد می کند.
  • pygame.display.set_caption("Bouncing Ball Game"): عنوان پنجره بازی را تنظیم می کند.
  • font = pygame.font.Font(None, 36): یک شی فونت را برای رندر کردن متن راه اندازی می کند.

ساعت برای کنترل نرخ فریم:

  • clock = pygame.time.Clock(): یک شی ساعت برای کنترل نرخ فریم ایجاد می کند.

مقداردهی اولیه متغیرهای بازی:

  • ball_pos = [WIDTH // 2, HEIGHT // 2]: موقعیت شروع توپ را در مرکز صفحه شروع می کند.
  • ball_speed = [random.uniform(2, 4), random.uniform(2, 4)]: سرعت شروع توپ را با مقادیر تصادفی اولیه می کند.
  • platform_pos = [WIDTH // 2 - PLATFORM_WIDTH // 2, HEIGHT - PLATFORM_HEIGHT - 10]: موقعیت شروع پلت فرم را راه اندازی می کند.
  • platform_speed = 10: سرعت حرکت سکو را تنظیم می کند.
  • score = 0: امتیاز بازیکن را مقدار دهی اولیه می کند.
  • lives = 3: تعداد زندگی های بازیکن را مقدار دهی اولیه می کند.
  • current_level = 1: سطح فعلی بازی را مقدار دهی اولیه می کند.
  • platform_color = ORANGE: رنگ پلت فرم را مقدار دهی اولیه می کند.

روش ایجاد صفحه نمایش بازی

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

# Functions for screens
def start_screen():
    screen.fill(BLACK)
    show_text_on_screen("Bouncing Ball Game", 50, HEIGHT // 4)
    show_text_on_screen("Press any key to start...", 30, HEIGHT // 3)
    show_text_on_screen("Move the platform with arrow keys...", 30, HEIGHT // 2)
    pygame.display.flip()
    wait_for_key()

def game_over_screen():
    screen.fill(BLACK)
    show_text_on_screen("Game Over", 50, HEIGHT // 3)
    show_text_on_screen(f"Your final score: {score}", 30, HEIGHT // 2)
    show_text_on_screen("Press any key to restart...", 20, HEIGHT * 2 // 3)
    pygame.display.flip()
    wait_for_key()

def victory_screen():
    screen.fill(BLACK)
    show_text_on_screen("Congratulations!", 50, HEIGHT // 3)
    show_text_on_screen(f"You've won with a score of {score}", 30, HEIGHT // 2)
    show_text_on_screen("Press any key to exit...", 20, HEIGHT * 2 // 3)
    pygame.display.flip()
    wait_for_key()

def wait_for_key():
    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                waiting = False

def show_text_on_screen(text, font_size, y_position):
    font = pygame.font.Font(None, font_size)
    text_render = font.render(text, True, WHITE)
    text_rect = text_render.get_rect(center=(WIDTH // 2, y_position))
    screen.blit(text_render, text_rect)

def change_platform_color():
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

بیایید توابع را مرور کنیم:

start_screen() تابع:

  • صفحه با پس زمینه سیاه را با استفاده از آن پاک می کند screen.fill(BLACK).
  • عنوان بازی و دستورالعمل ها را با استفاده از آن نمایش می دهد show_text_on_screen.
  • نمایشگر را می چرخاند تا تغییرات با آن قابل مشاهده باشد pygame.display.flip().
  • تماس می گیرد wait_for_key() قبل از ادامه، منتظر فشار یک کلید باشید.
تصویر-105

game_over_screen() تابع:

  • صفحه نمایش را با پس زمینه سیاه پاک می کند.
  • بازی را روی پیام، امتیاز نهایی و دستورالعمل‌های شروع مجدد نمایش می‌دهد.
  • نمایشگر را برمیگرداند.
  • تماس می گیرد wait_for_key() منتظر فشار دادن کلید باشید.
تصویر-106

victory_screen() تابع:

  • صفحه نمایش را با پس زمینه سیاه پاک می کند.
  • پیام تبریک، امتیاز نهایی و دستورالعمل خروج را نمایش می دهد.
  • نمایشگر را برمیگرداند.
  • تماس می گیرد wait_for_key() منتظر فشار دادن کلید باشید.

wait_for_key() تابع:

  • منتظر یک رویداد خروج (بستن پنجره بازی) یا یک رویداد فشار دادن کلید است.
  • اگر رویداد در حال ترک است، با استفاده از بازی از بازی خارج می‌شود pygame.quit() و sys.exit().
  • اگر رویداد با فشار دادن کلید باشد، از حلقه انتظار خارج می شود.

show_text_on_screen(text, font_size, y_position) تابع:

  • متن را رندر می کند روی صفحه نمایش با اندازه فونت مشخص شده و موقعیت Y.
  • استفاده می کند pygame.font.Font کلاس برای ایجاد یک شی فونت.
  • متن را روی سطحی با رنگ مشخص شده (در این مورد سفید) رندر می کند.
  • متن را در مرکز صفحه در موقعیت Y مشخص شده قرار می دهد.
  • متن را روی صفحه بازی پخش می کند (کشش می کند).

change_platform_color() تابع:

  • یک رنگ RGB تصادفی را برای تغییر رنگ پلتفرم برمی‌گرداند.

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

حلقه بازی اصلی

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

این طولانی ترین بلوک کد در این آموزش است، بنابراین صبور باشید – ارزشش را دارد.

# Main game loop
start_screen()
game_running = True

while game_running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game_running = False

    keys = pygame.key.get_pressed()

    # Move the platform
    platform_pos[0] += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * platform_speed
    platform_pos[1] += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * platform_speed

    # Ensure the platform stays within the screen boundaries
    platform_pos[0] = max(0, min(platform_pos[0], WIDTH - PLATFORM_WIDTH))
    platform_pos[1] = max(0, min(platform_pos[1], HEIGHT - PLATFORM_HEIGHT))

    # Move the ball
    ball_pos[0] += ball_speed[0]
    ball_pos[1] += ball_speed[1]

    # Bounce off the walls
    if ball_pos[0] <= 0 or ball_pos[0] >= WIDTH:
        ball_speed[0] = -ball_speed[0]

    if ball_pos[1] <= 0:
        ball_speed[1] = -ball_speed[1]

    # Check if the ball hits the platform
    if (
        platform_pos[0] <= ball_pos[0] <= platform_pos[0] + PLATFORM_WIDTH
        and platform_pos[1] <= ball_pos[1] <= platform_pos[1] + PLATFORM_HEIGHT
    ):
        ball_speed[1] = -ball_speed[1]
        score += 1

    # Check if the player advances to the next level
    if score >= current_level * 10:
        current_level += 1
        ball_pos = [WIDTH // 2, HEIGHT // 2]
        ball_speed = [random.uniform(2, 4), random.uniform(2, 4)]  # Randomize the ball speed
        platform_color = change_platform_color()

    # Check if the ball falls off the screen
    if ball_pos[1] >= HEIGHT:
        # Decrease lives
        lives -= 1
        if lives == 0:
            game_over_screen()
            start_screen()  # Restart the game after game over
            score = 0
            lives = 3
            current_level = 1
        else:
            # Reset the ball position
            ball_pos = [WIDTH // 2, HEIGHT // 2]
            # Randomize the ball speed
            ball_speed = [random.uniform(2, 4), random.uniform(2, 4)]

    # Clear the screen
    screen.fill(BLACK)

    # Draw the ball
    pygame.draw.circle(screen, WHITE, (int(ball_pos[0]), int(ball_pos[1])), BALL_RADIUS)

    # Draw the platform
    pygame.draw.rect(screen, platform_color, (int(platform_pos[0]), int(platform_pos[1]), PLATFORM_WIDTH, PLATFORM_HEIGHT))

    # Display information
    info_line_y = 10  # Adjust the vertical position as needed
    info_spacing = 75  # Adjust the spacing as needed

    # Draw the score in an orange rectangle at the top left
    score_text = font.render(f"Score: {score}", True, WHITE)
    score_rect = score_text.get_rect(topleft=(10, info_line_y))
    pygame.draw.rect(screen, ORANGE, score_rect.inflate(10, 5))
    screen.blit(score_text, score_rect)

    # Draw the level indicator in a light-blue rectangle at the top left (next to the score)
    level_text = font.render(f"Level: {current_level}", True, WHITE)
    level_rect = level_text.get_rect(topleft=(score_rect.topright[0] + info_spacing, info_line_y))
    pygame.draw.rect(screen, LIGHT_BLUE, level_rect.inflate(10, 5))
    screen.blit(level_text, level_rect)

    # Draw the lives in a red rectangle at the top left (next to the level)
    lives_text = font.render(f"Lives: {lives}", True, WHITE)
    lives_rect = lives_text.get_rect(topleft=(level_rect.topright[0] + info_spacing, info_line_y))
    pygame.draw.rect(screen, RED, lives_rect.inflate(10, 5))
    screen.blit(lives_text, lives_rect)

    # Update the display
    pygame.display.flip()

    # Control the frame rate
    clock.tick(FPS)

# Quit Pygame
pygame.quit()

بسیار خوب، این مقدار زیادی بود – اما در اینجا چیزی است که ما در کد بالا انجام دادیم:

پیشنهاد می‌کنیم بخوانید:  عملگر Non-Null Assertion در TypeScript

مقداردهی اولیه و صفحه شروع:

  • تماس می گیرد start_screen() برای نمایش صفحه اولیه با دستورالعمل.
  • مجموعه ها game_running به True برای شروع حلقه اصلی بازی.

حلقه اصلی بازی:

  • ادامه دارد تا game_running تبدیل می شود False (مثلا زمانی که کاربر پنجره بازی را می بندد).

مدیریت رویداد:

  • با استفاده از رویدادها را بررسی می کند pygame.event.get().
  • اگر یک رویداد خروج (بستن پنجره بازی) شناسایی شود، تنظیم می شود game_running به False برای خروج از حلقه

جنبش سکو:

  • وضعیت کلیدهای جهت دار را با استفاده از آن می خواند pygame.key.get_pressed().
  • موقعیت پلت فرم را بر اساس تنظیم می کند روی ورودی های کلید فلش
  • اطمینان حاصل می کند که پلت فرم در محدوده های صفحه باقی می ماند.

حرکت توپ و پرش:

  • به روز رسانی موقعیت توپ بر اساس روی سرعت آن
  • جهش از دیوارها را با معکوس کردن سرعت هنگام رسیدن به لبه های صفحه اجرا می کند.

تشخیص برخورد:

  • با مقایسه موقعیت ها بررسی می کند که آیا توپ به سکو برخورد می کند یا خیر.
  • اگر برخوردی رخ دهد، سرعت عمودی توپ معکوس می شود و بازیکن یک امتیاز می گیرد.

پیشرفت سطح:

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

بررسی بازی پایان:

  • اگر توپ از روی صفحه بیفتد نظارت می کند.
  • اگر توپ در زیر صفحه باشد، تعداد زندگی ها را کاهش می دهد.
  • اگر زندگی‌ها تمام شود، بازی را روی صفحه نمایش می‌دهد، بازی را دوباره راه‌اندازی می‌کند و امتیاز، زندگی و سطح را بازنشانی می‌کند.

رندر صفحه نمایش:

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

نمایش به روز رسانی و کنترل نرخ فریم:

  • نمایشگر را برای نمایش تغییرات به روز می کند.
  • نرخ فریم را با clock.tick(FPS).

خاتمه بازی:

  • از PyGame خارج می شود و با خروج از حلقه اصلی برنامه را خاتمه می دهد.

این ساختار گیم پلی مداوم، مدیریت ورودی کاربر، به روز رسانی وضعیت بازی و ارائه بازخورد بصری به بازیکن را تضمین می کند.

نتیجه

در این آموزش، شما در پیچیدگی‌های چندین عملکرد کلیدی که ستون فقرات بازی توپ پرنده شما را تشکیل می‌دهند، پیمایش کرده‌اید.

بیایید نقش آنها را مرور کنیم:

این start_screen() تابع صفحه نمایش را با پس‌زمینه سیاه پاک می‌کند، عنوان بازی و دستورالعمل‌ها را نمایش می‌دهد، نمایشگر را برای مشاهده بر می‌گرداند و منتظر فشار کلید با استفاده از wait_for_key().

این game_over_screen() تابع صفحه را با پس‌زمینه سیاه پاک می‌کند، بازی را روی پیام، امتیاز نهایی و دستورالعمل‌های راه‌اندازی مجدد نمایش می‌دهد، نمایشگر را برمی‌گرداند و منتظر فشار کلید با wait_for_key().

این victory_screen() تابع صفحه را با پس‌زمینه سیاه پاک می‌کند، پیام تبریک، امتیاز نهایی و دستورالعمل‌های خروج را نمایش می‌دهد، نمایشگر را برمی‌گرداند و منتظر فشار کلید با wait_for_key().

این wait_for_key() تابع منتظر یک رویداد خروج (بستن پنجره بازی) یا یک رویداد فشار دادن کلید است. در صورت ترک بازی از بازی خارج می شود و اگر کلیدی فشار داده شود از حلقه انتظار خارج می شود.

این show_text_on_screen(text, font_size, y_position) تابع متن را رندر می کند روی صفحه نمایش با ویژگی های مشخص شده، از pygame.font.Font کلاس برای ایجاد یک شی فونت، و قرار دادن و ترسیم متن در مرکز صفحه.

و change_platform_color() تابع یک رنگ RGB تصادفی را برای تغییر رنگ پلت فرم برمی گرداند.

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

شما شاهد بودید که چگونه این حلقه گیم پلی مداوم، تعاملات کاربر پاسخگو و تصاویر پویا را تضمین می کند.

اکنون که به درک این توابع و حلقه اصلی مجهز شده اید، دانش آزمایش، تغییر دادن و گسترش بازی خود را دارید. احساس قدرت برای سوار شدن کنید روی سفر خود را در توسعه بازی، کشف ویژگی های جدید، و ایجاد تجربه های منحصر به فرد بازی. کد نویسی مبارک!

اگر می خواهید کد را دانلود کنید یا بازی را انجام دهید، می توانید آن را در اینجا پیدا کنید:

GitHub – jpromanonet/bouncing_ball_game: یک بازی که در آن شما یک پلتفرم را کنترل می کنید تا توپ را بدون اینکه اجازه دهید از روی صفحه بیفتد، جهش کند.
یک بازی که در آن شما یک پلت فرم را کنترل می کنید تا توپ را بدون اینکه اجازه دهید از روی صفحه بیفتد، جهش کند. – GitHub – jpromanonet/bouncing_ball_game: یک بازی که در آن شما یک پلتفرم را کنترل می کنید تا توپ را نگه دارید…
پرش_توپ_بازی