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

روش اول-استفاده از Swing timer:
در این روش از کنترل timer از دسته کنترلهای Swing استفاده میکنیم. در واقع در این روش،حرکت تصویر را، در بازه های زمانی متوالی ای که به کمک timer ها ایجاد کردیم،بارها فراخوانی میکنیم.
خب!با این توضیحات کار را عملا شروع میکنیم.
کلاس اصلی برنامه (کلاس Board) را در یک کنترل Jpanel ایجاد میکنیم.
این فرم کلی کلاس Board ما خواهد بود،که با توضیحات بخش به بخشمان ،در نهایت به آن خواهیم رسید:

 

 

حال به تحلیل کد فوق میپردازیم:

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

(درباره ی ActionListener نیز جلوتر توضیح خواهیم داد.)

– شی ای از کلاس image  تولید میکنیم که بعدا برای به نمایش درآوردن عکس فوق از آن استفاده خواهیم کرد.
– بعد از آن شی ای از کلاس Timer ایجاد میکنیم برای زمان حرکت تصویرمان.

– در کلاس Board  با دستور

زمینه ی پنجره ی خروجی را به رنگ سفید در آوردیم.

 

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

 

– از آنجایی که کل ترسیماتی انجام میشوند ،قبل از اینکه به نمایش در آیند ابتدا بر روی حافظه قرار میگیرند و سپس از بافر به روی صفحه برنامه کپی میشوند ، از دستور

استقاده میکنیم (به این معنا که کنترل Jpanel  برای رسم ، از بافر استفاده میکند.)

 

-با استفاده از دستورات زیر یک شی از کلاس Swing Timer ایجاد  کردیم و سپس تایمر را فعال کردیم .

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

 

 

– بعد از آن، وقت این است که تصویرمان را به نمایش در بیاوریم، در کلاس paint به کمک دستور

 

اینکار را انجام میدهیم ،دو مولفه ی x,y هم همانطور که در مقاله ی قبل اشاره شد، همان فاصله ی تصویر از بالا و سمت چپ پنجره ی خروجی است،که آنها را از نوع Int  معرفی و مقداردهی کردیم.

 

 

-اما همانطور که در ابتدای مقاله اشاره شد، قصد ما صرفا نمایش یک تصویر نیست، بلکه میخواهیم این نمایش به طور پیوسته در پنجره ی خروجی به حرکت درآید.
این پیوستگی را توسط synchronize و با دستور زیر انجام میدهیم:

 

 

 

-خب برای اینکه به تصویرمان قابلیت حرکت بدهیم ، باید از actionPerformed استفاده کنیم.
درون این کلاس میزان افزایش مختصه ی x,y  را در هر مرحله مشخص میکنیم.
اما برای استفاده از این کلاس لازم هست که ابتدا متد ActionListener را پیاده سازی کنیم.که برای این منظور کلاس اصلیمان (Board) را از ActionListener، implement  میکنیم.

 

به تابع actionPerformed برمیگردیم، در این تابع مقدار افزایش X , Yتصویر را بزای هر بار حرکت ، 1 در نظر گرفتیم.واضح است که اگر این مقداررا افزایش دهیم، حرکت تصویر را سریعتر میبینیم.

 

اما این کافی نیست.باید متد repaint()  رافراخوانی کنیم  تا گرافیکهای رسم شده بر روی کامپوننت های swing بروز رسانی شوند . در واقعrepaint()باعث میشود که متد paint  بارها و بارها فراخوانی شود،و اگر این متد را قرار ندهیم تصویر حرکت نمیکند .

خب اگر، کلاس main  رو هم مطابق آموزش قبل ایجاد کنید :

 

 

 

 

Java

 

با اجرای برنامه ، میبینید که مثلث از گوشه سمت چپ بالای پنجره ی خروجی به سمت راست پایین پنجره حرکت میکند:

 

Java-Game

 

اما وقتی از گوشه ی سمت راست پنجره خارج میشود، دیگر ظاهر نمیشود.(در صورتیکه ما میخواستیم این حرکت همواره ادامه پیدا کند.)
برای حل این مشکل باید در تابع actionPerformed این شرط را قرار دهیم که وقتی تصویر از پنجره خارج شد (یعنی وقتی y  تصویر بیشتر از ارتفاع پنجره ی خروجی شد) با مقداردهی دوباره ی x ,y  ، تصویر دوباره از گوشه ی سمت چپ پنجره به نمایش در آید:

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

 

روش دوم – استفاده از thread(چند نخی):

همانطور که گفتیم متحرک سازی اشیا به کمک thread ها، بهترین و دقیقترین روش میباشد.

ما در روش قبل ، یک وظیفه (که نمایش تصویر بود) را تعریف کردیم و در بازه های زمانی متوالی ، مدام این وظیفه

را تکرار میکردیم. اما در روشی که در این قسمت ، مطرح میکنیم، کل انیمیشن را در یک thread  (نخ) قرار میدهیم و تنها یکبار متد  run ()  را فراخوانی میکنیم .
در تابع run()   یک حلقه ی تکرار درنظرمیگیریم که بارها وبارها متدهای cycle()  (که میزان افزایش مختصه های x,y  را در هر حرکت، درآن  پیاده سازی کردیم)و repaint()  را فراخوانی میکند.

قطعه کد کلاس  Board  به شکل زیر خواهد بود :

 

 

مشاهده میکنید که در اینجا خبری از timer  نیست!

یک thread  ایجاد کردیم و درمتدaddNotify() ، اینthreadرا (animator)، فعال کردیم.
“اما یک نکته ی مهم این است که ، برای استفاده از thread  ها باید حتما کلاس اصلی را از Runnable ، implement کنیم.”
در واقع ما کلاسی(تحت عنوان Board) تعریف کردیم که اینترفیس Runnable را implement کند. سپس آن کلاس متد run را implement می کند. که وقتی Thread ساخته می شود، یک آرگومان پاس داده می شود و start می شود.
متد Board  () و paint() ، همانطور که مشاهده میکنید،مطابق روش قبل پیاده سازی میشوند.

-خب به متد run()  میرویم :
درون این متد ابتدا تنها یک حلقه ی while  قرار دهید و توابع cycle و  repaint را در آن فراخوانی کنید، یعنی به این شکل:

 

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

 

متغیرbeforeTime زمان قبل از ورود به حلقه ی تکرارمان را در هر بار مشخص میکندو timeDiff زمان لازم برای اجرای متد.
متغیر sleep ، همان استراحتی خواهد بود که بین هر دو حرکت متوالی ، خواهیم داشت.که از کم کردن زمان لازم برای اجرای هر دو متد از متغیر ثابت DELAY بدست می اید.
حال کافیست  این زمان را برای توقف فراخوانی کنیم:

 

در این مقاله هم با مفهوم انیمیشن و چگونگی ایجاد آن در جاوا آشنا شدیم .
انشالله در مقاله ی بعدی ،کار با sprite ها رو شروع میکنیم.

 

 

 

ozviiiiiiiat