آموزش ساخت پایه انیمیشن انجین با اکشن اسکریپت

mehdadoo

Member
تو این آموزش، ساخت کلاس های انیمیشن در اکشن اسکریپت ۳ رو با هم مرور میکنیم.
در پایان یک موتور ساده برای انیمشین با کد درست میکنیم، که برای پروژه های cpu intensive فلش به کار خواهد اومد. چون نتیجه کلاس بسیار کم حجمی خواهد بود.
مدیریت تمام انیمیشن فقط در یک کلاس ساده انجام میشه، و الگوریتم های حالت انیمیشن به عهده کلاسهای کمکی دیگه خواهد بود.

هدف نهایی اینه که بتونیم خصوصیت (proprty) یک شی رو با دو خط انیمیت کنیم. مثلا اگر یک movieClip به نام _square داشته باشیم، بتونیم به این سادگی به حرکتش در بیاریم:

کد:
_animator = new Animator(_square, "x", 50, 450, 2000, Elastic.easeInOut);
_animator.start();
کد بالا با استفاده از موتوری که خواهیم ساخت، مکان شی رو در محور x، در دو ثانیه از ۵۰ به ۴۵۰ تغییر میده، اون هم با یک حالت انیمیشن بسیار جذاب!(main.swf در فایل های پیوستی)


خوب، ما یک کلاس مهم میسازیم، اون هم Animator.as هست. فانکشن new animator نیاز به چند چیز داره: یک آبجکت که میخواهیم خصوصیتیش رو تغییر بدیم، خصوصیتی رو که میخواهیم در طول انیمیشن تغییر بدیم، نقطه شروع و نقطه پایان. همین طور مدت زمانی که میخواهیم انیمیشن به درازا بکشه. این توسط
کد:
private var _object : Object;
private var _property : String;
private var _startValue : Number;
private var _endValue : Number;
private var _changeValue : Number;
private var _time : Number;
در کلاس Animator ذخیره میشن.

با استفاده از اعداد وارد شده، باید مقدار تغییر رو محاسبه کنیم. در مثال بالا مقدار ۴۵۰ - ۵۰ مقدار تغییره.
کد:
_changeValue = _endValue - _startValue;
همین طور در یک انیمیشن انجین ما باید تعداد به روزرسانی رو هم اندازه بگیریم. اگر بخواهیم هر ۳۰ هزارم ثانیه شی رو به مقصدش نزدیک تر کنیم، پس در طی ۳۰۰۰ میلی ثانیه (۳ ثانیه) با ید صد بار مکان آبجکت رو تغییر بدیم.
کد:
_totalIntervals = Math.floor(_time / Animator.intervalTime);
البته برای شروع انیمیشن باید از start() استفاده کنیم.

کد:
function start() : void
{
	_object[_property] = _startValue;
	_timer = new Timer(Animator.intervalTime, _totalIntervals);
	_timer.addEventListener(TimerEvent.TIMER, runTween, false, 0, true);
	_timer.start();
}
ابتدا خصوصیتی از شی رو که میخوایم انیمیت کنیم رو به نقطه شروع میبریم.
بعد یک شی تایمر میسازیم و اعدادی که قبلا محاسبه کردیم رو بهش میدیم. این شی در ۳ ثانیه آینده هر ۳۰ هزارم ثانیه یک بار، یعنی جمعا صد بار فانکشن runTween رو صدا میزنه.
مهم ترین قسمت کلاس runTween هست که کمی جلوتر به توضیح میپردازم.ولی فعلا باید بدونید فانکشن halt صرفا پس از رسیدن شی به مقصد انیمیشن رو متوقف میکنه. فانکشن die هم کلاس رو پاکسازی میکنه.
تمام قسمتی که باقی مونده تعیین کار runTween هستش. برای توضیح ساده تر، از الگوی یک نواخت استفاده میکنم.
کد:
function runTween(pEvent : TimerEvent) : void
{
	_object[_property] = _startValue + ((_changeValue/_totalIntervals) * timer.currentCount);
	if (_timer.currentCount >= _totalIntervals)
	{
		_object[_property] = _endValue;
		halt();
	}
}
اینجاخصوصیتی ازشی که در حال انیمیت شدن هست، در هر لحظه عدد جدیدی رو به خودش میگیره. فرمول ساده بالا به این گونه کار میکنه که مقداری که در هر عملیات به روزرسانی باید شی تغییر کند رو ضربدر زمان سپری شده میکنه و نتیجه رو با عدد شروع انیمیشن جمع میکنه. خیلی منطقی و ساده. البته درک این مطلب با یک مثال ساده تره.(انیشتن گفته مثال یکی از راه های یادگیری نیست، مثال تنها راه یادگیریه!) به عنوان مثال، اگر در حال انیمیت کردن x شی به نام clip بودبم، و میخاستیم در ۲ ثانیه x رو از ۵۰ به ۴۵۰ ببریم، _changeValue عدد ۴۰۰ می بود و _totalIntervals حتما ۶۶ میبود(۲۰۰۰ هزارم ثانیه تقسیم بر فاصله به روزرسانی). این یعنی پس از گذشت یک ثانیه از انیمیشن timer.currentCount برابر ۳۳(نصف ۲ ثانیه که جمعا باید ۶۶ به روزرسانی در کل داشته باشم) است. فرمولش هم این طوری میشه:
clip.x = 50 + ((400 / 66) * 33);
طبیعیه که clip در ثانیه ۱ انیمیشن در x برابر با ۲۵۰ قرار خواهد داشت، عدد بین ۵۰ و ۴۵۰.

و همش همین بود. شرط آخر هم چک میکنه که اگر تعداد به روز رسانی از عدد نهایی بگذره(در این مثال از ۶۶ بگذره)، انیمیشن تموم شده طلقی بشه و halt صدا زده بشه.


برای قسمت مهم انجینمون ما باید از حالت های انیمیشن با easing ها استفاده کنیم. اون ها الگوریتم های زیباو پیچیده ای هستند، که از قضا Robert Planner همه رو به کد در آورده. ما هم از فرمول های این ریاضی دان استفاده میکنیم. فقط کافیه به جای
کد:
_object[_property] = _startValue + ((_changeValue/_totalIntervals) * timer.currentCount);
از یک الگوریتم دیگه استفاده کنیم.
فقط کافیه در زمان به کار گیری کلاس مثلا از
‌Back.easeInOut
استفاده کنیم و میبینید که با یک کلمه به افکت متقاوتی دست پیدا خواهیم کرد.

کد پایانی گویای تمام جزییات هست.

با درست کردن این انجین ساده، نه تنها ما پایه انیمیشن در فلش رو یاد گرفتیم، بلکه میتونیم در پروژه هامون از یک کلاس خیلی خیلی سبک، ده ها بار سبک تر از fl.motion یا mx.effects بهره ببریم.
هدف ساختن موتور کامل انیمیشن نبود(که البته با اضافه کردن امکانات ساده به راحتی میشه بهش دست یافت)، هدف یادگیری برنامه نویسی پایه انیمیشن بود.
 

پیوست ها

  • Animation.zip
    27.7 کیلوبایت · بازدیدها: 107
آخرین ویرایش:

جدیدترین ارسال ها

بالا