FA-TOOLS — Header Component

آموزش ساخت بازی Snake با پایتون و Pygame

سلام رفیق برنامه‌نویس! اگه همیشه دوست داشتی یه بازی کلاسیک مثل Snake رو خودت بسازی و از صفر تا صدش رو تجربه کنی، جای درستی اومدی. پایتون با Pygame یه ترکیب فوق‌العاده برای شروع بازی‌سازی هست که هم یادگیریش آسونه و هم می‌تونی باهاش ایده‌های خلاقانه‌ت رو پیاده کنی. توی این آموزش، قراره قدم به قدم با هم یه بازی مار نوستالژیک رو بسازیم و لذت برنامه‌نوسی رو کنار هم بچشیم. پس بزن بریم که یه تجربه هیجان‌انگیز رو شروع کنیم!
اگه دنبال ابزارها و کدهای آماده پایتون هستی که پروژه‌هات رو سریع‌تر پیش ببری، حتماً یه سری به بخش اسنیپت‌های پایتون و صفحه اصلی fa-tools.ir بزن؛ کلی کد به درد بخور اونجا منتظرته تا کارتو راحت‌تر کنه!

🚀 نقشه راه سریع ساخت بازی Snake با پایتن!


  • ۱. آماده‌سازی: نصب Pygame و ایجاد پنجره اولیه بازی.
  • 🐍
    ۲. مار و غذا: تعریف گرافیک مار، غذا و تعیین محل تصادفی.
  • ➡️
    ۳. حرکت و کنترل: منطق حرکت مار بر اساس ورودی کاربر (کلیدها).
  • 💥
    ۴. برخوردها: تشخیص برخورد با دیوار، خود مار و غذا.
  • 💯
    ۵. امتیازدهی: نمایش امتیاز و مدیریت صفحه پایان بازی.
  • 🛠️
    ۶. عیب‌یابی: راه حل مشکلات رایج و نکات بهینه‌سازی.

چرا پایتون و Pygame برای شروع بازی‌سازی بهترین انتخابه؟

آموزش ساخت بازی Snake با پایتون و pygame — تصویر 1

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

آماده‌سازی محیط توسعه: اولین قدم‌های تو

آموزش ساخت بازی Snake با پایتون و pygame — تصویر 2

قبل از هر چیز، باید مطمئن بشیم که همه ابزارهای لازم رو در اختیار داریم. نگران نباش، کار سختی نیست و خیلی سریع انجام میشه.

۱. نصب پایتون

اگه پایتون رو هنوز نصب نکردی، می‌تونی از سایت رسمی python.org آخرین نسخه رو دانلود و نصب کنی. مطمئن شو که موقع نصب، تیک گزینه “Add Python to PATH” رو زدی تا بتونی راحت ازش تو ترمینال استفاده کنی.

۲. نصب Pygame

حالا که پایتون رو داری، نوبت Pygame هست. یه ترمینال یا Command Prompt باز کن و دستور زیر رو تایپ و اجرا کن:


pip install pygame

اگه همه چی خوب پیش بره، Pygame نصب میشه و آماده استفاده هستی.

۳. اولین کد: پنجره خالی بازی

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


import pygame

# ۱. Pygame رو مقداردهی اولیه می‌کنیم
pygame.init()

# ۲. ابعاد پنجره بازی رو تعریف می‌کنیم
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

# ۳. عنوان پنجره رو تنظیم می‌کنیم
pygame.display.set_caption("بازی مار با پایتون و Pygame")

# ۴. متغیر برای حلقه اصلی بازی
running = True

# ۵. حلقه اصلی بازی
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: # اگه کاربر روی دکمه بستن کلیک کرد
            running = False

    # اینجا میشه کارهای دیگه ای مثل نقاشی کردن انجام داد
    screen.fill((0, 0, 0)) # صفحه رو با رنگ مشکی پر می‌کنیم

    # ۶. به‌روزرسانی نمایش
    pygame.display.flip()

# ۷. خروج از Pygame
pygame.quit()
نکته: این کد یه پنجره مشکی رو باز می‌کنه. اگه این پنجره رو دیدی و تونستی با دکمه X ببندیش، تبریک! اولین قدم رو با موفقیت برداشتی.

طراحی اجزای اصلی بازی: مار و غذا

آموزش ساخت بازی Snake با پایتون و pygame — تصویر 3

حالا که پنجره بازی رو داریم، وقتشه که مهم‌ترین اجزای بازی، یعنی مار و غذا رو بهش اضافه کنیم.

۱. تعریف رنگ‌ها و ابعاد

برای اینکه کدهامون مرتب و خوانا باشن، بهتره رنگ‌ها و ابعاد ثابت رو در قالب متغیر تعریف کنیم.


import pygame
import random # برای تولید موقعیت تصادفی غذا

pygame.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("بازی مار با پایتون و Pygame")

# تعریف رنگ‌ها (RGB)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# ابعاد بلوک‌های بازی
BLOCK_SIZE = 20

# متغیرهای سرعت بازی
SNAKE_SPEED = 10
clock = pygame.time.Clock()

۲. ساخت مار

مار در واقع یه لیست از مختصات (x, y) هست که هر مختصات، یک قسمت از بدن مار رو نشون میده. اولین عنصر لیست، سر مار و بقیه، بدن مار هستن.


# موقعیت اولیه مار
snake = [(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)] # سر مار در مرکز
snake_direction = "RIGHT" # جهت اولیه حرکت مار

۳. ساخت غذا

غذا باید به صورت تصادفی در هر جای صفحه (به جز جایی که مار هست) ظاهر بشه.


def generate_food_position():
    x = random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE, BLOCK_SIZE)
    y = random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE, BLOCK_SIZE)
    return (x, y)

food_position = generate_food_position()
متغیر توضیح
SCREEN_WIDTH, SCREEN_HEIGHT ابعاد پنجره بازی
BLOCK_SIZE اندازه هر بلوک مار و غذا
snake لیستی از مختصات (x, y) برای هر قسمت مار
food_position مختصات فعلی غذا
SNAKE_SPEED سرعت حرکت مار (فریم در ثانیه)

قلب بازی: منطق حرکت و کنترل

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

۱. دریافت ورودی از کاربر

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


# داخل حلقه اصلی بازی (while running:)

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
    if event.type == pygame.KEYDOWN: # وقتی کلیدی فشرده میشه
        if event.key == pygame.K_UP and snake_direction != "DOWN":
            snake_direction = "UP"
        elif event.key == pygame.K_DOWN and snake_direction != "UP":
            snake_direction = "DOWN"
        elif event.key == pygame.K_LEFT and snake_direction != "RIGHT":
            snake_direction = "LEFT"
        elif event.key == pygame.K_RIGHT and snake_direction != "LEFT":
            snake_direction = "RIGHT"

۲. حرکت مار

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


# بعد از حلقه event، قبل از رسم

# محاسبه موقعیت جدید سر مار
x, y = snake[0] # سر فعلی مار

if snake_direction == "UP":
    y -= BLOCK_SIZE
elif snake_direction == "DOWN":
    y += BLOCK_SIZE
elif snake_direction == "LEFT":
    x -= BLOCK_SIZE
elif snake_direction == "RIGHT":
    x += BLOCK_SIZE

new_head = (x, y) # سر جدید

# اضافه کردن سر جدید به ابتدای مار
snake.insert(0, new_head)

۳. برخورد با غذا و رشد مار

اگه سر مار با غذا برخورد کرد، باید مار رو رشد بدیم و یه غذای جدید تولید کنیم. در غیر این صورت، آخرین قسمت بدن مار رو حذف می‌کنیم تا طولش ثابت بمونه.


if new_head == food_position:
    food_position = generate_food_position() # غذای جدید تولید کن
    # مار رشد می‌کند، پس نیازی به حذف دم نیست
else:
    snake.pop() # دم مار رو حذف کن تا طولش ثابت بمونه

۴. برخورد با لبه‌ها و خودش (شرط Game Over)

اینجا مشخص می‌کنیم چه زمانی بازی باید تموم بشه.


# برخورد با لبه‌های صفحه
if not (0 <= x < SCREEN_WIDTH and 0 <= y < SCREEN_HEIGHT):
    running = False # بازی تمام شد

# برخورد مار با خودش (از دومین عنصر لیست به بعد)
for segment in snake[1:]:
    if new_head == segment:
        running = False # بازی تمام شد

امتیازدهی و نمایش وضعیت بازی

بازی بدون امتیاز که معنی نداره! باید یه راهی برای نمایش عملکرد کاربر و اعلام پایان بازی داشته باشیم.

۱. پیاده‌سازی سیستم امتیاز

یه متغیر ساده برای امتیاز کافیه. هر وقت مار غذا خورد، امتیاز رو زیاد می‌کنیم.


# در ابتدای کد، قبل از حلقه اصلی
score = 0

# در قسمت برخورد با غذا
if new_head == food_position:
    food_position = generate_food_position()
    score += 1 # امتیاز رو زیاد کن
else:
    snake.pop()

۲. نمایش امتیاز و صفحه ‘بازی تمام شد’

با استفاده از ماژول pygame.font می‌تونیم متن رو روی صفحه نمایش بدیم.


# در ابتدای کد
font = pygame.font.Font(None, 36) # فونت پیش‌فرض با سایز ۳۶

# در حلقه اصلی بازی، بعد از screen.fill(BLACK) و قبل از pygame.display.flip()

# رسم مار
for segment in snake:
    pygame.draw.rect(screen, GREEN, pygame.Rect(segment[0], segment[1], BLOCK_SIZE, BLOCK_SIZE))

# رسم غذا
pygame.draw.rect(screen, RED, pygame.Rect(food_position[0], food_position[1], BLOCK_SIZE, BLOCK_SIZE))

# نمایش امتیاز
score_text = font.render(f"امتیاز: {score}", True, WHITE)
screen.blit(score_text, (5, 5)) # در گوشه بالا سمت چپ

# این کد بعد از اتمام حلقه اصلی و قبل از pygame.quit() قرار می‌گیرد
if not running: # وقتی بازی تموم میشه
    game_over_font = pygame.font.Font(None, 72)
    game_over_text = game_over_font.render("بازی تمام شد!", True, RED)
    score_final_text = font.render(f"امتیاز نهایی شما: {score}", True, WHITE)

    text_rect = game_over_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 40))
    score_rect = score_final_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 20))

    screen.fill(BLACK) # صفحه رو دوباره مشکی کن
    screen.blit(game_over_text, text_rect)
    screen.blit(score_final_text, score_rect)
    pygame.display.flip()

    # منتظر می‌مونیم تا کاربر پنجره رو ببنده
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit() # کاملا از برنامه خارج شو

اضافه کردن چاشنی‌های نهایی و جمع‌بندی حلقه اصلی

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

۱. کنترل سرعت بازی

با استفاده از pygame.time.Clock() می‌تونیم فریم‌ریت (FPS) بازی رو کنترل کنیم تا مار با سرعت ثابتی حرکت کنه.


# در ابتدای کد
clock = pygame.time.Clock()
SNAKE_SPEED = 10 # 10 فریم در ثانیه (سرعت حرکت مار)

# در انتهای حلقه اصلی بازی، قبل از pygame.display.flip()
clock.tick(SNAKE_SPEED) # فریم‌ریت رو تنظیم می‌کنه

کد کامل بازی Snake

برای اینکه کل کد رو یکجا داشته باشی، اینجا همه قسمت‌هایی که نوشتیم رو با هم ترکیب کردم.


import pygame
import random
import sys # برای خروج مطمئن

pygame.init()

# ابعاد صفحه
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("بازی مار با پایتون و Pygame")

# رنگ‌ها
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# تنظیمات مار و بازی
BLOCK_SIZE = 20
SNAKE_SPEED = 10 # فریم در ثانیه (FPS)
font = pygame.font.Font(None, 36) # فونت برای امتیاز

# ساعت برای کنترل فریم‌ریت
clock = pygame.time.Clock()

# موقعیت اولیه مار
snake = [(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)]
snake_direction = "RIGHT" # جهت اولیه
score = 0

# تابع برای تولید موقعیت تصادفی غذا
def generate_food_position():
    x = random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE, BLOCK_SIZE)
    y = random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE, BLOCK_SIZE)
    return (x, y)

food_position = generate_food_position()

# --------- حلقه اصلی بازی -----------
running = True
game_over = False

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP and snake_direction != "DOWN":
                snake_direction = "UP"
            elif event.key == pygame.K_DOWN and snake_direction != "UP":
                snake_direction = "DOWN"
            elif event.key == pygame.K_LEFT and snake_direction != "RIGHT":
                snake_direction = "LEFT"
            elif event.key == pygame.K_RIGHT and snake_direction != "LEFT":
                snake_direction = "RIGHT"

    if not game_over:
        # محاسبه موقعیت جدید سر مار
        x, y = snake[0]
        if snake_direction == "UP":
            y -= BLOCK_SIZE
        elif snake_direction == "DOWN":
            y += BLOCK_SIZE
        elif snake_direction == "LEFT":
            x -= BLOCK_SIZE
        elif snake_direction == "RIGHT":
            x += BLOCK_SIZE
        new_head = (x, y)

        # اضافه کردن سر جدید به ابتدای مار
        snake.insert(0, new_head)

        # بررسی برخورد با غذا
        if new_head == food_position:
            food_position = generate_food_position()
            score += 1
        else:
            snake.pop() # حذف دم مار

        # بررسی برخورد با لبه‌ها
        if not (0 <= x < SCREEN_WIDTH and 0 <= y < SCREEN_HEIGHT):
            game_over = True

        # بررسی برخورد مار با خودش
        for segment in snake[1:]:
            if new_head == segment:
                game_over = True
                break # اگه برخورد کرد، دیگه لازم نیست بقیه رو چک کنیم
    
    # پر کردن صفحه با رنگ مشکی
    screen.fill(BLACK)

    # رسم مار
    for segment in snake:
        pygame.draw.rect(screen, GREEN, pygame.Rect(segment[0], segment[1], BLOCK_SIZE, BLOCK_SIZE))

    # رسم غذا
    pygame.draw.rect(screen, RED, pygame.Rect(food_position[0], food_position[1], BLOCK_SIZE, BLOCK_SIZE))

    # نمایش امتیاز
    score_text = font.render(f"امتیاز: {score}", True, WHITE)
    screen.blit(score_text, (5, 5))

    # اگر بازی تمام شد، پیغام رو نمایش بده
    if game_over:
        game_over_font = pygame.font.Font(None, 72)
        game_over_text = game_over_font.render("بازی تمام شد!", True, RED)
        score_final_text = font.render(f"امتیاز نهایی شما: {score}", True, WHITE)

        text_rect = game_over_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 40))
        score_rect = score_final_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 20))

        screen.blit(game_over_text, text_rect)
        screen.blit(score_final_text, score_rect)
        # می‌تونیم یه گزینه "شروع مجدد" هم اینجا اضافه کنیم

    # به‌روزرسانی نمایش
    pygame.display.flip()

    # کنترل فریم‌ریت
    clock.tick(SNAKE_SPEED)

# خروج از Pygame
pygame.quit()
sys.exit() # برای خروج کامل و تمیز

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

تبریک می‌گم! حالا یه بازی Snake کامل داری. اما همیشه جا برای بهبود و اضافه کردن فیچرهای جدید هست. اینجا چند تا ایده بهت میدم که می‌تونی بازی رو جذاب‌تر کنی:

  • افزودن صدا و موسیقی: می‌تونی برای خوردن غذا یا Game Over شدن، افکت صوتی و برای پس‌زمینه بازی، موسیقی اضافه کنی. Pygame ماژول pygame.mixer رو برای این کار داره.
  • چند سطح دشواری: با افزایش SNAKE_SPEED می‌تونی بازی رو سخت‌تر کنی. می‌تونی یه منو برای انتخاب سطح دشواری هم بسازی.
  • ذخیره بالاترین امتیاز (High Score): با استفاده از فایل‌ها می‌تونی بالاترین امتیازات رو ذخیره کنی و هر بار که بازی شروع میشه، به کاربر نمایش بدی. برای این کار، اسنیپت‌های مربوط به فایل می‌تونن کمکت کنن.
  • اضافه کردن موانع: به جای فقط دیوارها، می‌تونی موانع ثابت یا متحرک دیگه هم به بازی اضافه کنی که مار نباید بهشون بخوره.
  • طراحی گرافیکی بهتر: به جای مربع‌های ساده، می‌تونی از تصاویر (sprites) برای مار و غذا استفاده کنی تا بازی قشنگ‌تر به نظر برسه.

عیب‌یابی سریع (Troubleshooting) – حل مشکلات رایج

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

۱. بازی خیلی کند یا خیلی تند اجرا میشه.

راه‌حل: متغیر SNAKE_SPEED رو تنظیم کن. این عدد فریم‌ریت بازی رو مشخص می‌کنه. اگه عددش رو زیاد کنی، بازی سریع‌تر میشه و اگه کم کنی، کندتر. حواست باشه که clock.tick(SNAKE_SPEED) رو در انتهای حلقه اصلی بازی قرار بدی.

۲. مار حرکت نمی‌کنه یا به کلیدها واکنش نمیده.

راه‌حل: مطمئن شو که کد مربوط به pygame.event.get() و بررسی event.type == pygame.KEYDOWN در حلقه اصلی بازی به درستی نوشته شده و جهت snake_direction درست تغیر می‌کنه. همچنین، کد به‌روزرسانی موقعیت مار باید بعد از این بخش قرار بگیره.

۳. مار از دیوارها یا از خودش عبور می‌کنه (Game Over نمیشه).

راه‌حل: منطق if not (0 <= x < SCREEN_WIDTH and 0 <= y < SCREEN_HEIGHT): برای برخورد با دیوارها و حلقه for segment in snake[1:]: برای برخورد با خودش رو دقیقاً مثل کد بالا پیاده‌سازی کن. یه اشتباه کوچیک تو شرط‌ها می‌تونه باعث این مشکل بشه. چک کن که متغیر game_over به درستی True میشه و حلقه اصلی بازی بعد از اون از حرکت مار جلوگیری می‌کنه.

۴. خطای module 'pygame' has no attribute 'init'

راه‌حل: این خطا معمولاً وقتی رخ میده که نام فایل پایتون شما pygame.py باشه. پایتون به جای کتابخانه اصلی Pygame، فایل شما رو ایمپورت می‌کنه. نام فایل رو به چیزی مثل snake_game.py تغییر بده و دوباره امتحان کن.

۵. غذا در محل مار ظاهر می‌شود.

راه‌حل: باید مطمئن بشی که تابع generate_food_position() غذایی رو تولید نمی‌کنه که دقیقاً روی قسمتی از بدن مار باشه. می‌تونی یه حلقه while اضافه کنی که تا وقتی محل غذا با مار تداخل داره، یه محل جدید رو امتحان کنه.


def generate_food_position():
    while True:
        x = random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE, BLOCK_SIZE)
        y = random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE, BLOCK_SIZE)
        new_food_pos = (x, y)
        if new_food_pos not in snake: # اطمینان حاصل کن که غذا روی مار نیست
            return new_food_pos
اگه هنوز مشکلی داری یا سوالی برات پیش اومده، نگران نباش! ما همیشه اینجا هستیم تا کمکت کنیم. می‌تونی باهامون تماس بگیری و مشکلت رو مطرح کنی: 09202232789

جمع‌بندی و گام‌های بعدی تو!

خسته نباشی! الان تو یه بازی Snake کاملاً کاربردی با پایتون و Pygame ساختی. این یه نقطه شروع عالی برای ورود به دنیای بازی‌سازی با پایتونه و نشون میده که با کمی تلاش و خلاقیت، می‌تونی ایده‌های جذابت رو به واقعیت تبدیل کنی.

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

Table of Contents

آخرین نوشته‌ها