گودو گیم دو، بلاگ بازی سازی با انجین گودو Godot

گودو گیم دو، بلاگ آموزشی و اطلاع رسانی انجین بازی سازی گودو (Godot) است. در این بلاگ مطالب زیادی درباره انجین گودو و بازی سازی یاد میگیرید.

تابع clamp در انجین گودو برای محدود کردن یک متغیر

سلام به همه دوستداران گودو. یه مدتی نبودم. تو این مدت مهمترین اتفاقی که افتاده اینه که ورژن 4.2 گودو منتشر شد(و من هم تو این آموزش ازش استفاده میکنم) که تو بعضی زمینه ها نسبت به ورژن قبلی بهبود داشت. و خبر خوب دیگه این که فروم یا انجمن گودو به روز شد که جای خیلی خوبیه برای سوال پرسیدن و معاشرت کردن با دیگر توسعه دهندگان گودو. اینم آدرسش :

 https://forum.godotengine.org

با یه آموزش کاربردی دیگه اومدم. اول مسئله رو مطرح میکنم. وقتی میخواید یه متغیرو بین دوتا مقدار حداقل و حداکثر، یا کمینه و بیشینه محدود کنید، چه کار میکنید؟ خوب، اولین گزینه ای که به ذهن آدم میاد اینه که در تابع proccess  یا physics_proccess از چند تا دستور شرطی استفاده کنه و بگه: اگه مقدار متغیر از x کمتر شد، تو اون رو برابر مثلا 0 قرار بده و اگه از فلان مقدار بیشتر شد، تو این رو برابر یا 1000 قرار بده. این ایرادی نداره و احتمالا کار میده. ولی همیشه اولین راه حل، بهترین راه حل نیست. راه های بهتری هم هست. این راهی کی میخوایم ازش صحبت کنیم، تابع clamp ئه. 

تابع clamp یک متغیر رو بین دوتا مقدار کمینه و بیشینه نگه میداره و اجازه نمیده از اون حدود تجاوز کنه. یک بار برای همیشه بیاید و clamp رو یاد بگیرید و همیشه ازش استفاده کنید. این قدر برای همه چیز شرط if نزنید(خطاب به خودم!).

توی پروژه کوچیکی که برای مثال این مطلب استفاده میکنم، یک آبجکت داریم که با دکمه بالا و پایین حرکت میکنه ولی از بالا و پایین تصویر، اون طرف تر نمیره. 

اول scenetree رو لوازم مورد نیاز رو براتون میذارم و بعد کد، و کد رو توضیح میدم. 

صحنه ما از یک node2D که سرشاخه است و یک scene به نام animal  تشکیل شده. صحنه animal، خودش شامل یک نود character2d به عنوان سرشاخه و دوتا نود زیر مجموعه که یکی sprite2d و دیگری collisionshape2d ئه و هر دو برای ساخت یک character2d میشه گفت ضروری هستن. 

 و حالا صحنه animal و چینش صفحه بازی. من animal رو آوردم وسط صفحه و رنگ پس زمینه رو به آبی روشن تغییر دادم. 

این از پیش نیازهای پروژه.

حالا دقت کنید که animal  یه اسکریپت داره. کد این اسکریپت به شرح زیره:

(خطایی توی تصویر هست، برای این که حرکت درست باشه جای 250 و منفی 250 باید عوض شه)

به ترتیب شماره گذاری توضیح میدم:

  1. یک متغیر از نوع vector2 به نام movement تعریف کردم.
  2. در تابع پیش ساخته physics_proccess دو تا شرط برای حرکت رو به بالا و رو به پایین نوشتم. به این صورت که وقتی کلید بالای کی برد فشرده شد، متغیر movement برابر بشه با مقداری که میبینید که  x اش صفره و y اش 250. و اون رو ضربدر delta کردم.و همین کار برای دکمه پایین کی برد. دقت کنید هنوز حرکتی صورت نگرفته.
  3. اینجا گفتم که position نود مورد نظر هر چی که هست با مقدار movement جمع بشه که بسته به دکمه بالا یا پایین، یا مقدارش کم میشه ( حرکت رو به بالا) یا مقدارش زیاد میشه (حرکت رو به پایین). به خاطر این که در گودو y رو به پایین مقدارش افزایش پیدا میکنه. و بعد هم تابع move_and_slide رو استفاده کردم که از توابع نود character2d ئه و عملا تغییر پوزیشن رو اعمال میکنه.
  4. میرسیم به خط طلایی که مقدار global_position بین 0 و عرض تصویر بازی(get_viewport)، محدود میکنه. 

   اول نتیجه بهتون نشون میدم و بعد چند نکته میگم:

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

یا این که مثل من روی یک مقدار که از نوع vector2 ئه به کارش ببرید. چون نوع vector2 خودش تابع clamp برای تعریف شده. در این صورت متغیر وکتور2 خودتون رو مینویسید و بعد clamp و بعد مقدار حداقل و حداکثر رو وارد میکنید. 

نکته خیلی مهم:

برای این که اثر clamp اعمال بشه، حتما باید برابر با متغیر قرار بگیره. clamp خالی هیچ کاری نمیکنه.

توی تصویر ببینید من چجوری نوشتم.

خوب آموزش به پایان رسید. فکر کنید ببینید کجاها این به درد میخوره. مثلا یک بازی  space shooter  که پلیر سمت چپ تصویره و باید مهاجما رو از بین ببره و دامنه حرکتش از بالا تا پایین تصویره. یا فرض کنید میخواید سرعت یه آبجت از یه حدی فراتر نره.

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

  • 0 نظر
  • 0 پسند
    • danial abdl
    • 14:03 1402/09/28

    متغیرهای سراسری و اتولود (autoload) در انجین بازی گودو

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

    در یه مثال ساده این رو بهتون نشون میدم. 

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

     

    میخوایم اسکریپت اتولود رو بسازیم. در بخش filesystem روی res کلیک راست  و بعد گزینه create new و بعد script رو انتخاب کنید.اسمشو بذارید General یعنی عمومی یا سراسری. 

    حالا اسکریپت جنرال رو میخوایم اتولود کنیم. از مسیرsetting و بعد project setting، تب autoload رو انتخاب میکنیم. برای اضافه کردن اسکریپت به اتولود روی آیکون فولدر کلیک میکنیم، اسکریپت General رو انتخاب میکنیم و open  رو کلیک میکنیم. در نهایت سمت راست صفحه دکمه Add رو میزنیم تا اسکریپت به لیست اضافه بشه. 

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

    توی این قسمت میخوایم داخل اسکریپ General یه متغیر ساده اضافه کنیم تا بتونیم توی اسکریپت main ازش استفاده کنیم و متن اون رو توی لیبل نشون بدیم. اینجا میخوام نحوه تایپ و کدنوشتن هم بهتون نشون بدم. گاهی اوقات وقتی بخشی از کلمه رو تایپ میکنید، برنامه به شما کلمه رو پیشنهاد میده و با کلید Enter میتونید انتخابش کنید. یه متغیر به نام text میسازم و مقدارشو (متنشو) میذارم "General text". متنها همیشه در کدنویسی گودو بین دوتا علامت " قرار میگیرن.  

    حالا توی اسکریپت main از متغیری که توی اسکریپت general هست استفاده میکنیم. دقت کنید که هر چندتا اسکریپت دیگه هم داشتیم و حتی اگه  در صحنه های دیگه هم بودن، میتونستیم به متغیرهای General دسترسی داشته باشیم. 

    کاری که توی این کد انجام میشه اینه که در فانکشن یا تابع ready ، به لیبل ارجاع میدم و متنشو برابر با متن متغیر text  از اسکریپت general  میکنم.( تابع ready یکی از تابع های پیش ساخته گودوئه و هر اسکریپتی در شروع صحنه، تابع ready رو اجرا میکنه. )

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

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

    فایده اتولود اینه که شما رو از دوباره‌کاری بی نیاز میکنه. فرض کنید 10 تا صحنه داشتید که میخواستید اون متن رو توی همشون نشون بدید. باید در هر 10 تا صحنه متغیری میساختید. ولی با این روش یک بار نوشتید و میتونید 10 بار یا بیشتر استفاده کنید. 

    درآخر کدها رو میذارم تا داشته باشید.

    ...

  • 0 نظر
  • 0 پسند
    • danial abdl
    • 20:28 1402/07/23

    تبدیل هر نودی به قابل کلیک و لمس در گودو با یک ترفند ساده

    اگه بخواید توی بازیتون چیزی قابل کلیک کردن و لمس کردن باشه، ولی الزاما ظاهر دکمه نداشته باشه، از چه روشی استفاده میکنید؟ توی گودو دکمه های مختلفی هست. Button، texture Button و ... انواع دکمه ها هستن. ولی هرکدوم قابلیت و محدودیت خودشون رو دارن. توی ساخت بازی زیاد پیش میاد که میخواید یه چیزی مثل یه متن پیام ساده، یه اسپرایت، یا حتی کامپوننت های پیچیده تری که ساختید، مثل دشمن ها، آبجکت ها قابل کلیک  یا لمس باشن و با کلیک روی اون انتظار دارید، اتفاقی بیفته. برای این کار روش های مختلفی هست که بعضی هاش پیچیده ترن. اما من اینجا یه روش ساده و کاربردی بهتون یاد میدم.

    مطالبی که توی این آموزش پوشش داده میشه:

    1. معرفی نود Label
    2. استفاده از سیگنال‌ها
    3. معرفی ویژگی modulate برای تغییر رنگ و شفافیت

    کاری که انجام میدیم به طور خلاصه اینه: یک لیبل میسازیم و زیر مجموعه‌اش یه Button اضافه میکنیم. شفافیت button رو صفر میکنیم تا نامرئی بشه. بعد سیگنال pressed دکمه رو به لیبل متصل میکنیم و در فانکشن کلیک روی دکمه، متن رو ناپدید میکنیم. 

    مثل همیشه با یه صحنه جدید شروع میکنیم. ولی این بار به جای 2D scene، این بار Other node رو انتخاب میکنیم. این بار میخوایم به جای یک صحنه کامل، یه کامپوننت یا آبجکتی بسازیم که داخل هر صحنه ای قابل استفاده است. روند کار فرقی نمیکنه. 

    برای ایجاد صحنه جدید یا از منوی scene، گزینه new scene رو انتخاب کنید یا از بخش file system، کلیک راست کنید و create new و بعد scene رو انتخاب کنید. وقتی میخواید نود سرشاخه رو انتخاب کنید، روی other node کلیک کنید:

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

    حالا نود label رو انتخاب کنید و از تب inspector در سمت راست، در قسمت Text، به فارسی بنویسید: "کلیک کن تا ناپدید بشم".

     از بهترین قابلیت‌های گودو پشتیبانی فوق‌العاده خوب از زبان فارسیه.  

     و بعد پایین تر برید و از Theme override و بعد font size فونت در به 30 تغییر بدید تا متن بزرگتر بشه.

    با کلیک روی نود label، گزینه add child رو کلیک میکنیم و یه Button زیر مجموعه لیبل اضافه میکنیم. توی صحنه اندازه button رو با اندازه لیبل برابر میکنیم.

    قدم بعدی اینه که دکمه رو نامرئی کنیم. بعد از انتخاب دکمه، از اینسپکتور قسمت visibility رو باز میکنیم . روی modulate کلیک میکنیم. modulate بخشیه که رنگ و شفافیت نود رو مشخص میکنه. ما نمیخوایم رنگ رو تغییر بدیم، بلکه میخوایم شفافیت رو 0 کنیم. یعنی کاملا نامرئی. قسمت modulate، چهار تا اسلایدر داره که سه تای اولی برای رنگ و آخری برای شفافیته. آخری رو میگیریم و میکشیم تا به 0 برسه. خواهید دید که دکمه کاملا نامرئی میشه. همون چیزی که میخواستیم. 

    حالا به نود label یه اسکریپت اضافه میکنیم و سیگنال pressed از دکمه رو به label متصل میکنیم. اینها رو توی آموزش‌های قبلی توضیح دادم و توی تصویر هم مشاهده میکنید.

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

    بیاید نتیجه کار رو ببینیم.

    این ترفند خیلی کاربردیه. توی بازی ای که خودم ساختم ازش استفاده کردم. این ترفند شما رو از کلی دردسر راحت میکنه. با این کار به راحتی هر چیزی رو توی بازی میتونید قابل کلیک و لمس (مناسب بازی‌های موبایلی) میکنه. فکر کنید توی چه بازی هایی میتونید ازش استفاده کنید؟ فرض کنید یه بازی دارید که توی اون، در یه زمان مشخص باید هر چقدر میتونید سنگ طلا جمع کنید و اگه روی دینامیت‌ها کلیک کنید جون از دست میدید. اگه روی 3 تا دینامیت کلیک کنید میبازید. این جا با این ترفند همه طلاها و دینامیت ها رو قابل کلیک و لمس کنید و بازی خودتون رو بسازید. اگه این تمرینو انجام دادید بهم بگید. موفق باشید. 

  • 0 نظر
  • 2 پسند
    • danial abdl
    • 12:48 1402/07/21