گودو گیم دو، بلاگ بازی سازی با انجین گودو 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

    روش ساده سیو و لود داده ها در گودو در قالب یک پروژه ساده

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

    آموزش رو در قالب یک پروژه کوچیک انجام میدیم و در آخر فایل پروژه رو براتون میذارم و میتونید دانلود کنید.

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

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

    پروژه ما در ابتدا این شکلی خواهد بود.

    همچنین در این پروژه دوتا اسکریپت داریم. یکی که به نود دوبعدی سرشاخه ضمیمه میشه و یکی به نام general که اتولود میشه و توابع سیو و لود و ریست کردن داده اونجا قرار داره. روی دکمه ها متن های لازم رو نوشتم و و لیبل هم همین طور. 

     بخش اتولود که فایل general رو قرار میدیم این شکلی میشه.

    لازمه که برای هر دو دکمه، سیگنال pressed  رو به نود سرشاخه وصل کنیم که با این کار داخل اسکریپت node2d، دوتا تابع برای دو دکمه ایجاد میشه. در اسکریپت node2d، یک متغیر به نام coin مثلا برای تعداد سکه میسازیم. توی تصویر بالا برای لیبل و یکی از دکمه ها متغیر ایجاد کردم که ضروری نبوده و لازم نیست شما انجام بدید. در ابتدا اسکریپت نود 2d به این صورته. 

    بعد توی اسکریپت general چندتا کار باید انجام بدیم. 

    • یک متغیر برای سکه ها (که قراره برای سیو و لود استفاده بشه) ایجاد کنیم که من برای این که با اون یکی متغیر اشتباه نگیریدش به نام G_coin ساختم. 
    • یک متغیر رشته ای برای ذخیره مسیر فایلی که متغیر ما قراره توش سیو بشه که اسمش رو گذاشتم coin_save_path. دقت کنید که در ابتدای این آدرس از "user" استفاده شده و به فرض در موبایل، این ادرس میشه فولدر اصلی گوشی شما یا به اصطلاح root. 
    • یک تابع برای سیو. در این تابع کاری که انجام میدیم اینه که یک فایل ایجاد میکنیم و اون رو برای ذخیره کردن یا WRITE باز میکنیم، و متغیر G_coin رو در اون ذخیره میکنیم. 
    • یک تابع برای لود کردن. در این تابع اول بررسی میکنیم که اگر فایلی که قراره ساخته بشه وجود داره(برای جلوگیری از خطا) متغیر ذخیره شده رو در متغیر G_coin قرار بده یا لود کنه.
    • یک تابع برای ریست کردن مقدار ذخیره شده. برای این که بتونید برنامتون رو بارها تست کنید. اسکریپت general به این شکل خواهد بوددقت کنید که برای ذخیره کردن در فایل WRITE استفاده میشه و برای لود کردن از READ. یک نکته دیگه این که من تابع reset_coins رو در تابع ready فراخوانی کردم، ولی فعلا به صورت کامنت درش آوردم تا فراخوانی نشه. بعدا درباره این توضیح میدم. 

    حالا باید در اسکریپت node2d تغییراتی ایجاد و اون رو تکمیل کنیم. اسکریپت در آخر اینجوری میشه:

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

    • وقتی دکمه افزایش عدد زده(button2) میشه، مقدار coin ده تا افزایش پیدا میکنه و متن لیبل هم به روز میشه، یعنی دوباره مقدار جدید میگیره. دقت کنید که کلمه score و علامت : به مقدار عدد سکه اضافه میشه. 
    • وقتی دکمه ذخیره (button) زده میشه، اول مقدار G_coin برابر با مقدار coin میشه. به این دلیل که ما مقدار coin رو تغییر دادیم. میخوایم مقدار G_coin  که قراره ذخیره بشه هم بروز بشه. و بعد تابع save_coin فراخوانی میشه و مقدار رو ذخیره میکنه. به طور کلی coin  در G_coin ذخیره میشه و بعد در فایل ذخیره میشه. 
    • در تابع ready  که در ابتدای برنامه لود میشه، قراره عمل لود کردن رو انجام بدیم. پس اول تابع load رو از general فراخوانی میکنیم. بعد مقدرا coin رو برابر با مقدار G_coin که تازه از فایل لود شده میکنیم. و در نهایت هم متن لیبل رو بروزرسانی میکنیم. چون تا مقدار جدید رو نمایش ندیم نمیتونیم بفهمیم که سیو و لود به درستی انجام شده یا نه. 

    حالا وقتی پروژه رو اجرا کنید باید با چنین چیزی روبرو بشید:

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

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

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

    فایل پروژه:

    دانلود

  • 0 نظر
  • 0 پسند
    • danial abdl
    • 16:00 1402/08/10

    تجربه پس از انتشار بازی اندروید و راه‌هایی برای دیده شدن

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

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

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

    راه هایی که وجود داره:کانال‌های اجتماعی و ارتباطی قوی، تبلیغات و راه‌هایی که به ذهن شما میرسه (توی کامنتها بگید). برای من این طور پیش رفت که بعد از خروج از لیست جدیدترین‌ها، آمار مشاهده و نصب خیلی پایین اومد و در کانالهای ارتباطی که داشتم هم به اندازه کافی اطلاع رسانی کردم. به فکر تبلیغ افتادم. نوعی از تبلیغات به اسم تبلیغات نصب وجود داره که خلاصه اش اینه که با مقدار مشخصی بودجه، و این که برای هر نصب حاضرید چقدر هزینه کنید، بازی شما اونقدر در مارکت به کاربرا نشون داده میشه تا به اون تعداد نصب برسید. باید احتیاط کنید. هزینه تبلیغات بالاست و باید به فکر برگشت این هزینه باشید. من از تبلیغات با بودجه بسیار محدود استفاده کردم. برای هر مارکت حدود 500 هزار تومن و برای این که بدونید 500 هزار تومن یعنی چی، با این مبلغ در این تاریخ، میشه حدود 200 نصب گرفت. این جا آمار مشاهده و نصب دو روز تبلیغات در مایکت رو براتون میذارم

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

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

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

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

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

    اعتراف میکنم که خیلی امیدوار نبودم که بپذیرن ولی همون روز پذیرفتن و و همون روز بازی در یکی از لیست ها قرار گرفت (کافه بازار) و در روزهای بعدی هم در لیست های پربازدیدتری قرار گرفت. در واقع اول بازار قبول کرد که بازی رو در لیست "تازهای معمایی" قرار بده و چند روز بعد در لیست "تازه به بازار رسیده" در صفحه اصلی قرار بده. مایکت هم اول بازی رو در لیست "تازه های منتخب" بازی‌های فکری و بعد از چند روز در لیست "تازه های منتخب" در صفحه اصلی قرار داد. 

    آمار چند روز رو براتون میذارم

    دقت کنید که اون نسبت نصب به مشاهده که بالاتر در قسمت تبلیغات گفتم اینجا متفاوته. برای مثال نسبت نصب به مشاهده مایکت در روز 30 مهر، 9 درصده که نسبت به  تبلیغات بالاتره. با تبلیغات من 138 نصب در یک روز رسیدم، در حالی که وقتی در لیست های پربازدید قرار گرفتم بدون هزینه به 625 نصب رسیدم.

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

    در آخر نتیجه های مهم رو مرور میکنم:

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

    دوست دارم شما هم تجربه های خودتون رو بگید و هر سوالی داشتید بپرسید. امیدوارم مطالعه این تجربه برای شما مفید باشه.

  • 0 نظر
  • 1 پسند
    • danial abdl
    • 11:57 1402/08/04