توسعه بازೌ با گدوت

Skip to content

این یک متن ترجمه شده ماشینی است که ممکن است حاوی خطا باشد!

این اطلاعات از کجا آمده است؟

بسیاری از این موارد صرفاً بازگویی مستندات رسمی Godot هستند. در زیر، برخی از لینک‌های مفید به مستندات رسمی را مشاهده می‌کنید (که من ترجیح می‌دهم از آن‌ها به جای این نسخه در Piggy استفاده کنید، اما اگر این نسخه را ترجیح می‌دهید، می‌توانید از همین استفاده کنید!)

منابع مفید:

آیا در مورد گرافیک چطور؟ آیا باید آن را خودم بسازم؟

نه! شما می‌توانید دارایی‌های رایگان زیادی در اینجا پیدا کنید:

سایر پیوندهای مفید:

موتورهای بازی دیگر؟

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

موتورهای دیگری هم وجود دارند، اگر می‌خواهید چیز دیگری را امتحان کنید، حتماً جستجو کنید!

گودوت چیست؟

گودوت (تلفظ: گو-دو) یک «موتور بازی» است. به زبان ساده، برنامه‌ای است که به شما امکان می‌دهد بازی بسازید (یا اگر مایل باشید، نرم‌افزارهای معمولی ایجاد کنید). گودوت قادر به انجام تقریباً تمام کارهایی است که سایر موتورهای بازی انجام می‌دهند؛ چه در دو بعد و چه سه بعد.

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

فقط بازی‌های مستقل نیستند که در گودوت ساخته شده‌اند؛ سونیک کلرز آلتیمیت نیز با استفاده از گودوت توسعه یافته است! 🦔🦔🦔

چگونه گودوت را به دست آورید؟

شما می‌توانید گودوت را از یکی از منابع زیر دانلود کنید:

فقط کافیست آن را دانلود و نصب کنید (یا مستقیماً روی استیم اجرا نمایید).

یک پروژه ایجاد کنید!

هنگام راه‌اندازی گودت، این پنجره نمایش داده می‌شود:

پروژه گودت

در اینجا از شما زبان برنامه‌نویسی مورد نظر خواسته می‌شود؛ اِدیاسکریپت یا سی‌شارپ. ادیاسکریپت بسیار شبیه پایتون است.

تفاوت‌های بین EDScript و پایتون (بدون رنگ‌بندی):

def hello():
    text = "Hello world!"

    print(text)
func hello():
    var text = "Hello world!"

    print(text)

برای متغیرها در پایتون تنها کافیست نام متغیر را بنویسید. اما در EDScript باید ابتدا کلمه کلیدی var را نوشته باشد. برای ساخت توابع به جای def از func استفاده شود.

صحنه‌ها و گره‌ها

یکی از مهم‌ترین مفاهیم در Godot، صحنه‌ها و گره‌ها هستند. می‌توانیم با گره‌ها شروع کنیم. یک گره یک شیء در Godot است و می‌تواند هر چیزی را نشان دهد. این می‌تواند چیزی باشد که یک بازیکن، یک دشمن، یک دکمه در یک منو، متن روی صفحه نمایش، هر چیزی را نشان دهد. صحنه‌ها مجموعه‌ای از گره‌ها هستند.

در اینجا می‌خواهیم یک مثال بسیار ساده ایجاد کنیم.

بخش اول - تنظیم صحنه «player» (بازیکن)

در بالای پنجره گودو، روی دکمه «۲بعدی» کلیک کنید تا نمای دید به یک نما دوبعدی تغییر کند.

در سمت چپ پنجره، رابط کاربری زیر را مشاهده می‌کنید:

ساختن صحنه

روی دکمه «گرهی دیگر» کلیک کرده و عبارت «CharacterBody2D» را جستجو کنید؛ آن را انتخاب نموده و سپس بر «ایجاد» ضربه بزنید. این نوع گرهِ برای بازیکن دو بعدی استفاده می‌شود. ممکن است متوجه شوید که در کنار نودِ CharacterBody2D علامت هشدار ⚠️ وجود دارد. دلیل آن کمبود برخی ویژگی‌های ضروری مورد نیاز توسط این نود است.

اگر با کلید راست ماوس روی نود کلیک کنید، گزینه‌ای به نام «+ افزودن فرزند…» ظاهر خواهد شد. از این طریق دو نود جدید اضافه کنید: Sprite2D و CollisionShape2D. نود Sprite2D جهت نمایش عناصر گرافیکی مربوط به شخصیت بازیکن کاربرد دارد، در حالی که دیگری وظیفه بررسی برخورد (کلیشن) را بر عهده دارد. همچنین می‌توانید برای هر کدام اسم خاصی تعیین نمایید تا مدیریت آنها آسان‌تر شود. من نام CharacterBody2D خودم را به “Player” تغییر داده ام. نمای فعلی صحنه باید شبیه تصویر زیر باشد:

صحنه کنونی

بخش ۱ب - رفع مشکل ❗ روی CollisionShape2D

مثلث هشدار در این مورد نشان می‌دهد که CollisionShape2D فاقد کولایدر است. برای اصلاح آن، نود را انتخاب کنید (سمت چپ)، سپس پنلی در سمت راست ظاهر خواهد شد. در اینجا اطلاعات زیادی دربارهٔ نودی که قابل تغییر است نمایش داده می‌شود؛ پیشنهاد می‌کنیم با گزینه‌های موجود تمرین کنید. اما آنچه باید بر روی آن تمرکز کنیم «نوع شکل» یا همان Shape است و مثلاً مقدار آن را به RectangleShape2D تنظیم نمایید. واقعیت مهمی ندارد زیرا ما از کولیذرها استفاده نخواهیم کرد.

Del 1c - افزودن یک Sprite، گرافیک

اگر روی Sprite2D در سمت چپ کلیک کنید، فیلدی در سمت راست ظاهر می‌شود که در آن “Texture” نوشته شده است. در اینجا می‌توانید یک تصویر برای بازیکن قرار دهید. فقط کافی است یک تصویر را بکشید و در فیلد رها کنید.

به این شکل بعد از افزودن یک sprite خواهد بود.

Sprite menu

بخش ۲ - افزودن ورودی، کنترل‌ها

در بالای پنجره یک منو وجود دارد: “Scene - Project - Debug - Editor - Help”. روی “Project” و سپس “Project Settings” کلیک کنید. در اینجا منویی با تنظیمات بسیار باز می‌شود. روی “Input Map” کلیک کنید. در اینجا می‌توانید دکمه‌های کیبورد را تنظیم کنید.

  • در فیلد “Add New Action”، عبارت “left” را تایپ کرده و سپس روی “Add” کلیک کنید.
  • سپس “right”، “up” و “down” را اضافه کنید.
  • این موارد به عنوان “Actions” شناخته می‌شوند.
  • برای هر “Action” می‌توانید با فشار دادن دکمه + در سمت راست، دکمه‌ها را اضافه کنید.

Plus button

  • در اینجا فقط کافی است روی دکمه‌ای از کیبورد فشار دهید و سپس روی Add کلیک کنید.
  • برای تمام actions دکمه‌ها را اضافه کنید.

بخش سوم – افزودن یک اسکریپت برای کنترل بازیکن

برای اضافه کردن منطق بازی، یعنی انجام کاری روی بازیکن یا پس‌زمینه یا هر چیز دیگری در بازی، به یک اسکریت نیاز داریم. اسکریت‌ها کد هستند و می‌توان آن‌ها را با دو زبان نوشت: GDScript یا سی‌شارپ؛ پیش‌فرض GDScript است.

  • دکمه «CharacterBody2D» (من نامش را «Player» گذاشتهام) گره Node را فشار دهید.
  • دکمه «Attach Script» را فشار دهید (به تصویر زیر توجه کنید).

اتصال اسکریت

  • اکنون پنجره‌ای ظاهر می‌شود که در آن می‌توانید زبان انتخاب کنید (GDscript را برگزینید) و مسیری تعیین نمایید (تنها اجازه دهید همان چیزی باشد که نمایش داده شده، اما امکان تغییر نام نیز وجود دارد)، سپس ادامه دهید. اکنون یک پنجرهٔ «اسکریpt» برایتان باز خواهد شد. در ابتدا محتوایی زیادی اینجا دیده نمی‌شود.

extends CharacterBody2D

در حال حاضر، این کد فقط می‌گوید که کد باید به یک گره از نوع “CharacterBody2D” تعلق داشته باشد، که همان بازیکن ماست.

ما یک تابع را در اینجا اضافه خواهیم کرد که برای دستکاری بازیکن از آن استفاده خواهیم کرد:

extends CharacterBody2D

func _physics_process(_delta: float) -> void:
    return

Physics Process?

_physics_process تابعی است که هر “فریم” به‌روزرسانی می‌شود، یعنی حدود 60 بار در ثانیه (پیش‌فرض). یک تابع دیگر به نام _process نیز وجود دارد که به‌طور مداوم به‌روزرسانی می‌شود. اگر می‌خواهید بازیکن با سرعت ثابتی حرکت کند، از _physics_process استفاده کنید.

اینجاست که باید کدی را اضافه کنیم که بازیکن را حرکت می‌دهد.

بخش ۴ - ورودی پایه

در بخش دوم، شما دکمه‌های ورود را اضافه کردید؛ حالا می‌خواهیم از آن‌ها استفاده کنیم. یک شیء داخلی به نام Input وجود دارد که ما می‌توانیم برای بررسی اینکه آیا بازیکن روی چیزی در «نقشهٔ ورود» (Input Map) کلیک کرده است یا نه، از این شیء استفاده کنیم.

کد زیر را وارد کدهای داخل تابع _physics_process کنید:

# Hvis høyre-tasten holdes nede
if Input.is_action_pressed('right'):
    # Bevegelse i x-retning med hastighet 100
    velocity.x = 100

# Flytt figuren og håndter kollisjoner automatisk
move_and_slide()

move_and_slide() چیست؟

move_and_slide() یک تابع داخلی در گودوت است که زمانی استفاده می‌شود که بخواهیم واقعاً آنچه را که به آن اعمال کرده‌ایم جابه‌جا کنیم. بدون این، بازیکن حرکت نخواهد کرد.`

Warning

فضای بین خطوط بسیار مهم است، این موضوع مشابه پایتون است.

وقتی برنامه را با فشردن دکمه‌ی پخش در پنجره‌ی Godot شروع می‌کنید و سپس “راست” را فشار می‌دهید، چه اتفاقی می‌افتد؟

اگر الان هیچ اتفاقی نیفتاد:

  • آیا چیزی را در “Input Map” تنظیم کرده‌اید؟
  • آیا right را نوشته‌اید و نه Right؟ یعنی، آیا آنچه را که در کد نوشتید با نام موجود در input map یکسان است؟

تمام کد تا اینجا
extends CharacterBody2D

func _physics_process(delta: float) -> void:
    if Input.is_action_pressed('right'):
        velocity.x = 100

    move_and_slide()

سعی کنید حالا کد مربوط به 'left', 'up', 'down' را اضافه کنید.

velocity.x برای 'left' باید چه مقداری باشد؟ در مورد 'up' و 'down' چطور؟

کل کد اکنون
extends CharacterBody2D

func _physics_process(delta: float) -> void:
    if Input.is_action_pressed('right'):
        velocity.x = 100
    if Input.is_action_pressed('left'):
        velocity.x = -100
    if Input.is_action_pressed('down'):
        velocity.y = 100
    if Input.is_action_pressed('up'):
        velocity.y = -100

    move_and_slide()

بخش پنجم – اصلاح کد

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

پیش از تمام دستورات if، خطی اضافه کنید تا سرعت (velocity) به صفر تنظیم شود. برای انجام این کار عبارت زیر را بنویسید: velocity = Vector2().

تمام سرعت‌ها و جهت‌ها در گودوت بردار هستند؛ این مفهوم ریاضیاتی موضوعی نیست که بخواهیم همین حالا وارد آن شویم، اما اگر درباره معنی آن کنجکاوتر هستید، اینجا مراجعه نمایید: وکتورهای ویکی‌پدیا.

تمام کد اکنون
extends CharacterBody2D

func _physics_process(delta: float) -> void:
    velocity = Vector2()

    if Input.is_action_pressed('right'):
        velocity.x = 100
    if Input.is_action_pressed('left'):
        velocity.x = -100
    if Input.is_action_pressed('down'):
        velocity.y = 100
    if Input.is_action_pressed('up'):
        velocity.y = -100

    move_and_slide()

هنگامی که اکنون بازی را شروع می‌کنید، می‌توانید بازیکن را حرکت دهید:

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

به عنوان مثال، می‌توانید (قبل از تابع) یک ثابت اضافه کنید که سرعت را پیگیری کند.

تمام کد در انتها با const
extends CharacterBody2D

const SPEED = 100

func _physics_process(delta: float) -> void:
    velovity = Vector2()

    if Input.is_action_pressed('right'):
        velocity.x = SPEED
    if Input.is_action_pressed('left'):
        velocity.x = -SPEED
    if Input.is_action_pressed('down'):
        velocity.y = SPEED
    if Input.is_action_pressed('up'):
        velocity.y = -SPEED

    move_and_slide()

بخش ششم – خودتان بازی کنید!

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

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