محمود صاحبی
محمود صاحبی
خواندن ۲ دقیقه·۵ سال پیش

مشکل تبدیل اعداد به استرینگ در GMS

در این پست قصد دارم در مورد مشکل گیم میکر در تبدیل اعداد به استرینگ (string) و روش حلش صحبت کنم، مشکلی که از ابتدای ظهور گیم میکر حضور داشته و همچنان هم هست.

نیاز ما

تابعی که ما می خوایم باید با پرفورمنس خیلی خوبی عدد اعشاری رو با تعداد رقم دلخواه ما به استرینگ تبدیل کنه، مثلا اگه گفتیم 3.21462 با دقت 3 رقم اعشار به استرینگ تبدیل بشه نتیجه به سادگی بشه "3.215"، یا اگه 1.5 رو با دقت 3 رقم به استرینگ تبدیل کردم حاصل همون "1.5" باشه و رشتمون صفر اضافی در انتهاش نداشته باشه.

مشکل

در گیم میکر اما قضیه متفاوته. کد زیر رو در نظر بگیرید:

a = 1.5; b = 3.1415926536; show_debug_message( string(a) ); show_debug_message( string(b) );

خب اگر کد بالا رو در گیم میکر اجرا کنید نتیجه می شه "1.50" و "3.14". خب مشکلش کجاست؟ یک مشکل اینه که تابع string فقط تا دو رقم اعشار رو به ما نشون می ده و ممکنه ما بخوایم بیشتر یا کمتر از دو رقم نمایش بدیم. مشکل دوم اینه موقع تبدیل 1.5 به استرینگ ، یک صفر اضافی به انتهای استرینگ اضافه می‌شه که دلخواه ما نیست.

اما گیم میکر تابع دیگه هم برای تبدیل عدد به استرینگ داره به نام string_format که اجازه می ده تعداد ارقام اعشار مورد نظرتون رو تعیین کنید اما به نظرم به جای حل مشکل، قضیه رو پیچیده تر هم می کنه. اینجا دیگه توضیحی در مورد روش عمل این تابع نمی دم، فقط خروجیش رو بهتون نشون می دم:

show_debug_message( string_format(1234, 8, 0) ); show_debug_message( string_format(1234, 1, 5) ); show_debug_message( string_format(pi, 5, 5) );

که خروجیش می شه:

&quot    1234&quot &quot1234.00000&quot &quot    3.14159&quot

خب نتیجه واقعا بده و از چیزی که ما می خوایم مطمئنا خیلی فاصله داره.

راه‌حل

یک اسکریپت جدید می سازیم و اسمش رو می ذاریم StringFloat (شما می‌تونید هر اسمی بخواید بذارید). کدش به این صورته:

/// @arg float /// @arg precision /// @desc The precision must be a power of 10 like 10/100/1000/10000... var _frac = abs(round(frac(argument0)*argument1)); if _frac == 0 return string(argument0); while (_frac mod 10) == 0 _frac = _frac div 10; return string(argument0 div 1) + &quot.&quot + string(_frac);

این تمام چیزیه که ما نیاز داریم. آرگومان اول عدد مورد نظرمونه (از نوع real) و آرگومان دوم دقت تبدیله که حتما باید مضرب 10 باشه. به این مثال ها دقت کنید:

// s1 = &quot3.215&quot var s1 = StringFloat(3.21462, 1000) // s2 = &quot3.1416&quot var s2 = StringFloat(pi, 10000); // s2 = &quot3&quot var s3 = StringFloat(3, 100); // s3 = &quot1.2&quot var s4 = StringFloat(1.2, 10000);

توجه کنید تعداد صفر‌های آرگومان دوم می شه دقت تبدیل، در مثال بالا عدد 1000 یعنی تبدیل با دقت سه رقم و 10 یعنی تبدیل با دقت 1 رقم و الی آخر.

جمع‌بندی

من سعی کردم تا جای ممکن از if های بی مورد پرهیز کنم. اولویت اصلی من پرفورمنس خیلی بالا بود چون این اسکریپت احتمالا قراره خیلی استفاده بشه. فقط توجه کنید که اگه ورودیش از نوع real نباشه با ارور مواجه می شید، که این هم با تابع is_real قابل بررسیه تا به خطا نخورید.

خوش باشید.

gamemakerگیم میکرtutorialآموزش
مشاهده گر
شاید از این پست‌ها خوشتان بیاید