اشتباهات رایج در استفاده از ایونتهای کانستراکت 2
|توقّع دقیق بودن محاسبات ریاضی
تمام کامپیوترهای مدرن اعداد اعشاری را در قالبی مثل 0.5 نگهداری میکنند. چون حافظه و قدرت پردازش کامپیوتر بینهایت نیست، کامپیوتر مجبور میشود کمی اعداد را گرد کند. این به نوبهی خود میتواند باعث شود جوابی که کامپیوتر به دست میآورد کمی دور از جواب حقیقی باشد، مثلاً در جایی که توقّع دارید کامپیوتر به شما عدد 1 را نشان دهد عدد 0.999999 را نمایش میدهد.
حالا توضیح میدهیم این مشکل چرا پیش میآید. تقسیم عدد 1 بر 3 را در نظر بگیرید. جواب میشود 0.3333333… که همین طور تا ابد 3 تکرار میشود. امّا کامپیوتر حافظهی محدودی دارد و نمیتواند بینهایت عدد مثل این بینهایت 3 را در حافظهاش نگه دارد. بنابراین فقط تعداد محدودی از اعشار را ذخیره میکند و بعد از آن، محاسبه را متوقّف میکند. مثلاً فقط تا 6 رقم اعشار را نگه میدارد و جواب میشود 0.333333 . این از لحاظ ریاضی غلط است، ولی کامپیوتر نمیتواند جواب درست را نگه دارد. حالا فرض کنید این جواب را مجدداً در 3 ضرب کنیم. شما انتظار دارید سه ضربدر یکسوّم برابر 1 شود، ولی در حقیقت عدد 0.999999 را دریافت میکنید که خیلی به جواب اصلی نزدیک است، ولی دقیق نیست. اگر بازی شما بخواهد که جواب دقیقاً مساوی 1 شود، آنگونه که انتظار دارید عمل نمیکند. معمولاً میتوانید از طریق دیباگر (debugger) جوابی را که واقعاً محاسبه میشود بررسی کنید.
این نوع مشکل در محاسبات اعشاری در اغلب نرمافزارها وجود دارد. راه فراری نیست! این حقیقت نحوهی عملکرد کامپیوترهاست. مثال ما در بالا در مبنای 10 بود، درحالیکه کامپیوتر در مبنای 2 کار میکند، و دورهی گردش رقمهای اعشار در مبنای 2 با مبنای 10 فرق میکند. یعنی 0.1 در مبنای 10 یک عدد اعشاری مختوم است و دورهی گردش ندارد، ولی همین عدد وقتی به مبنای 2 میرود دارای دورهی گردش میشود. یعنی این مشکل حتّی در مواقعی که انتظارش را هم ندارید میتواند اتّفاق بیفتد، حتّی اگر فکر کنید که دارید با اعداد دقیقی محسابه میکنید. این مشکل مخصوصاً در محلّ اشیاء اثر میگذارد، چون حرکت یک شیء در زاویهای خاص معمولاً نیاز به محاسبات سینوس و کسینوسی دارد، که معمولاً جواب بسیار نزدیکی به جواب اصلی به دست میآید، ولی دقیق نیست.
راهکاری که میتوانید از آن در هر نرمافزار و فریمورکی برای حلّ این مشکل استفاده کنید این است که مقداری تلرانس[1] را مجاز اعلام کنید. توقّع نداشتهباشید ایونتی مثل Sprite.X = 100 همیشه درست کار کند. به جای آن از چیزی مثل [2]abs(Sprite.X – 100) < 0.01 استفاده کنید. این کار مقایسهی شما را درست میکند، زیرا اگر نتیجه تا 0.1 از 100 فاصله داشت، باز هم ایونت اجرا میشود. پس اگر مثلاً عدد ما 99.999999 شد باز هم همان طور که انتظار داریم، ایونت اجرا میشود.
[1] تلرانس: به خطای مجاز تلرانس گفته میشود، مثلاً میگوییم اگر جواب به دست آمده تا 0.2 با جواب اصلی فرق داشت عیبی ندارد (در این حالت تلرانس ما 0.2 است).
[2] طبق اصول ریاضی، قدر مطلق تفاضل دو عدد، فاصلهی آن دو از هم را نشان میدهد. پس در اینجا گفتهایم اگر فاصلهی بین Sprite.X و 100 کمتر از 0.01 باشد اکشنها را اجرا کن (در این مثال تلرانس 0.01 است)
سلام وخسته نباشید به داداش گلم اقامجتبی
من 2تابازیکن دارم که میخوام به هرکدوم یک ماموریت مخصوص بدم که هرکدوم وظیفه داده شده راانجام بده. به طور واضح تربگم میخوام وقتی به پلیر Aماموریت دادم به ماموریتش به پردازه و درهمان زمان من پلیر Bرا ماموریت بدم
ایشالا جوابمو بگیرم
علیک سلام
لطفاً سؤالاتتون رو در انجمن بپرسید.
سلام خسته نباشید
میخواستم بدونم چگونه stop و play برای بازی ام بسازم؟؟؟
ممنون
علیک سلام،
میتونید جلسهی ششم دورهی تابستانی ما رو ببینید:
http://construct2.ir/showthread.php?tid=609
خواهش میکنم