در این پست قصد دارم در مورد مشکل گیم میکر در تبدیل اعداد به استرینگ (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) );
که خروجیش می شه:
" 1234" "1234.00000" " 3.14159"
خب نتیجه واقعا بده و از چیزی که ما می خوایم مطمئنا خیلی فاصله داره.
یک اسکریپت جدید می سازیم و اسمش رو می ذاریم 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) + "." + string(_frac);
این تمام چیزیه که ما نیاز داریم. آرگومان اول عدد مورد نظرمونه (از نوع real) و آرگومان دوم دقت تبدیله که حتما باید مضرب 10 باشه. به این مثال ها دقت کنید:
// s1 = "3.215" var s1 = StringFloat(3.21462, 1000) // s2 = "3.1416" var s2 = StringFloat(pi, 10000); // s2 = "3" var s3 = StringFloat(3, 100); // s3 = "1.2" var s4 = StringFloat(1.2, 10000);
توجه کنید تعداد صفرهای آرگومان دوم می شه دقت تبدیل، در مثال بالا عدد 1000 یعنی تبدیل با دقت سه رقم و 10 یعنی تبدیل با دقت 1 رقم و الی آخر.
من سعی کردم تا جای ممکن از if های بی مورد پرهیز کنم. اولویت اصلی من پرفورمنس خیلی بالا بود چون این اسکریپت احتمالا قراره خیلی استفاده بشه. فقط توجه کنید که اگه ورودیش از نوع real نباشه با ارور مواجه می شید، که این هم با تابع is_real قابل بررسیه تا به خطا نخورید.
خوش باشید.