ساخت بازی مار با پایتون؛ راهنمای کامل کدنویسی + کد آماده

آیا میدانستید یادگیری برنامهنویسی میتواند به اندازه یک بازی قدیمی و خاطرهانگیز لذتبخش باشد؟ بازی “مار” (Snake) یکی از کلاسیکترین پروژههایی است که هر برنامهنویس پایتون باید حداقل یکبار آن را تجربه کند. اگر تازه وارد دنیای پایتون شدهاید، ساخت این بازی نه تنها اعتمادبهنفس شما را بالا میبرد، بلکه به شما کمک میکند مفاهیم پایهای مانند حلقهها، شرطها و مدیریت رویدادها را به صورت عملی لمس کنید.
در این مطلب، بدون پیچیدگیهای غیرضروری، قدمبهقدم با هم کد کامل یک بازی مار جذاب را مینویسیم و بررسی میکنیم که هر بخش از کد دقیقاً چه وظیفهای دارد تا در نهایت، نسخهای از این بازی را روی سیستم خود داشته باشید که آماده بازی است.
۲. چرا ساخت بازی مار برای شروع یادگیری پایتون عالی است؟
یکی از بزرگترین چالشهای یادگیری یک زبان برنامهنویسی جدید، خستهکننده بودن تمرینات تئوری است. ساخت پروژه بازی مار باعث میشود تا شما به جای سر و کله زدن با مفاهیم انتزاعی، مستقیماً خروجی کار خود را مشاهده کنید. این بازخورد بصری فوری، انگیزه شما را برای ادامه مسیر چند برابر میکند. علاوه بر این، در حین کدنویسی این بازی، شما با نحوه کارکرد سیستمهای هماهنگی (Coordinate System) و مدیریت ورودیهای کاربر (Keyboard Input) آشنا میشوید که در بسیاری از پروژههای پیچیدهتر نیز کاربرد دارند.
در واقع، دنیای توسعه نرمافزار پر از پروژههای پیچیده است، اما یادگیری اصول “پایه” در قالب یک پروژه سرگرمکننده، بهترین متد برای تثبیت دانش است. وقتی شما متوجه میشوید که چگونه یک مار با استفاده از دستورات شرطی حرکت میکند و با برخورد به دیوار بازی تمام میشود، عملاً در حال تمرینِ «منطق برنامهنویسی» هستید. این بازی کوچک، پلی است بین دانش تئوری شما و مهارتهای مورد نیاز برای توسعه نرمافزارهای حرفهایتر.
در نهایت، یادگیری ساختار بازی مار به شما اجازه میدهد تا با مفاهیم شیءگرایی (Object-Oriented Programming) نیز آشنا شوید. بسیاری از توسعهدهندگان موفق دنیا، شروع مسیر خود را با ساخت پروژههای سادهای از این دست آغاز کردهاند و این پروژه میتواند نقطه عطف شروع دوران حرفهای شما باشد.
۳. ابزارهای مورد نیاز برای اجرای پروژه
قبل از اینکه اولین خط کد را بنویسیم، باید محیط توسعه خود را آماده کنیم. برای شروع، پیشنهاد میکنم حتماً آخرین نسخه پایتون را از سایت رسمی دانلود و روی سیستم خود نصب کنید. در هنگام نصب، گزینه “Add Python to PATH” را حتماً علامت بزنید تا در تمامی محیطهای سیستمعامل در دسترس باشد. برای نوشتن کد نیز میتوانید از محیطهای سادهای مثل IDLE که همراه پایتون نصب میشود یا ویرایشگرهای پیشرفتهتری مانند VS Code استفاده کنید.
برای پیادهسازی این بازی ما از کتابخانه محبوب turtle استفاده میکنیم که به صورت پیشفرض در پایتون وجود دارد. این کتابخانه به دلیل سادگی در ترسیم اشکال گرافیکی و کنترل حرکات، بهترین گزینه برای تازهکارهاست. برای اینکه بدانید سیستم شما چه نیازمندیهایی دارد، جدول زیر را بررسی کنید:
| نیازمندی | توضیحات |
|---|---|
| پایتون | نسخه 3.8 یا بالاتر |
| کتابخانه | Turtle (داخلی) |
۳.۱ نصب پایتون و محیط کدنویسی
نصب پایتون فرآیند پیچیدهای نیست، اما دقت در مراحل اولیه میتواند شما را از بسیاری از خطاهای رایج در آینده دور نگه دارد. پیشنهاد میکنم در هنگام نصب، حتماً تیک گزینه “pip” را نیز بزنید تا بتوانید در آینده کتابخانههای جانبی دیگر را به راحتی نصب کنید. اگر از سیستمعامل ویندوز استفاده میکنید، محیط cmd یا PowerShell ابزارهای اصلی شما برای بررسی نصب بودن پایتون هستند که با تایپ python --version میتوانید از صحت نصب مطمئن شوید.
در مرحله بعدی، داشتن یک ادیتور مناسب، سرعت کدنویسی شما را به شدت افزایش میدهد. ادیتورهایی که دارای قابلیت Syntax Highlighting هستند، به شما کمک میکنند تا ساختارهای کد را بهتر تشخیص دهید و خطاها را سریعتر شناسایی کنید. اگر به دنبال یک محیط بدون دغدغه هستید، VS Code با نصب افزونه پایتون یکی از بهترین گزینهها برای شروع است.
۳.۲ آشنایی با کتابخانه Turtle
کتابخانه turtle برای کسانی که میخواهند با مبانی گرافیک در پایتون آشنا شوند، مانند یک بوم نقاشی دیجیتال عمل میکند. این کتابخانه در اصل برای آموزش طراحی شده و به شما اجازه میدهد با دستورات بسیار سادهای مثل forward() یا right()، اشکالی را روی صفحه رسم کنید. برای بازی مار، ما از قابلیتهای این کتابخانه برای ایجاد حرکتهای پیکسلی استفاده میکنیم.
یکی از نکات قوت این کتابخانه، عدم نیاز به نصب هیچگونه فایل یا درایور اضافی است. شما میتوانید همین حالا یک فایل پایتون جدید بسازید، آن را وارد کنید و با چند خط دستور، یک نقطه متحرک روی صفحه ایجاد کنید. این سادگی همان چیزی است که به شما کمک میکند تمرکز خود را به جای درگیری با تنظیمات گرافیکی پیچیده، روی منطق بازی و کدنویسی متمرکز کنید.
۴. کد آماده و کامل بازی مار با پایتون
اکنون که محیط کار را آماده کردهاید، نوبت به نوشتن کد اصلی میرسد. ما سعی میکنیم این کد را به صورت ماژولار و مرتب بنویسیم تا هم برای خودتان قابل فهم باشد و هم در آینده بتوانید ویژگیهای جدیدی به آن اضافه کنید. در نظر داشته باشید که برای اجرای این کد، تمام بخشهای زیر را در یک فایل با پسوند .py (مثلاً snake_game.py) کپی کرده و اجرا کنید.
در این پروژه، ما از چهار بخش اصلی استفاده میکنیم: تنظیمات پنجره بازی، تعریف بدنه مار، منطق حرکت و در نهایت مدیریت برخوردها. کد زیر پایه و اساس بازی شماست و با استفاده از کتابخانه turtle نوشته شده است که به سادگی قابل درک و پیادهسازی است.
پیش از اجرای کد، حتماً به این نکته دقت کنید که در دنیای برنامهنویسی، کپی و پیست کردن کد کافی نیست؛ بلکه باید سعی کنید هر خط را برای خودتان تحلیل کنید تا در صورت بروز خطا، قادر به عیبیابی باشید. این کد به گونهای بهینهسازی شده که با کمترین میزان مصرف منابع سیستم، بهترین تجربه بصری را به شما ارائه دهد.
۴.۱ قطعه کد بخش اول: تنظیمات محیط بازی
در این بخش، ابتدا پنجره اصلی بازی را ایجاد میکنیم. ما باید ابعاد صفحه، رنگ پسزمینه و نام بازی را مشخص کنیم. کتابخانه turtle به ما این اجازه را میدهد که با استفاده از کلاس Screen، یک محیط گرافیکی متمرکز ایجاد کنیم. در این مرحله، ما همچنین قابلیت بهروزرسانی خودکار صفحه را غیرفعال میکنیم (با دستور tracer(0)) تا حرکت مار نرمتر و بدون پرشهای گرافیکی باشد.
در واقع، تنظیمات اولیه مانند زیربنای یک ساختمان هستند؛ اگر ابعاد و رنگبندی صفحه به درستی تعریف نشود، در بخشهای بعدی با مشکلات مختصاتدهی مواجه خواهیم شد. دقت کنید که ما در اینجا نقطه (0,0) را مرکز صفحه قرار میدهیم تا مدیریت موقعیت مار آسانتر شود.
import turtle
# تنظیمات صفحه
win = turtle.Screen()
win.title("بازی مار ساده")
win.bgcolor("black")
win.setup(width=600, height=600)
win.tracer(0)۴.۲ قطعه کد بخش دوم: منطق حرکت و کنترل مار
حالا باید خودِ مار را ایجاد کنیم. مار در اینجا یک لیست از اشیاء گرافیکی است که در هر لحظه به دنبال سرِ مار حرکت میکنند. برای کنترل جهتهای حرکت (بالا، پایین، چپ، راست)، از کلیدهای جهتنمای کیبورد استفاده میکنیم. هر بار که کاربر کلیدی را فشار میدهد، یک تابع خاص فراخوانی میشود و جهت حرکت سر مار تغییر میکند.
نکته مهم در این بخش این است که مار نباید بتواند در جهت مخالف حرکت فعلی خود بچرخد (مثلاً اگر به سمت راست میرود، نباید بلافاصله به سمت چپ برگردد). این محدودیت منطقی توسط دستورات شرطی if کنترل میشود تا از باگهای احتمالی جلوگیری کنیم.
head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)
head.direction = "stop"پس از تعریف این بخش، مار آماده است تا دستورات کاربر را دریافت کند. به یاد داشته باشید که در هر حلقه بازی، مار باید به صورت خودکار به حرکت خود ادامه دهد، بنابراین ما از یک حلقه while True استفاده میکنیم که وظیفه بهروزرسانی مداوم موقعیت سر و بدن مار را بر عهده دارد.
۴.۳ قطعه کد بخش سوم: برخوردها و امتیازدهی
آخرین بخش از کد، حیاتیترین قسمت برای جذابیت بازی است. در اینجا بررسی میکنیم که آیا مار با دیوارههای صفحه برخورد کرده است یا خیر. اگر مختصات سر مار از حدود صفحه (300 یا -300) فراتر برود، بازی باید ریست شود. همچنین، اگر مار با بدن خودش برخورد کند، سناریوی مشابهی رخ میدهد.
علاوه بر این، برای اینکه بازی معنیدار شود، یک “غذا” (Food) برای مار تعریف میکنیم. هر بار که مختصات سر مار با مختصات غذا یکی شود، مار بزرگتر میشود (یک قطعه جدید به لیست بدنه اضافه میشود) و امتیاز کاربر افزایش مییابد. این چرخه، هسته اصلی اعتیادآور بودن بازیهای کلاسیک است.
- برخورد با دیوار: باعث صفر شدن امتیاز و بازگشت مار به مرکز صفحه میشود.
- برخورد با بدن: مشابه برخورد با دیوار، بازی را به حالت اولیه برمیگرداند.
- غذا خوردن: افزایش طول مار و تولید غذای جدید در یک مختصات تصادفی.
۵. تحلیل عملکرد کدها
پس از اینکه کدهای اصلی را در محیط برنامهنویسی خود وارد کردید، احتمالاً کنجکاو هستید که بدانید دقیقاً چه اتفاقی در پسزمینه رخ میدهد. در حقیقت، آنچه ما به عنوان بازی مار میبینیم، در واقع مجموعهای از محاسبات ریاضی ساده است که به سرعت و به صورت مداوم تکرار میشوند. کتابخانه turtle در هر لحظه، مختصات (X, Y) سر مار و تکههای بدن آن را کنترل میکند تا وضعیت جدید را برای کاربر ترسیم کند.
تحلیل کد نه تنها باعث میشود اعتماد به نفس بیشتری در کدنویسی پیدا کنید، بلکه قدرت عیبیابی شما را نیز ارتقا میدهد. اگر در جایی از بازی با خطا مواجه شدید، به احتمال زیاد مشکل در یکی از همین بخشهای منطقی است. درک عمیق از نحوه حرکت و جایگذاری المانها، زیربنای ورود شما به پروژههای گرافیکی سنگینتر و بازیسازیهای پیچیدهتر در آینده خواهد بود.
به یاد داشته باشید که این بازی بر پایه یک «حلقه اصلی» (Main Loop) استوار است. در هر بار اجرا، کد بررسی میکند که آیا کاربر کلیدی را فشار داده، آیا مار به غذا رسیده یا آیا برخورد نامطلوبی رخ داده است؟ این چرخه به قدری سریع انجام میشود که چشم انسان آن را به صورت یک حرکت روان مشاهده میکند. در ادامه، جزئیات بیشتری از این منطق را بررسی میکنیم.
۵.۱ چگونه مار حرکت میکند؟
حرکت در بازی مار بر اساس تغییر متغیرهای مختصات انجام میشود. فرض کنید سر مار در نقطه (0,0) است؛ برای حرکت به سمت راست، ما مقدار X را افزایش میدهیم. برای حرکت به سمت بالا، مقدار Y را اضافه میکنیم. این کار در یک حلقه بینهایت انجام میشود. برای اینکه مار حرکت خود را حفظ کند، ما همیشه آخرین تکه بدنه مار را به موقعیت قبلی سر مار منتقل میکنیم؛ این ترفند هوشمندانه باعث میشود مار در حال حرکت به نظر برسد.
اگر بخواهیم دقیقتر بگوییم، مار در واقع مجموعهای از اشیاء است که هر کدام از آنها جایگاه قبلی شیء جلویی خود را اشغال میکنند. این مکانیزم صف (Queue) مانند، باعث میشود که وقتی سر مار تغییر جهت میدهد، تمام بدنه آن به صورت یک زنجیره پشت سر آن حرکت کنند. این دقیقاً همان جایی است که اهمیت استفاده از لیستها در پایتون مشخص میشود، چرا که ما باید موقعیت تمام تکههای بدن مار را در یک لیست ذخیره و مرتباً بروزرسانی کنیم.
۵.۲ مدیریت برخورد با دیوارها و بدنه خود
شناسایی برخورد (Collision Detection) در بازیسازی یکی از بخشهای جذاب است. در این بازی، ما به سادگی با استفاده از دستورات شرطی if، فاصله سر مار را با مرزهای صفحه مقایسه میکنیم. اگر مختصات سر مار از حدود صفحه (مثلاً 300+ یا 300-) عبور کند، یعنی برخورد رخ داده است. این محاسبات بسیار سبک هستند و در کسری از میلیثانیه انجام میشوند.
در مورد برخورد با خود، منطق کمی متفاوت است. در اینجا، ما باید موقعیت سر مار را با موقعیت تمامی تکههای لیست بدنه مقایسه کنیم. اگر فاصله سر مار با هر یک از تکههای بدنش کمتر از مقدار مشخصی (مثلاً 20 پیکسل) باشد، یعنی مار با خودش برخورد کرده است. مدیریت این برخوردها باعث میشود بازی چالشبرانگیز باقی بماند و کاربر همیشه مراقب مسیر حرکت خود باشد.
نکته حرفهای: همیشه سعی کنید بازه برخورد (Collision Distance) را کمی کمتر از اندازه واقعی اشیاء در نظر بگیرید تا از برخوردهای ناخواسته و ناعادلانه جلوگیری شود.
۶. چطور بازی را شخصیسازی کنیم؟
یکی از لذتبخشترین قسمتهای برنامهنویسی، دستکاری کدهایی است که خودتان نوشتهاید. بازی مار پایتون که ما نوشتیم، پتانسیل بسیار بالایی برای شخصیسازی دارد. از تغییر رنگ مار گرفته تا سرعت حرکت و حتی افزودن مراحل سختتر، همگی با تغییر چند خط کد ساده امکانپذیر هستند. این کار به شما کمک میکند تا به جای استفاده از یک کد آماده، مالکیت آن را به دست بگیرید و خلاقیت خود را در آن دخیل کنید.
توصیه میکنم هنگام شخصیسازی، حتماً از یک سیستم کنترل نسخه یا حداقل کپیبرداری از فایل اصلی استفاده کنید تا اگر تغییری باعث خرابی بازی شد، بتوانید به نسخه سالم بازگردید. تغییر پارامترها مانند رنگ یا سرعت، اولین گام برای درکِ عمیقتر از متغیرها و مقادیر در پایتون است. در ادامه، ایدههایی برای تغییر ظاهر و عملکرد بازی ارائه دادهایم که میتوانید همین حالا روی سیستم خود پیاده کنید.
به علاوه، شخصیسازی بازی یک تمرین عالی برای یادگیری کار با توابع و ورودیهای آنهاست. برای مثال، میتوانید تابعی بنویسید که رنگ مار را به صورت تصادفی از بین یک لیست انتخاب کند. این تغییرات کوچک، بازی شما را از یک پروژه ساده آموزشی به یک سرگرمی شخصی تبدیل میکند که میتوانید آن را به دوستان خود نشان دهید.
۶.۱ تغییر سرعت حرکت مار
در کدهای اولیه، سرعت حرکت مار به صورت ثابت تعیین شده است. برای تغییر این سرعت، شما باید به حلقه اصلی بازی نگاه کنید. در کتابخانه turtle، دستوری به نام time.sleep() وجود دارد که تأخیر بین هر حرکت را مشخص میکند. هرچه مقدار این عدد کمتر باشد، سرعت مار بیشتر میشود. این یک راه بسیار ساده برای اضافه کردن “سطوح دشواری” به بازی است؛ مثلاً میتوانید بعد از خوردن هر غذا، سرعت را کمی افزایش دهید.
جدول زیر به شما کمک میکند تا رابطه بین زمانِ تاخیر و سطح دشواری بازی را بهتر درک کنید:
| مقدار تاخیر (ثانیه) | سطح دشواری |
|---|---|
| 0.2 | آسان (مناسب یادگیری) |
| 0.1 | متوسط |
| 0.05 | سخت (حرفهای) |
۶.۲ تغییر رنگ و اندازه مار
تغییر ظاهر مار میتواند جذابیت بصری بازی را دوچندان کند. در بخش تعریف مار (که در ابتدای کد آورده شد)، میتوانید ویژگیهای گرافیکی را با تغییر متدهای shape() و color() عوض کنید. برای مثال، میتوانید به جای مربع از دایره استفاده کنید یا رنگ بدن مار را با هر بار خوردن غذا تغییر دهید تا جلوه بهتری پیدا کند.
تغییر اندازه مار نیز بسیار ساده است. شما میتوانید با استفاده از متد shapesize() ابعاد قطعات بدن مار را به دلخواه بزرگ یا کوچک کنید. حتی میتوانید کاری کنید که در مراحل بالاتر، اندازه مار کمی کوچکتر شود تا کار برای بازیکن سختتر گردد. این تنظیمات کوچک، تأثیر مستقیم و فوری در تجربه کاربری (User Experience) بازی شما خواهند داشت و نشاندهنده توجه شما به جزئیات است.
۷. نتیجهگیری
ساخت بازی مار با پایتون، فراتر از یک تمرین ساده، دریچهای به دنیای مهیج برنامهنویسی و حل مسئله است. در این مسیر، شما یاد گرفتید که چگونه با استفاده از کتابخانههای پایه، منطق حرکت، برخورد و مدیریت وضعیت بازی را پیادهسازی کنید. این پروژه به شما نشان داد که چگونه مفاهیم تئوری مانند متغیرها، حلقهها و توابع در عمل به یک خروجی بصری و سرگرمکننده تبدیل میشوند. آنچه امروز به عنوان یک کد ساده پیاده کردید، خشت اول برای یادگیری مفاهیم پیشرفتهتر در توسعه نرمافزار و بازیسازی است.
فراموش نکنید که یادگیری برنامهنویسی یک مسیر مداوم است. حالا که توانستید این بازی را اجرا کنید، پیشنهاد میکنم به سراغ شخصیسازیهای بیشتر بروید؛ مثلاً سعی کنید سیستم ثبت رکورد (High Score) را به بازی اضافه کنید یا مراحل مختلف با سرعتهای متفاوت بسازید. هر تغییری که در کد اعمال میکنید، درک شما را عمیقتر کرده و تسلط شما را بر زبان پایتون افزایش میدهد. اعتماد به نفس حاصل از موفقیت در اجرای همین پروژه کوچک، بهترین ابزار شما برای رویارویی با چالشهای بزرگتر در دنیای توسعه نرمافزار خواهد بود.
در نهایت، این بازی فقط شروع ماجراست. پایتون کتابخانههای بسیار قدرتمندی مانند Pygame دارد که برای ساخت بازیهای حرفهایتر و گرافیکیتر به کار میروند. پس از اینکه با منطق این پروژه کاملاً آشنا شدید، میتوانید مطالعه در مورد آنها را آغاز کنید. دنیای کدنویسی پر از فرصتهای خلاقانه است و شما همین حالا قدم بزرگی را در این مسیر برداشتهاید.
۸. سوالات متداول
۱. آیا برای اجرای این کد حتماً باید اینترنت داشته باشم؟
خیر، کتابخانه turtle به صورت پیشفرض همراه با پایتون نصب میشود و برای اجرای این بازی، نیازی به اتصال اینترنت یا دانلود هیچ فایل جانبی ندارید.
۲. چرا هنگام اجرای بازی، پنجره بلافاصله بسته میشود؟
اگر پنجره بازی سریع بسته میشود، احتمالاً در انتهای کد خود دستور turtle.done() یا win.mainloop() را فراموش کردهاید. این دستور باعث میشود پنجره بازی باز بماند و منتظر رویدادهای کیبورد بماند.
۳. چگونه میتوانم این بازی را به یک فایل اجرایی (.exe) تبدیل کنم؟
برای تبدیل کدهای پایتون به فایل اجرایی، میتوانید از ابزارهایی مانند PyInstaller استفاده کنید. با نصب این کتابخانه و اجرای دستور pyinstaller --onefile snake_game.py در ترمینال، فایل اجرایی بازی برای شما ساخته میشود.