بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

آشنایی با کتابخانه AndEngine (موتور بازی سازی) + آموزش

Criss  10 سال پیش  6 سال پیش
+54 0

 

http://dchabmztumu0g.cloudfront.net/wp-content/uploads/2012/12/logoimage.png

 

Nicolas Gramlich

andengine.org

Forums

نصب APK از مثال ها (این نسخه قدیمی هست و آپدیت نشده !)

تعداد از بازی های ساخته شده با AndEngine از جمله عنکبوت حریص و Noogra Nuts

 Blog (پیشنهاد میکنم تغییر آیپی بدید < که بتونید کلیپ های یوتیوب توی این آدرس رو ببینید)

از بازی هایی که سازنده AndEngine یعنی (Nicolas Gramlich) برای نمونه ساخته (به کم حجم بودن بازی ها دقت کنید)

این بازی هم با AndEngine نوشته شده

گفتوگوی جام جم با میلاد دورباش که از AndEngine استفاده کرده  (لینک بازی)

استخدام برنامه نویس AndEngine در ایران ! ! ! (لینک های بیشتر)

منابع آموزشی :

//


 

از تمام دوستانی که این موضوع براشون جالب هست و علاقه به یادگیری دارند دعوت میکنم در تولید مقاله های آموزشی کمک کنند < ، سعی میکنم انجمنی رو برای یادگیری AndEngine شروع کنیم ، باید ببینم شرایط چطور پیش میره ، به احتمال زیاد تاپیک پرسش و پاسخ AndEngine و آموزش ها در همین Uncocoder ادامه پیدا میکنه و از اینجا خارج نشیم


# بر چسب :

AndEngine ، آموزش AndEngine ، فارسی AndEngine ، اندروید ، بازی سازی ، بازی اندروید ، ساخت بازی ، اندانجین ، AndEngine Toturial ، android game ، game maker android

AndEngine for Android Game Development Cookbook

Learning Android Game Programming

+1 0
ممنون بابت آموزش ها و وقتی که گذاشتی و میخوای بزاری ، در مورد خود این andEngine بیشتر توضیح بدید ، مثلا اینکه برای ساخت بازی andEngine بهتر هست یا OpenGL (10 سال پیش)
+1 0
خیلی ممنون (10 سال پیش)
+1 0
ولی بهتر نبود یه دفعه یونیتی رو شروع میکردیم هرچیزی را بهره کاری ساختند... (10 سال پیش)
+1 0
سلام آقا criss خسته نباشید با آموزش خوبتون . من یه بازی ساختم 90 درصد کار رو رفتم و یکمی پیچیده شده و باب دلم در نیومده و از اونجایی ک قراره چند تا بازی دوبعدی دیگه طراحی کنم و با توجه به این که زحمت کشیدید آموزش AndEngine رو قرار دادید . خواستم یه نگاهی به بازی منم بندازی با تجربه ای ک تا الان کسب کردی نظرت رو درباره این که این بازی رو با AndEngine طراحی کنم چیه ؟ لینک ویدئو بازی لینک (10 سال پیش)
+1 0
البته این بازی بیش از 30 مرحله داره و نمیخوام زیاد سنگین بشه . (10 سال پیش)
0 0
@علی : پیام خصوصی شد (10 سال پیش)
0 0
با سلام ، تشکر از زحمات شما (10 سال پیش)
 برای این سوال 48 پاسخ وجود دارد.
پاسخ به سوال 
Criss  10 سال پیش
+15 0

توی این پست سعی میکنم راجب AndEngine سرچ کنم و هرچی نتیجه گرفتم اینجا توضیح بدم < (پس صحت و دقت این اطلاعاتی که اینجا میزارم بر اساس برداشت هایی هست که بعد از سرچ نتیجه گرفتم و هیچ تجربه مستقیم و عملی ندارم )


 

با استفاده از این موتور بازی سازی چیکار میتونیم کنیم ؟

  • با استفاده از موتور بازی سازی حرکت دادن یک کاراکتر روی صفحه خیلی راحت تر میشه ، میتونید برخورد کردن دو شی با هم ، ضربه زدن ها ، پرتاب شدن ها و . . . راحتر بسازید
  • حجم تصاویر در مصرف حافظه بهینه میشه
  • از مهمترین موارد موتور بازی سازی این هست که شما میتونید فیزیک رو بکار بگیرید وزن ، سرعت قدرت ضربه زدن ، گرانش و ... رو میشه شبیه سازی و استفاده کرد < مثلا جاذبه زمین رو شبیه سازی کنید و تمام کاراکترهای موجود رو به سمت دلخواه بکشید ، بازی انگری برد نمونه کاملی از استفاده از فیزیک توسط موتور بازی سازی هست
  •  و . . .

AndEngine یک موتور بازی سازی دو بعدی فقط برای اندروید هست ، که از (OpenGL ES or GLES) استفاده میکنه ، تفاوت هایی بین OpenGL , OpenGL ES وجود داره ، از اونجایی که اطلاعی در این زمینه ندارم نمیدونم چقدر این دو متفاوت هستند < ولی در مورد OpenGl ES درحال حاضر 3 نسخه موجود هست  که AndEngine از نسخه 2 استفاده میکنه البته نسخه قبلی AndEngine بر اساس GLES 1 بود :

  • OpenGL ES 1.1  : برای اندروید 1 و بالاتر .
  • OpenGL ES 2.0 :  از اندروید 2 (API Level 8) و بالاتر .
  • OpenGL ES 3.0 : این نسخه از OpenGL ES از اندروید 4.3 (API Level 18) و بالاتر .

 

یک مثال کوچیک از OpenGL : در پروژه های OpenGL بصورت معمول دو کلاس های GLSurfaceView و GLSurfaceView.Renderer استافده یجورایی این دو کلاس برای OpenGL شبیه همون ActivityMain خودمون میمونه ! برای آشنایی با OpenGL این پروژه رو به Eclipse اضافه کنید < (اصلا خودتون رو درگیر OpenGL نکنید < من چون دوستون بالاتر درخواست داده بودند سرچ کردن و اینجا قرار دادم < اصلا قرار نیست درگیر OpenGL بشیم)

لینک پروژه OpenGL Sample

کلمه عبور : uncox.com


  •  خب توضیحی که بالا دادم برای این بود که بدونید در حالی که AndEngine از OpenGL استفاده میکنه اما نیازی به دانش استفاده از OpenGL نیست
  • AndEngine برای توسعه دهندگان OpenSource هست (که اگر برنامه نویس خیلی خوبی باشید میتونید  در این موضوع دخالت کنید)
  • در AndEngine محیط گرافیکی نداریم و تمام قسمت های بازی با نوشتن کد پیش میره
  • یکی از نکات خوبی که بر خلاف Unity داره این هست که حجم بازی خیلی کم هست ، در حالی که برای Unity فک میکنم حداقل یک بازی ساده 10 مگابایت حجم داشته باشه (خب یونیتی فقط برای اندروید نیست و میتونید  ازش خروجی های متفاوت بگیرید ، ولی ما هدفمون اندروید هست)
  • من اعتقاد دارم با BatchFile ها میشه botnet طراحی کرد ، نبابراین در مورد قدرت و توانایی های این موتور که بعضی ها میگند متوسط هست نمیشه تصمیم گرفت ، چون خیلی ها هم این موتور رو حرفه ایی میدونند بلاخره باید دقت کنید این موتور دوبعدی و فقط برای اندروید هست ، در نهایت همه چیز به برنامه نویس بستگی داره که چقدر قدرت رو به نمایش بزاره
  • AndEngine تعدادی افزونه (Extention) داره که همانند خود AndEngine کتابخانه هستند و در کنار AndEngine به اکلیپس اضافه می شوند و توانایی های شما اضافه میکنند

 

AndEnginePhysicsBox2DExtension - برای بکارگیری فیزیک دو بعدی 
AndEngineMultiplayerExtension - زمانی که نیاز داشته باشید بازی چند نفره بازی بشه
AndEngineMultiTouchExtension - برای چند لمس همزمان روی صفحه
AndEngineLiveWallpaperExtension - فک کنم طبق اسمش برای ساخت LiveWallpaper باشه
AndEngineSVGTextureRegionExtension - اگر از فایل ها برداری همون تصاویر وکتور و "اس وی جی" استفاده میکنید
AndEngineTexturePackerExtension - برای انتخاب و برش زدن یک قسمت از اسپرایت شیت ها
AndEngineMODPlayerExtension - فکر میکنم برای اجرای فایل های صوتی 8 بیتی باشه
AndEngineTMXTiledMapExtension - فکر میکنم به شما کمک میکنه یه نقشه بزرگتر از اسکرین کوشی داشته باشید و با حرکت کردن به اطراف قسمت های بیشتر نمایش داده بشه و ساخت نشقه با تصاویر تکرای
//این موارد زیر رو هم نمیدونم چی هستند
AndEngineAugmentedRealityExtension
AndEngineRobotiumExtension
AndEngineScriptingExtension
AndEngineScriptingExtensionGenerator

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

http://www.slant.co/topics/1476/~2d-game-engines-for-android
https://software.intel.com/en-us/android/blogs/2012/03/13/game-engines-for-android
https://software.intel.com/en-us/blogs/2012/05/14/eight-popular-open-source-android-game-engines

در حال ویرایش . . .

پاسخ به سوال 
Criss  10 سال پیش
+14 0

نحوه اضافه کردن این کتابخانه به اکلیپس 

  • از همین ابتدا تاکید میکنم :
  • از اونجایی که هنوز به اندازه کافی تجربه کار رو ندارم و همراه با شما دارم هرچیزی رو که یاد میگیرم رو اینجا قرار میدم < حتما از لینک هایی که معرفی میکنم < استفاده کنید < به دلیل اینکه توی نسخه های مختلف ناپایداری های مختلفی وجود داره و ممکنه توی اکلیپس شما رو اذیت کنه < که در آینده با کسب تجربه ی بیشتر میتونیم این موضوع رو هم حل کنیم
  • برای خود AndEngine و تمام Extention ها نسخه JavaCompiler باید 1.6 باشه

 

برای اضاف کردن AndEngine به این آدرس گیت هاب برید فایل ZIP رو دانلود کنید بعد از Extract کردن اون رو به اکلیپس Import کنید < در صورتی که از پروژه ارور گرفتید < روی پروژه راست کلیک کرده < Properties و JavaCompiler رو 1.6 قرار بدید < از قسمت Android هم IsLibery رو تیک بزنید <

آموزش تصویری

کلمه عبور : uncox.com

0 0
cooooooooooool (10 سال پیش)
پاسخ به سوال 
Criss  10 سال پیش
+11 0

Extentions (افزونه ها)

آموزش تصویری

کلمه عبور : uncox.com

از این آدرس Extention هایی که زیر لیست کردم رو دانلود کنید <

AndEngineAugmentedRealityExtension
AndEngineDebugDrawExtension
AndEngineExamples
AndEngineLiveWallpaperExtension
AndEngineMODPlayerExtension
AndEngineMultiplayerExtension
AndEnginePhysicsBox2DExtension
AndEngineSVGTextureRegionExtension
AndEngineTexturePackerExtension
AndEngineTMXTiledMapExtension

البته به تمام این Extention ها نیاز نداریم < بعدا تاپیک رو ویرایش کنم و توضیحات رو اضاف میکنم

 در حال ویرایش  . . .

پاسخ به سوال 
Criss  10 سال پیش
+11 0

ساخت یک پروژه

کافیه یک پروژه اندروید بسازیم < AndEngine رو به عنوان کتابخانه بهش معرفی کنیم < و  extends BaseGameActivity کنیم اکلیپس به ما هشدار میده که متدهای مورد نیاز رو استفاده نکردیم پس  Add unplemented metohds رو میزنیم

آموزش تصویری

کلمه عبور : uncox.com

public class MainActivity extends BaseGameActivity {

@Override
public EngineOptions onCreateEngineOptions() {
return null;
}

@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {

}

@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {

}

@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {

}
}

 

بجای BaseGameActivity  میتونستیم از SimpleBaseGameActivity هم استفاده کنیم که در نهایت کدهامون به شکل زیر میشد ، البته مورد های دیگه هم برای extends شدن هست که نمیدونم چنتا هستن ، دقیقا چی هستن و یا کجاها استفاده میشن !

 public class MainActivity extends SimpleBaseGameActivity {

@Override
public EngineOptions onCreateEngineOptions() {
return null;
}

@Override
protected void onCreateResources() {

}

@Override
protected Scene onCreateScene() {
return null;
}
}

هنوز تفاوت BaseGameActivity  و  SimpleBaseGameActivity رو نمیدونم ولی معلومه یکیش کاملتره و اونیکی ساده تر یکی دیگه از تفاوت های مهمشون هم در متد ها هست که یکی void هست و اون یکی خروجی داره

پاسخ به سوال 
Criss  10 سال پیش
+14 0

استفاده از AndEngineExamples

 توی پست اول این رو به عنوان نصب APK از مثال ها معرفی کردم و اگر برنامه رو دانلود و دیده باشید ، متوجه میشید چیزی که قراره الان باهاش کار کنیم همون پروژه هست < در نهایت Sample ها رو بیرون میکشیم < و خروجی رو تست میکنم < بعدا میتونیم با بررسی کردن سورس ها < AndEngine رو خیلی ساده تر یاد بگیریم

آموزش تصویری

کلمه عبور : uncox.com

 

0 0
درود دوست من. یه سوال. تا چه حد این کتابخونه انعطاف داره؟؟ برای مثال میشه ازش در لیست ویوو یا ایمیج ویوو یا موارد مشابه استفاده کرد؟؟ (10 سال پیش)
+2 0
@ Possible : همونطور که گفتم هیچ تجربه ی قبلی در این زمینه ندارم و هرچیزی رو که دارم یاد میگیرم اینجا به اشتراک میزارم < احساس میکنم شما موضوع رو به درستی درک نکردید ویا من منظورتون رو درست متوجه نمیشم ، ولی چیزی که فعلا مشخصه این هست که AndEngine اکتیویتی خاص خودش رو داره < بنابر این شما میتونید از توی لیست ویو و یا ImageView با استفاده از intent به این اکتیویتی منتقل بشید و بازی رو نمایش بدید (10 سال پیش)
+1 0
ممنون دوست من. منظور من این بود که یه انیمیشن خاص رو در یه اپلیکیشن معمولی ( نه بازی ) پیاده کنیم. فرض کنید همین قوانین فیزیک رو برای یک دکمه تعریف کنیم. آیا امکان همچین جیزی هست؟؟ (10 سال پیش)
+2 0
فک میکنم ممکن باشه ، البته هنوز اطلاع دقیقی ندارم ، ولی چیزی که تا الان متوجه شدم کد های مربوط به قوانین فیزیک و غیره فقط در اکتیویتی ها خاص خودشون اجرا میشند < پس شما باید اونهارو در View ها خاص خودتون نمایش بدید (10 سال پیش)
پاسخ به سوال 
Criss  10 سال پیش
+10 0

  • ساخت یک پروژه ساده در SimpleBaseGameActivity : (هر پروژه ایی به Camera , Sence نیاز داره)
  • رنگ دادن به BackGround
  • اضافه کردن Line
  • Camera = که اندازه صفحه رو نمایش میدیم < دراقع اگر ما اندازه رو 1080*1980 قرار بدیم یک بازی FullHD داریم (فکر میکنم درست گفته باشم !)
  • Sence = همون سن نمایش ، صحنه  اصلی بازی که همه چیز رو نمایش میده <
  • در متد onCreateScene ما Scence رو return میکنیم
 
public class T1_BackGround extends SimpleBaseGameActivity {

private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;


@Override
public EngineOptions onCreateEngineOptions() {
final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
}


@Override
protected void onCreateResources() {

}


@Override
protected Scene onCreateScene() {
Scene scene = new Scene();
// ترسیم یک خط از نقظه 0 و 0 تا وسط صفحه
Line line = new Line(0, 0, (CAMERA_WIDTH / 2), (CAMERA_HEIGHT / 2), this.getVertexBufferObjectManager());
scene.setBackground(new Background(1f, 0f, 0f)); // مقادیر 0 تا 1
scene.attachChild(line);
return scene;
}

}

در رابطه با this.getVertexBufferObjectManager() هنوز چیزی نمیدونم ولی لازمه فعلا به چشم Context بهش نگاه کنید :D ، بعدا سرچ میکنم راجبش اینجا توضیح میدم

 

پاسخ به سوال 
Criss  10 سال پیش
+11 0

ساخت یک پروژه ساده در BaseGameActivity

 

  • در onCreateResources مانند زیر  onCreateResourcesFinished میکنیم ، به منظور اتمام لود کردن منابع از قبیل فایل های صوتی و تصویری
  • در onCreateScene بر خلاف کد های بالا خروجی نداریم پس صحنه رو روی mEngine ست میکنیم
  • mEngine نیازی به تعریف از قبل نداره در در متد onCreateScene قابل شناسایی هست ء کافیه بنویسیدش و صحنه رو بهش ست کنید
  • همونطور که میبینید ما یک بک گراند صورتی با یک خط رو در صحنه ترسیم کردیم و نمایش دادیم
public class T2_BackGround extends BaseGameActivity {

Camera camera;
Scene mainScene;


@Override
public EngineOptions onCreateEngineOptions() {
camera = new Camera(0, 0, 800, 480);
EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), camera);
return engineOption;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scence = new Scene();
scence.setBackground(new Background(Color.PINK));
Line line = new Line(0, 0, 250, 250, this.getVertexBufferObjectManager());
scence.attachChild(line);
mEngine.setScene(scence);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {

}

 

پاسخ به سوال 
Criss  10 سال پیش
+11 0

آشنایی با مفاهیم بنیادی و پایه

ITextureRegion  TiledTextureRegion 
ITexture BitmapTextureAtlas
Sprite AnimatedSprite

برای نمایش تصاویر بر روی Scene باید چهار مرحله مرحله انجام بشه :

1- انتخاب تصویر از Asset و تعیین Region

2- اضافه کردن اون تصویر به BitmapTextureAtlas و لود کردن روی حافظه

3-ساخت یک Sprite از روی Region و نمایش دادن روی Scene

فرض کنید در AndEngine با دو نوع تصویر ثابت و متحرک سرو کار داریم که در زیر میبینید

برای نمایش دادن تصویر اول ابتدا باید اون رو توی یک ITextureRegion از Asset به کمک BitmapTextureAtlas لود کنیم و بعدا اون رو به یک Sprite وصل کنیم و حالا میتونید Sprite را روی Scene نمایش بدیم در نهایت یک تصویر ثابت داریم (پس برای ساخت یک تصویر ثابت از ITextureRegion و Sprite استفاده میکنیم این وسط BitmapTextureAtlas  تنها به مصرف بهینه حافظه کمک میکنه)

برای نمایش دادن تصویر دوم به یک TiledTextureRegion نیاز داریم که از Asset به کمک BitmapTextureAtlas اون رو لود کنیم و بعدا اون رو به یک AnimateSprite وصل کنیم و متدهای لازم برای تنظیمات و نحوه نمایش متحرک بودن این تصویر روی AnimatedSprite ست کنیم ،  حالا میتونید AnimateSprite را روی Scene نمایش بدیم و یک تصویر متحرک داشته باشیم (پس برای ساخت یک تصویر متحرک از TiledTextureRegion و AnimateSprite استفاده میکنیم این وسط BitmapTextureAtlas  تنها به مصرف بهینه حافظه کمک میکنه)

 

با توضیحاتی که دادم ممکنه هنوز برای شما مطلب گنگ باشه (مهم نیست که چیزی تا به اینجا متوجه نشدید ، فقط نیاز بود پیش زمینه ایی در ذهن شما شکل بگیره ، حداقل میدونید نمایش تصویر 4 مرحله نیاز داره همچنین نمایش تصویر های متحرک و ثابت شیوه خودش رو داره) تمام مفاهیمی که بالا نام بردن رو توضیح دادم و فقط مونده ITexture .

ITexture یکی از ساده ترین روش هایی هست که به کمک اون تصویری رو از روی Asset میتونیم Load کنیم ، توی این روش که کاملا ساده هست ، اثری از BitmapTextureAtlas  نیست در واقع هر دوی ITexture  و BitmapTextureAtlas  به ما کمک میکنند که تصویری رو از روی Asset لود کنیم ، اما استفاده از ITexture اصلا بهینه نیست و در ادامه و  آینده اصلا از اون استفاده نمیکنم و بجای ITextur  همیشه از BitmapTextureAtlas استفاده میکنیم چون به ما کمک میکنه مصرف حافظه خیلی بهینه تر باشه دلیل اینکه راجبش اینجا توضیح میدیم این هست که حداقل اون رو بشناسید و با سورس هایی که در کلاس SpriteExample وجود داره گیج نشید که اونجا فقط یک مثال ساده زده شده

اما چرا ITexture بهینه نیست و از  BitmapTextureAtlas استفاده میکنیم ؟ خودتون فکرش رو کنید توی یک بازی قرار بشه 10 تصویر داشته باشید چقدر حافظه مصرف میشه ؟ کاری که ITexture انجام میده ، این هست که تمامی تصاویر رو بصورت جداگانه روی حافظه لود میکنه ، اما BitmapTextureAtlas اینطوری عمل نمیکنه و تمامی تصاویر رو تحت یک تصویر قرار میده و فقط یک تصویر رو روی حافظه Load میکنه


هنوز برای کد زدن و توضیح دادن سورس کد ها نیاز به پیش زمینه های بیشتری دارید که در پست های بعدی توضیح میدم (این ابتدایی ترین موضوع در AndEngine هست پس چرا اینهمه پیش زمینه و توضیحات اضافه و بلند ؟ بله ساده هست ولی تا جایی که توانایی داشته باشم سعی میکنم جزئیات ساده و کامل بیان کنم و پس به اشتباه فکر نکنید که توضیحات به این بلندی حتما مطلب سختی رو در خودش داره ! )

 

پاسخ به سوال 
Criss  10 سال پیش
+11 0

توضیحات تکمیلی از BaseGameActivity و SimpleBaseGameActivity

در پست های قبلی با BaseGameActivity و SimpleBaseGameActivity  آشنا شدید از این به بعد فقط از BaseGameActivity استفاده میکنیم

توی این پست سعی میکنم جنبه های بیشتری رو از این دو که تجربه کردم رو توضیح بدم (این پست صرفا انتقال تجربیات هست و توضیحات تکمیلی)

هر Activity که میسازیم و به دلخواه هرکدوم رو که از BaseGameActivity و SimpleBaseGameActivity مشتق میکنیم همیشه با متد های اصلی سر و کار داریم

onCreateEngineOptions
onCreateResources
onCreateScene

در SimpleBaseGameActivity میبینم که جنس یا همون نوع متد ها مشخص شده بنابراین نیاز به این داره که در نهایت  متد Return داشته باشه

 public Scene onCreateScene() { 

در تمامی Activity ها که از جنس SimpleBaseGameActivity هستند متد onCreateScene همیشه  return میشوند همچنین متد onCreateResources که Void هست فقط منابع در اون Load میشوند و هیچ چیز خاص دیگه ایی نداره

در BaseGameActivity متد ها Void هستند اما تمامی آنها CallBack هایی دارند (همون طور که میدونید CallBack ها شباهتی مانند لیستنر ها و AsynTask ها دارند و میتونند نتیجه پردازش شده رو ارسال کنند ونتیجه رو به جایی که صدا زده شده تحویل دهند)

  public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {

توی پست های قبلی شما فقط نمونه ی ساده ایی از BaseGameActivity رو دیدید ، بنابر این در اینجا BaseGameActivity رو کامل تر توضیح میدم ، در BaseGameActivity شما باید تمام این CallBackهارو فعال کنید و خروجی های اونهارو صدا بزنید که AndEngine متوجه پایان کار متد بشه

 public class BaseGameSample extends BaseGameActivity {

@Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
return null;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}

تفاوت دیگری که در BaseGameAcivity وجود داره این هست که یک متد اضافی به اسم onPopulateScene داره که فکر میکنم بعد از اتمام کار در متد onCreateScene این متد شروع به کار میکنه (در آینده که بیشتر یاد بگیرم اطلاعاتی در مورد onPopulateScene قرار میدم)

نکته دیگه ایی که وجود داره این هست که در پست قبلی که از BaseGameActivtiy داشتیم خروجی متد onCreateScene بصورت زیر تعریف شده بود

 mEngine.setScene(scene);

اینکه mEngine در AndEngine دقیقا این وسط بدون اینکه از قبل تعریف شده باشه چیکار میکنه رو نمیدونم ولی مشخصه یکی از متغیرهایی هست که همیشه میتونید در AndEngine ازش استفاده کنید بدون اینکه اون رو تعریف کنید ، چیزی که من تجربه کردم در مورد mEngine این هست که نیاز نیست نگرانش باشید اون هم یکی از روش های ساده برای ارسال خروجی و نمایش روی Scene هست دقیقا چیزی شبیه به ITexture هست که قبلا راجبش گفته بودم و هیچوقت دوباره ازش استفاده نمیکنیم ، چیزی که من تجربه کردم این بود :

یک اکتیوتی داشتم که با کلیک کردن روی صفحه کاراکتر مورد نظر (Sprite) باید به محلی که کلیک کرده بودم حرکت میکرد ، با اینکه همه چیز درست بود اما چون Scene رو با mEngine.setScene(scene); ست کرده بودم به کلیک هایی که روی صفحه میشد و پاسخ ها باید CallBack میشدند جواب نمیداد و خروجی برای من صحیح نمایش داده نمی شد بنابر این سورس رو به شکل زیر تغییر دادم و نتیجه حاصل شد

  pOnCreateSceneCallback.onCreateSceneFinished(scene);
//mEngine.setScene(scene);

 

چند نکته ی دیگه هم وجود داره که مانند متد زیر که میشه به BaseGameActivity و SimpleBaseGameActivity اضافه کرد مشخص میکنه که در هر ثانیه چند فریم از بازی نمایش داده بشه (از اونجایی که تجربه ایی ندارم نمیتونم بیشتر و کاربردی تر در این مورد بهتون توضیح بدم)

     @Override
public Engine onCreateEngine(EngineOptions pEngineOptions) {
return new LimitedFPSEngine(pEngineOptions, 60);
}

و متد زیر در onCreateScene که این مورد ور کاملا نمیدونم کارش چی هست !

    @Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
this.mEngine.registerUpdateHandler(new FPSLogger());
Scene scene = new Scene();
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}

 

0 0
در مورد AndEngine سوال کردم : و آقای رمضان زاده به این شکل جواب داد : mEngine همون موتور اصلی بازیه که اول ساخته میشه و ما تنظیمات خاصی رو روش اعمال می کنیم (مثلاً تنظیمات توی onCreateEngine) و خب چون بازی فقط یک موتور بازی می تونه داشته باشه (که کل دنیا و فیزیک و اشیا و زمان بندی و فریم بندی و غیره رو کنترل کنه) بهتره که بدین شکل همه جا قابل دسترسی باشه. (عاخه چرا الکی به یه چیزی گیر میدم که باعث میشه فکر و دیدم بسته بشه ، خب این کاملا مشخص بود ما بیشتر از یک انجین که نداریم :| ) (10 سال پیش)
پاسخ به سوال 
Criss  10 سال پیش
+11 0

محور مختصات در AndEngine

محور مختصات در AndEngine بصورت زیر هست ، حتی اون Camera و EngineOption هم که مختصات 800*480  رو داره از این مختصات تبعیت میکنن ، برای اینکه در پست بعدی قرار هست BitmapTextureAtlas رو توضیح بدیم شما باید این محور مختصات رو بدونید

کافیه این قائده رو بدونید < همه چیز از نقطه 0 و 0 با توجه به مقداری که برای عرض و طول دربافت میکنه رسم میشه

این عرض و ارتفاع میتونه خود Camera و یا Scene و یا یک کاراکتر بازی 32*32 و هرچیزی باشه

پس فراموش نکنید ترسیم هرچیزی از نقطه 0 و 0 شروع میشه و با توجه به مقدار عرض و مقدار طول ترسیم میشه

حالا اگر مقدار عرض و طول منفی باشه چی میشه ؟ خب تصویر در جهت عکس رسم میشه یعنی اگر در نقطه 0 و 0 رسمش کنید چیزی ازش نمیبینید < اما اگر در مرکز صفحه قرار بدید کمی متوجه موضوع میشید

 

 

پاسخ به سوال 
Criss  10 سال پیش
+12 0

که بود وچه کرد ؟ :دی  BitmapTextureAtlas

پیشنهاد میکنم برای فهم بهتر این موضوع به آموزش های آقای سیف الله رمضان زاده مراجعه کنید (اگر منبعی که معرفی کردم رو مطالعه نکنید BitmapTextureAtlas رو متوجه  نمیشید و نمیتونید ادامه آموزش رو درک کنید !)

 در ادامه یک مثال از نمونه های کاربرد BitmapTextureAtlas در استفاده از Region و Load کردن اونهارو مثال میزنم

ابتدا یک تصویر ثابت رو در در BitmapTextureAtlas اضافه میکنیم و BitmapTextureAtlas رو Load میکنیم، بنابر این یک Activity به شکل زیر میسازیم

 public class LoadSprite extends BaseGameActivity {

ITextureRegion faceRegion;
BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, 800, 480);
EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), camera);
return engineOption;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");

atlas = new BitmapTextureAtlas(getTextureManager(), 64, 64);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(Color.CYAN));
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}

 

خب تمام موارد موجود در این Activity رو بلد هستید من فقط در مورد متد onCreateResources توضیح میدم :

        BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");

atlas = new BitmapTextureAtlas(getTextureManager(), 64, 64);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();

با خط اول مسیر منابع رو مشخص میکنیم که در یک فولدر به نام res در فولدر asset وجود داره

در خط بعدی BitmapTextureAtlas رو میسازیم و اندازه اون رو 64*64 قرار میدیم (امیدوارم در مورد BitmapTextureAtlas مطالعه کرده باشید ، پس حتما میدونید که ما میتونستیم این رو 32*32 تعریف کنیم چون تصویری که ما داریم همین اندازه رو داره و هیچ تصویر اضافه ایی هم نمیخوایم به BitmapTextureAtlas اضافه کنیم ، ولی من دوست دارم 64 رو انتخاب کنم !! ) ، خب این BitmapTextureAtlas که ساخته میشه در واقع یک تصویر خالی هست بصورت Transparent (کاملا شفاف) که در خطوط بعدی تصاویر دیگری بهش اضافه میشه و این عکس Transparent کم کم سکل به خودش میگیره و هر چقدر که اندازه داشته باشه میتونیم بهش تصویر اضافه کنیم در اینجا 64*64 پیکسل فضا داریم بنابر این میتونیم حداکثر 4 تصویر مختلف با اندازه 32*32 رو روی اون قرار بدیم در این مثال فقط یک تصویر 32*32 پیکسل داریم . که با توجه به خط زیر به BitmapTextureAtlas اضافه میشه

 faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);

خب میبینید که بعد از اسم تصویری که انتخاب کردیم یک مختصات 0 و 0 هم وجود داره که این مختصات مربوط میشه به BitmapTextureAtlas که در کل 64*64 هست و ما در نقطه 0 و 0 اون یک تصویر به اندازه 32*32  قرار دادیم

در مسیر یادگیری AndEngine شدیدا نیاز دارید که پارامترهای ورودی متدهارو چک کنید و با توجه به اونها مقدار دهی کنید

در ادامه فرض میکنیم که 2 تصویر دیگر با اندازه های 32*32 و 32*64 هم داریم ، در این روشی که یاد گرفتید باید دقت کنید که تصاویر روی یک دیگر قرار نگیرند (بعد از یاد گیری این مورد میتونید خودتون تست کنید که اگر مختصات تصاور روی هم قرار بگیرند در زمان Load کردن یک تصویر روی Scene چه اتفاقی میوفته !)

خب فرض میکنیم در کل 3 تصویر داریم با با اندازه های 32*32 و 32*32 و 64*32 که یکی از تصاویر روی BitmapTextureAtlas در مختصات 0 و 0 قرار گرفته

تصویر دوم که 32*32 هست رو باید در چه مختصاتی رسم کنیم که به مشکل بر نخوریم ؟ باید برابر با تصویر زیر مختصات رو از روی BitmapTextureAtlas  انتخاب کنیم

خب بزارید کمی شما رو به چالش بکشم همونطور که میبینید با استفاده از یک BitmapTextureAtlas  با اندازه 64*64 میتونیم 4 تصویر با اندازه 32*32 رو Load کنیم ، حالا اگر بخوایم 8 تصویر یعنی دوبرابر رو لود کنیم باید اندازه ها BitmapTextureAtlas  رو چقدر انتخاب کنیم ؟ اگر به نتیجه 128*128 رسیدید ؟ یعنی 64 رو دو برابر کردید باید بگم که اشتباه کردید در اندازه ایی برابر با 128*128  فضا برای 16 تصویر با اندازه 32*32 وجود داره برای لود کردن 8 تصویر باید BitmapTextureAtlas  رو برابر با 64*32 انتخاب کنیم ، یعنی فقط در یکی از جهات X , Y باید محور BitmapTextureAtlas  رو گسترش بدیم ، کمی در مورد فکر کنید به درک بهتری میرسید که در ادامه شدیدا به این درک نیاز دارید

 


در ادامه باید بگم که علاوه بر روش بالا که برای BitmapTextureAtlas مختصات وارد میکنیم و همیشه باید برای تصاویر بعدی که Load میکنیم هم مختصات دقیق و صحیحی وارد کنید که این ممکنه باعث اشتباه بشه روشی دیگر هم بجای استفاده از BitmapTextureAtlas وجود داره که توی آموزش های آقای سیف الله رمضان زاده بهش اشاره شده ، و اون هم استفاده از BuildableBitmapTextureAtlas بجای BitmapTextureAtlas هست در آینده در مورد صحبت میکنیم برای لود کردن تصاویر متحرک واقعا کار مارو راحت میکنه بعدا خودتون متوجه میشید چرا گفتم در تصاویر متحرک به کارمون میاد ، برای اینکه با BuildableBitmapTextureAtlas بیشتر آشنا بشید ، میتونید علاوه بر آموزش هایی آقای رمضان زاده باتوجه به آموزشی که بالاتر "استفاده از AndEngineExamples" دادم برید و کلاس AnimatedSpritesExampl.java رو کپی کنید و سورس قسمت مربوط به onCreateResure رو ببینید که از BuildableBitmapTextureAtlas در اونجا استفاده شده

 

علاه بر موضوع بالا نکته ایی دیگه هم وجود داره که مربوط به RGB 8888 , RGB 4444 میشه (کیفیت عکس هارو مشخص میکنه و همچنین میزان حافظه) این موضوع رو در کتاب COOKBOOK اموزش AndEngine دیدم ولی حالا چطور میهشه ازش استفاده کرد رو نمیدونم (منابع آموزشی رو در آینده معرفی میکنم)

 BitmapTextureFormat.RGBA_8888.

در حال ویرایش . . .

پاسخ به سوال 
Criss  10 سال پیش
+10 0

ادامه آموزش قبل
BitmapTextureAtlas تصاویر متحرک و

خب توی آموزش قبلی به خوبی با BitmapTextureAtlas آشنا شدید و همچنین یاد گرفتید که چطور از ITextureRegion  استفاده کنید و یک تصویر ثابت 32*32 رو با کمک ITextureRegion  و BitmapTextureAtlas رو Load کنید

در ادامه یاد میگیریم که چطور یک تصویر متحرک رو با کمک TiledTextureRegion روی BitmapTextureAtlas لود کنیم

قبل از هرچیز لازم هست دقت کنیم که در اینجا ما دو تصویر 32*32 و 132*70 داریم بنابر این باید اندازه BitmapTextureAtlas  حداقل 164*70 باشه (درواقع همیشه نیاز دارید که دقت کنید که تصاویر شما چه سایزی رو دارند و چند در چند هستند چون در آینده که بحث فیزیک و برخورد دو شی به هم و حرکت و انتقال Sprite روی صفحه رو داریم به این مختصات احتیاج پیدا میکنید)

خط زیر رو همراه با قسمت های مختلفی که داره بخوبی میشناسید

faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);

با خط زیر مقایسه کنید و متوجه متفاوت بودن Load کردن یک تصویر ثابت و یک تصویر متحرک میشید

ذananaRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "banana_tiled.png", 32, 0, 4, 2);

خب همون طور که قبلا بهتون گفته بودم همیشه نیاز دارید که پارامترهای ورودی متد هارو چک کنید و با توجه به اونها مقدار دهی کنید 

در تصویر بالا میبینیم که باید تعداد Column ها و Row هارو وارد کنید تصویری که از banana در بالا میبینید دارای 4 ستون و 2 سطر هست

 public class LoadSprite extends BaseGameActivity {

private ITextureRegion faceRegion;
private TiledTextureRegion bananaRegion;
private BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, 800, 480);
EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), camera);
return engineOption;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");

atlas = new BitmapTextureAtlas(getTextureManager(), 164, 70);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);
bananaRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "banana_tiled.png", 32, 0, 4, 2);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}

اگر توی هر کدام از مرحله های بالا اشتباهی در اندازه BitmapTextureAtlas انجام میداد (کوچکتر از اندازه مورد نیاز) و یا تعداد سطر و ستون تصویر متحرک رو اشتباه وارد میکردید < و یا مختصات اون رو بجای 32و0 مثلا 32و32 وارد میکردید (که قسمتی از تصویر banaana از BitmapTextureAtlas بزنه بیرون) تصویر در Scene کاملا سیاه نمایش داده میشد پس حتما همیشه بعد از لود کردن منابع Activity رو تست کنید

 

پاسخ به سوال 
Criss  10 سال پیش
+11 0

استفاده از Sprite ها و نمایش در Scene

Sprite اون چیزی هست که نهایتا روی Scene به نمایش گذاشته میشه Sprite از روی ITextureRegion ساخته میشه ، به اشتباه فکر نکنید که برای هر Sprite نیاز به یک ITextureRegion داریم ؟! خیر به اینصورت نیست ! در واقع شما میتونید یک ITextureRegion داشته باشید و از روی اون چندیدن Sprite تولید کنید و روی Scene به نمایش بزارید

در مثال های قبلی 90% کار رو پیش بردید و برای نمایش دادن یک Sprite کد زیادی نمونده ، دقت کنید که هنوز صحبتی از AnimatedSprite نشده و تنها داریم ازSprite  مثال میزنیم

کل پروژه ایی که تا به اینجا اومدیم بصورت زیر هست :

 public class LoadSprite extends BaseGameActivity {

private ITextureRegion faceRegion;
private TiledTextureRegion bananaRegion;
private BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, 800, 480);
EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), camera);
return engineOption;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");

atlas = new BitmapTextureAtlas(getTextureManager(), 164, 70);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);
bananaRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "banana_tiled.png", 32, 0, 4, 2);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(Color.CYAN));

Sprite sprite1 = new Sprite(0, 0, faceRegion, getVertexBufferObjectManager());
scene.attachChild(sprite1);

pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}

از کد های بالا همه اش رو بلد هستید و میشناسید و فقط onCreateScene رو توضیح میدم

        Scene scene = new Scene();
scene.setBackground(new Background(Color.CYAN));

Sprite sprite1 = new Sprite(0, 0, faceRegion, getVertexBufferObjectManager());
scene.attachChild(sprite1);

pOnCreateSceneCallback.onCreateSceneFinished(scene);

از کد بالا هم تمام گزینه هارو میشناسید و فقط نحوه ساخت یک Sprite برای شما جدید هست که اون هم پارامترهای ورودی زیر رو داره که در کل چیز ساده هست ، در مورد getVertexBufferObjectManager هم اگر سوالی دارید قبلا هم گفتم هرجا بهش نیاز بود یه همین روش مقدارش رو بهش ست کنید ، در مورد float pX, float pY هم باید مختصاتی بدید که Sprite شما از اونجا شروع به ترسیم میکنه

 org.andengine.entity.sprite.Sprite.Sprite(float pX, float pY, ITextureRegion pTextureRegion, VertexBufferObjectManager pVertexBufferObjectManager)

یک نکته : قبلا بهتون گفته بودم که نیاز دارید حتما اندازه تصاویری که در ITextureRegion قرار میدید رو بدونید ، الان این گزینه به چه درد ما میخوره ؟ اگر اکتیویتی رو Run کنید میبیند که تصویر در نقطه 0 و 0 ترسیم شده در ظاهر شما متوجه این تفاوت نمیشید (اما اگر قرار باشه با کلیک شدن روی صفحه و یا با دستور کردن دادن یک Sprite رو ترسیم کنیم اونجا هست که بخوبی متوجه این تغییر میشید)

در واقع چیزی که میخوام بهتون بگم این هست که وقتی ما میگیم تصویر در نقطه 0 و 0 رسم بشه انتظار دارید مرکز تصویر در نقطه 0 و 0 قرار گرفته باشه ، ولی در اینجا میبینیم که گوشه بالا سمت چپ تصویر روی نقطه 0 و 0 از  Scene قرار گرفته !

همونطور که قبلا هم گفته بودم همه چیز در AndEngine از محور مختصات تبعیت میکنه بنابر این کاملا طبیعی هست که وقتی میگید در نقطه 0 و 0 ، ترسیم شکل به این صورت نمایش داده بشه

حالا برای اینکه مرکز Sprite روی نقطه 0 و 0 قرار بگیره باید چه کنم ؟ کد زیر مشکل رو حل میکنه

 Sprite sprite1 = new Sprite(0 - faceRegion.getWidth() / 2, 0 - faceRegion.getHeight() / 2, faceRegion, getVertexBufferObjectManager());

خب همونطور که در ابتدای این پست گفتم شما میتونید چندید Sprite از روی ITextureRegion بسازید و نمایش بدید

 Sprite sprite1 = new Sprite(0 - faceRegion.getWidth() / 2, 0 - faceRegion.getHeight() / 2, faceRegion, getVertexBufferObjectManager());
Sprite sprite2 = new Sprite(32, 32, faceRegion, getVertexBufferObjectManager());
Sprite sprite3 = new Sprite(64, 64, faceRegion, getVertexBufferObjectManager());
scene.attachChild(sprite1);
scene.attachChild(sprite2);
scene.attachChild(sprite3);
پاسخ به سوال 
Criss  10 سال پیش
+11 0

جنبه های مختلف و اطلاعات تکمیلی از Sprite ها

استفاده از  AnimateSprite ها بصورت ساده

 در آموزش قبلی به خوبی تونستید یک Sprite رو در Scene نمایش بدید ، توی این پست جنبه های مختلف و اطلاعات تکمیلی رو توضیح میدیم که بهتر موضوع رو درک کنید

شاید برای شما هم سوال بشه اگر تصویر موز رو بجای اینکه با TiledTextureRegion لود کنیم اون رو با ITextureRegion   لود میکردیم چه اتفاقی می افتاد ؟ (پیشنهاد میکنم ادامه آموزش رو دنبال نکنید و خودتون دست بکار بشید و سعی کن)

احتمالا با اولین اجرای Activity با یک تصویر سیاه مواجه میشید ، کمی فکر میکنید و متوجه میشید که باید اندازه Atlas رو افزایش میداد و باید از نظر عرضی برای نقطه y حداقل 70 پیکسل پایین تر مختصات رو انتخاب کنید

ممکنه جاهایی دگه ایی هم به مشکل بر بخورید پس بهتر بهش فکر کنید که در نتیجه درکتون در یادگیری AndEngine افزایش پیدا کنه

در نهایت میتونید مثل من زیاد خودتون رو درگیر محاسبات دقیق نکنید و اندازه Atlas رو 500*500 در نظر بگیرید

 public class LoadSprite extends BaseGameActivity {

private ITextureRegion faceRegion;
private TiledTextureRegion bananaRegion;
private ITextureRegion bananaRegion2;
private BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, 800, 480);
EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), camera);
return engineOption;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");

atlas = new BitmapTextureAtlas(getTextureManager(), 500, 500);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);
bananaRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "banana_tiled.png", 32, 0, 4, 2);
bananaRegion2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "banana_tiled.png", 0, 200);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}

حالا میتونید یک Sprite درست کنید و اون رو روی Scene نمایش بدید < تصویر جدیدی که نمایش داده میشه یک تصویر کامل از تمام 8 تا banana ها هست

مورد دوم که میتونید تست کنید این هست که مختصات مختلفی به این bananaRegion2  بدید میبینید که توی بعضی مختصات که روی دیگر Region ها رسمش کردید در موقع نمایش دادن روی Scene تصویر اصلی زیر تصویری قرار مییگیره که مختصات اشتباهی بهش داده شده و دیده نمیشه !

خب بهتره که banana رو با TiledTextureRegion لود کنید و اون روی به یک Sprite وصل کنید و روی Scene نمایش بدید ، میبینید که بخوبی نمایش داده میشه ، نمیدونم چی انتظار داشتید ولی شاید یادتون باشه که در بالا من گفته بودم برای نمایش تصاویر متحرک از TiledTextureRegion استفاده میکنیم و برای نمایش TiledTextureRegion از AnimateSprite استفاده میکنیم ولی میبینید که اینجا خلاف حرف من ثابت شده و شما تونستید banana رو که یک TiledTextureRegion هست بوسیله یک Sprite نمایش بدید

اگر کمی تیز باشید حتما میرید و با AnimateSprite هم تست میکینم و باز هم میبینید که خروجی همون چیزی هست که با Sprite نمایش داده میشه !

   @Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(Color.CYAN));

Sprite sprite1 = new Sprite(0 - faceRegion.getWidth() / 2, 0 - faceRegion.getHeight() / 2, faceRegion, getVertexBufferObjectManager());
Sprite sprite2 = new Sprite(32, 32, faceRegion, getVertexBufferObjectManager());
Sprite sprite3 = new Sprite(64, 64, faceRegion, getVertexBufferObjectManager());
Sprite sprite4 = new Sprite(0, 150, bananaRegion2, getVertexBufferObjectManager());
AnimatedSprite bananaAnimateSprite = new AnimatedSprite(250, 250, bananaRegion, getVertexBufferObjectManager());
Sprite bananaSprite = new Sprite(300, 300, bananaRegion, getVertexBufferObjectManager());
scene.attachChild(sprite1);
scene.attachChild(sprite2);
scene.attachChild(sprite3);
scene.attachChild(sprite4);
scene.attachChild(bananaSprite);
scene.attachChild(bananaAnimateSprite);

pOnCreateSceneCallback.onCreateSceneFinished(scene);
}

خب بله باید هم خروجی به این صورت باشه به این دلیل که شما به AnimateSprite تنظیمات مربوط به نحوه نماش متحرک بودن تصویر  رو ست نکردید عین  جمله ایی که گفتم رو اینجا براتون دوباره قرار میدم

برای نمایش دادن تصویر دوم به یک TiledTextureRegion نیاز داریم که از Asset به کمک BitmapTextureAtlas اون رو لود کنیم و بعدا اون رو به یک AnimateSprite وصل کنیم و متدهای لازم برای تنظیمات و نحوه نمایش متحرک بودن این تصویر روی AnimatedSprite ست کنیم ،  حالا میتونید AnimateSprite را روی Scene نمایش بدیم و یک تصویر متحرک داشته باشیم (پس برای ساخت یک تصویر متحرک از TiledTextureRegion و AnimateSprite استفاده میکنیم این وسط BitmapTextureAtlas  تنها به مصرف بهینه حافظه کمک میکنه)


 

شاید براتون جالب باشه که چرا تصویر banana که TiledTextureRegionبود با اینکه ما بهش طول و عرض خاصی ست نکردیم و چطور داره اولین تصویر از مجموع 8 تصویر دیگه رو نمایش میده ؟ ول اگر دقت کنید ما  یکبار تعداد ستون ها و تعداد سطر ها رو بهش ست کرده بودیم بنابر این حداقل مقدار سطر و ستون اول رو در خودش نگه میداره و نمایش میده

پاسخ به سوال 
Criss  10 سال پیش
+10 0

پایان AnimatedSprite و نمایش یک تصویر متحرک

 خب حالا چطور میتونیم یک تصویر متحرک روی Scene اضاف کنیم

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

 bananaAnimateSprite.animate(100);

 

مقدار 100 در بالا تعیین میکنه که از تصویر از 8 تصویر بالا 100 میلی ثانیه نمایش داده بشه بنابر این اگر بجای 100 عدد 1000 رو وارد کنید هر تصویر 1 ثانیه طول میکشه و در کل که 8 تصویر داریم 8 ثانیه به طول می انجامد اگر من بودم روی 125 قرار میدادم تا کلا 1 ثانیه اجرای این انیمیشن متحرک زمان صرف کنه (ازاین به بعد بجای استفاده از عبارت تصویر ، میگیم فریم)

 @Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(Color.CYAN));

Sprite sprite1 = new Sprite(0 - faceRegion.getWidth() / 2, 0 - faceRegion.getHeight() / 2, faceRegion, getVertexBufferObjectManager());
Sprite sprite2 = new Sprite(32, 32, faceRegion, getVertexBufferObjectManager());
Sprite sprite3 = new Sprite(64, 64, faceRegion, getVertexBufferObjectManager());
Sprite sprite4 = new Sprite(0, 150, bananaRegion2, getVertexBufferObjectManager());
AnimatedSprite bananaAnimateSprite = new AnimatedSprite(250, 250, bananaRegion, getVertexBufferObjectManager());
Sprite bananaSprite = new Sprite(300, 300, bananaRegion, getVertexBufferObjectManager());
scene.attachChild(sprite1);
scene.attachChild(sprite2);
scene.attachChild(sprite3);
scene.attachChild(sprite4);
scene.attachChild(bananaSprite);
scene.attachChild(bananaAnimateSprite);
bananaAnimateSprite.animate(125);

pOnCreateSceneCallback.onCreateSceneFinished(scene);
}

( برای خود من سواله اگر bananaAnimateSprite رو به Scene اضاف کنیم مقدار animate رو بعدا بهش بدیم مانند کد بالا و یا قبل از اینکه به Scene اضاف کنیم مقدار animate بهش چه تفاوتی داره ؟ احتمالا اینجا چون داریم از CallBack استفاده میکنیم هیچ تفاوتی نداره! )

خب برای اینکه با نحوه AnimateSprite ها بهتر آشنا بشید پیشنهاد میکنم طبق آموزشی که بالاتر گذاشتم "استفاده از AndEngineExamples" کلاس AnimatedSpritesExample.java رو پیدا کنید < کپی کنید و اجرا کنید اونجا هست که متونید یاد بگیرید این AnimateSprite ها چقدر میتونه انعطاف پذیر باشه

خب اینجا یک نمونه از animate رو توضیح دادم نمونه دوم رو هم توضیح میدم نمونه ی دیگه ایی تست نکردم و ندیده ام البته که نمونه های مختلف دیگه ای هم وجود داره < کافیه جلوی متد animate یک CTRL+SPACE بزنید <

خب متد های ورودی animate قبلی به شرح زیر بود فقط یک مقدار  FrameDuration هست !

 org.andengine.entity.sprite.AnimatedSprite.animate(long pFrameDurationEach)

اما یک animate دیگه هم داریم با مقادیر های زیر

 org.andengine.entity.sprite.AnimatedSprite.animate(long[] pFrameDurations, int pFirstTileIndex, int pLastTileIndex, boolean pLoop)

که به شکل زیر مقادیر بهش ست میشه

// bananaAnimateSprite.animate(125);
bananaAnimateSprite.animate(new long[]{ 100, 100, 100, 100, 100, 100, 100, 100 }, 0, 7, true);

تصویر ما 8 قسمت داشت که ما باید یک آرایه  8 عنصری رو معرفی کنیم که مشخص میکنه هر فریم در چند میلی ثانیه نمایش داده بشه < قسمت دوم بهش میگیم که از index 0 تا index 7 که تعدادشون میشه 8 تا رو باید animate کنه index0 تا index7 همون سطر و ستون های هستند که توی آموزش قبلی دیدید که وقتی از Sprite استفاده میکنید < بصورت پیشفرض index0 رو نمایش میده و در آخر مقدار true میزاریم مبنی بر اینکه آیا این انیمیشن تکرار بشه یا خیر !

خب اونجایی که گفتم SpriteAnimate ها میتونه منعطف باشه این مثال هست : که تنها index1 , index2 رو نمایش میده

        //bananaAnimateSprite.animate(125);
//bananaAnimateSprite.animate(new long[]{ 100, 100, 100, 100, 100, 100, 100, 100 }, 0, 7, true);
bananaAnimateSprite.animate(new long[]{ 100, 100 }, 1, 2, true);

 

در حال ویرایش . . .

 

پاسخ به سوال 
Criss  10 سال پیش
+11 0

EntityModifier

خب موضوع بعدی ModiFire ها هستند که این موضوع هم واقعا ساده هست

پیشنهاد میکنم با توجه به آموزش های آقای سیف الله رمضان زاده که به ترتیب بهتون معرفی میکنم مطالعه ایی رو انجام بدید که درک کافی در ذهنتون شکل بگیره

MoveModifier
LoopEntityModifier

همچنین با توجه به آموزش "استفاده از AndEngineExamples" که بالاتر تصویری آموزش دادیم کلاس های زیر رو استفاده کنید میتونید با دیدن کد ها همه چیز رو یاد بگیرید

EntityModifierExample.java

EntityModifierIrregularExample.java

در ادامه یافته های خودم رو براتون مثال میزنم : یک پروژه بصورت زیر میسازیم < دیگه همه چیزش رو بلدید

 

 public class Modifire extends BaseGameActivity {

private static final int WIDTH = 800;
private static final int HEIGHT = 480;

private ITextureRegion faceRegion;
private TiledTextureRegion bananaRegion;
private BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, WIDTH, HEIGHT);
EngineOptions engineOption = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
return engineOption;
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");
atlas = new BitmapTextureAtlas(getTextureManager(), 256, 256);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "face_box.png", 0, 0);
bananaRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "banana_tiled.png", 32, 0, 4, 2);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.5f, 0.5f, 0.5f));
Sprite face = new Sprite((WIDTH / 2) - 100, (HEIGHT / 2), faceRegion, getVertexBufferObjectManager());
AnimatedSprite happyBanana = new AnimatedSprite((WIDTH / 2) + 100, (HEIGHT / 2), bananaRegion, getVertexBufferObjectManager());
happyBanana.animate(125);

scene.attachChild(face);
scene.attachChild(happyBanana);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}

 خب همه چیز آماده هست که یک Modifier رو تست کنیم برای اعمال Modifier ها باید از متد _ برای Sprite ها استفاده کنیم

 sprite.registerEntityModifier

برای اویل مثال از Modifier مربوط به Scale (سایز و اندازه) استفاده میکنم

new ScaleModifier(pDuration, pFromScale, pToScale)
 andengine.entity.modifier.ScaleModifier.ScaleModifier(float pDuration, float pFromScale, float pToScale)

که مقدار اول زمان هست و مقدار 2 رو وارد میکنیم یعنی این Modifier باید در مدت زمان 2 ثانیه انجام بشه مقدار دوم این و سوم هم مشخص هست از چه اندازه ایی به چه اندازه ایی Scale انجام بشه

 ScaleModifier scale = new ScaleModifier(2, 1f, 2f);
face.registerEntityModifier(scale);

برای اندازه ها اگر 1 رو وارد کنید برابر اندازه طبیعی ،  مقدار 2 و دوبرابر اندازه عادی و هر چی بیشتر به همون برابر تصویر تغییر میکنه ، اندازه 0.5 هم ندازه رو نصف میکنه

برای Modifier ها میشه Listener تعریف کرد که وقتی کار به اتمام رسید به شما خبر بده ما بعد از اینکه اندازه تصویر 2 برابر شد لون رو به حالت اولش بر میگردونیم

 ScaleModifier scale = new ScaleModifier(2, 1, 2);
face.registerEntityModifier(scale);
scale.addModifierListener(new IModifierListener<IEntity>() {

@Override
public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {}


@Override
public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
face.registerEntityModifier(new ScaleModifier(2, 2, 1));
}
});

Modifier رو هم به شکل زیر میتونید استفاده کنید (میدونید دوتا Modifier رو باهم ست کنید)

 AlphaModifier alpha = new AlphaModifier(2, 1, 0.2f);


ScaleModifier scale = new ScaleModifier(2, 1, 2);
AlphaModifier alpha = new AlphaModifier(2, 1, 0.2f);
face.registerEntityModifier(scale);
face.registerEntityModifier(alpha);

Modifier ها در صورتی که با هم منافاتی نداشته باشند میتونید چندتارو با هم ست کنید اما توی مثال زیر میبیند که Modifier  دوم اعمال نمیشه

        ScaleModifier scale = new ScaleModifier(2, 1, 2);
ScaleModifier scale2 = new ScaleModifier(2, 2, 1);
face.registerEntityModifier(scale);
face.registerEntityModifier(scale2);

چند نمونه از Modifier ها رو که تست کردم رو اینجا میزارم خودتون خروجی بگیرید و ببینید

                               //new JumpModifier(2, 50, 50, 300, 300, 2) // این رو خودم هرچی تست متوجه نشدم !
new ColorModifier(2, Color.RED, Color.BLUE)
new ScaleModifier(1, 2, 1)
new ScaleModifier(1, 1, 2)
new AlphaModifier(1, 1, 0.4f)

در حال ویرایش . . .

پاسخ به سوال 
Criss  10 سال پیش
+11 0

LoopEntityModifier و SequenceEntityModifier و ParallelEntityModifier

همونطور که در LoopEntityModifier توضیح داده شد :

 LoopEntityModifier : این Entity Modifier به ما اجازه می دهد تا یک Modifier را به صورت نامحدود یا N  بار تکرار کنیم.

  • ParallelEntityModifier : این Entity Modifier به ما اجازه می دهد تا چندین Modifier را همزمان استفاده کنیم و انیمیشن های پیچیده ای ایجاد کنیم.
  • SequenceEntityModifier : این Entity Modifier به ما اجازه می دهد تا زنجیره از Modifier ها را به وجود بیاوریم و چندین Modifier را پشت سر هم بر روی یک Entity اعمال کنیم ، استفاده از DelayModifier هنگام استفاده از SequenceEntityModifier می تواند مفید و جذاب واقع شود.

 تا اینجا یاد گرفتید که چطور بصورت خیلی ساده با استفاده از registerEntityModifier یک Modifier شاده رو استفاده کنید ، در اینجا با استفاده از  SequenceEntityModifier میتونید چندین Modifier ساده رو با هم به ترتیب استفاده کنید

با استفاده از ParallelEntityModifier میتونید از چندین SequenceEntityModifier که استفاده کنید (که SequenceEntityModifier  خودش چندین Modifier رو داره )

LoopEntityModifier هم به شما کمک میکنه که بتونید بصورت پیاپی Modifier هارو تکرار کنید

یک مثال از SequenceEntityModifier :

        //> SequenceEntityModifier
ColorModifier colorModifier = new ColorModifier(2, Color.RED, Color.BLUE);
face.registerEntityModifier(
new SequenceEntityModifier(
//new ColorModifier(2, Color.RED, Color.BLUE),
colorModifier,
new DelayModifier(0.5f),
new ScaleModifier(1, 1, 2),
new DelayModifier(0.5f),
new ScaleModifier(1, 2, 1),
new DelayModifier(0.5f),
new AlphaModifier(1, 1, 0.4f),
new DelayModifier(0.5f),
new AlphaModifier(1, 0.4f, 1)));

یک مثال از ParallelEntityModifier :

        //> ParallelEntityModifier
SequenceEntityModifier seModifier1 = new SequenceEntityModifier(new ScaleModifier(1, 1, 2),
new DelayModifier(0.5f),
new ScaleModifier(1, 2, 1));
SequenceEntityModifier seModifier2 = new SequenceEntityModifier(new AlphaModifier(1, 1, 0.4f),
new DelayModifier(0.5f),
new AlphaModifier(1, 0.4f, 1));

face.registerEntityModifier(new ParallelEntityModifier(seModifier1, seModifier2));

مثال از LoopEntityModifier :

برای LoopEntityModifier شما میتونید تعیین کنید که Modifier ها چه به تعداد تکرار بشوند و یا اینکه بصورت نامحدود همیشه در حال حرکت باشند :

 face.registerEntityModifier(new LoopEntityModifier(new ParallelEntityModifier(seModifier1, seModifier2), 3));

نمونه ایی از تکرار بی نهایت :

 face.registerEntityModifier(
new LoopEntityModifier(
new SequenceEntityModifier(
new ColorModifier(2, Color.RED, Color.BLUE),
new DelayModifier(0.5f),
new ScaleModifier(1, 1, 2),
new DelayModifier(0.5f),
new ScaleModifier(1, 2, 1),
new DelayModifier(0.5f),
new AlphaModifier(1, 1, 0.4f),
new DelayModifier(0.5f),
new AlphaModifier(1, 0.4f, 1))));

ا

پاسخ به سوال 
Criss  10 سال پیش
+10 0

MoveModifier و PathModifier

استفاده از EaseFunction ها

همونطور که در آموزش های آقای رمضان زاده گفته شد Modifier ها به همین جا ختم نمیشوند در ادامه آخرین چیزهایی که از Modifier ها بلد هستم رو به اشتراک میزارم

 MoveModifier :

این Modifier به شما کمک میکنه که تعیین کنید یک Sprite از یک نقطه X,Y به یک نقطه X,Y در زمان مشخصی حرکت کنه

//MoveModifier(pDuration, pFromX, pToX, pFromY, pToY) 

 MoveModifier moveModifer = new MoveModifier(5, 0, 800, 0, 480);
face.registerEntityModifier(moveModifer);

حتما متوجه این موضوع شدید که بعد از اتمام MoveModifier که در بالا ست کردیم Sprite از تصویر خارج میشه ، خب این کاملا طبیعی هست < همونطر که بهتون گفتم همه چیز از محور مختصات تبعیت میکنه و در محور مختصات همه چیز ار نقطه 0 و 0 در جهت عرض و طول ترسیم میشه < بنابراین تصویر ما از نقطه 800*480  شروع به ترسیم میکنه درحالی که به سمت خارج از Camera و Scene ترسیم میشه ، کد رو به شکل زیر تصحیح میکنیم

 MoveModifier moveModifer = new MoveModifier(5, 0, 800 - (face.getWidth() / 2), 0, 480 - (face.getHeight() / 2));
face.registerEntityModifier(moveModifer);

PathModifier :
این Modifier کمک میکنه چندیدن نقطه مختلف از مختصات برای حرکت کردن به Sprite ست کنید در تصویر نمونه ایی که قرار هست اجرا کنیم رو میبینید : (شروع از 0*0  پایان در 800*480)

Path path = new Path(5).to(0, 0).to(400, 0).to(400, 240).to(800, 240).to(800 - (face.getWidth()), 480 - (face.getHeight()));
face.registerEntityModifier(new PathModifier(5, path));

در مثال بالا PathModifier از دوقسمت تشکیل شده یکی مدت زمان هست و دومی Path هست ،  PathModifier بیشتر از این نیازی به توضیح نداره ، در مورد Path که از دو بخش تشکل شده بخش اول تعداد حرکت ها هست که در اینجا 5 هست ، حداقل تعدادی که میشه تعیین کرد هم 2 هست ، بخش دوم تشکیل میشه از مختصاتی از X,Y که باید به تعداد 5 بار تعریف بشه

EaseFunction :

AndEngine استفاده از EaseFunction ها رو خیلی راحت کرده ، برای اینکه با EaseFunction ها آشنا بشید برید Example اصلی AndEngine رو اجرا کنید و نمونه های مختلفش رو خودتون تست کنید در کلاس EaseFunctionExample.java به تعداد 36 نمونه مختلف رو مثال زده

 

برای ترکیب کردن EaseFunction با PathModifier و MoveModifier بصورت زیر کد میزنیم :

MoveModifier moveModifer = new MoveModifier(5, 0, 800 - (face.getWidth() / 2), 0, 480 - (face.getHeight() / 2), EaseBounceInOut.getInstance());
face.registerEntityModifier(moveModifer);

Path path = new Path(5).to(0, 0).to(400, 0).to(400, 240).to(800, 240).to(800 - (face.getWidth()), 480 - (face.getHeight()));
face.registerEntityModifier(new PathModifier(5, path, EaseBackIn.getInstance()));

 

در حال ویرایش . . .

پاسخ به سوال 
Criss  10 سال پیش
+10 0

تشخیص Touch روی Scene

 برای تشخیص کلیک شدن روی Scene باید اکتیویتی رو impelement کنیم از IOnSceneTouchListener و در این شرایط یک متد جدید به اسم onSceneTouchEvent به اکتیویتی اضافه میشه

public class TouchSceneAndArea extends BaseGameActivity implements IOnSceneTouchListener {

متد جدید :

  @Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
return false;
}

برای اینکه بتونیم از این متد استفاده کنیم لازم هست که که متد زیر رو در onCreateScene استفاده کنیم :

 scene.setOnSceneTouchListener(this);

بعد از این میتونیم مقدار X و Y در محل کلیک شده رو بدست بیاریم :

  @Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
pSceneTouchEvent.getX();
pSceneTouchEvent.getY();
return false;
}

اکتیوتی رو بصورت زیر میسازیم و خروجی هارو در LOG میتونیم بعد از هر کلیک دریافت کنیم :

 public class TouchSceneAndArea extends BaseGameActivity implements IOnSceneTouchListener {

private static final int WIDTH = 800;
private static final int HEIGHT = 480;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, WIDTH, HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.8f, 0.8f, 0.8f));

scene.setOnSceneTouchListener(this);

pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}


@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
Log.i("TOUCH", pSceneTouchEvent.getX() + " " + pSceneTouchEvent.getY());
return false;
}
}

حتما متوجه این موضوع شدید که با هر بار کلیک روی Scene کلی لاگ در خروجی نمایش داده میشه ، به این دلیل هست که این یک onClickListener ساده برای یک Button نیست ، در اینجا ما با Event سرو کار داریم ، Event ها مشخص میکنه که چه نوع کلیک شدنی روی Scene انجام شده

بصورت زیر کد بزنید اکتیویتی رو اجرا کنید و تست کنید خودتون متوجه میشید چه اتفاقی افتاده :

    @Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.isActionDown()) {
Log.i("TOUCH", pSceneTouchEvent.getX() + " " + pSceneTouchEvent.getY());
return true;
}
return false;
}

 در بالا میبینید که بعد از گرفتن Log مقدار true  رو Return کردیم ، شیوه صحیح کد زدن این هست چون نوع متد Boolean هست ، اما هنوز اینکه از نظر کاربردی چطور میتونه به ما کمک کنه رو نمیدونم ، و  نمیتونم مثال خوبی بزنم

پاسخ به سوال 
Criss  10 سال پیش
+10 0

تشخیص Touch روی یک Sprite

 برای تشخیص کلیک شدن روی یک Sprite اکتیوتی رو از IOnAreaTouchListener بصورت زیر Impelement میکنیم و متد جدیدی به اکتیویتی اضافه میشه

public class TouchArea extends BaseGameActivity implements IOnAreaTouchListener {

در ادامه مقدمات استفاده از متد onAreaTouched که جدیدا به اکتیویتی اضاف شده رو طی میکنیم : اکتیوتی به شکل زیر داریم

public class TouchArea extends BaseGameActivity implements IOnAreaTouchListener {

private static final int WIDTH = 800;
private static final int HEIGHT = 480;

TiledTextureRegion faceRegion;
BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, WIDTH, HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");
atlas = new BitmapTextureAtlas(getTextureManager(), 64, 32);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_box_tiled.png", 0, 0, 2, 1);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.6f, 0.8f, 0.2f));

AnimatedSprite faceSprite = new AnimatedSprite((WIDTH / 2) - (faceRegion.getWidth() / 2), (HEIGHT / 2) - (faceRegion.getHeight() / 2), faceRegion, getVertexBufferObjectManager());
faceSprite.animate(100);
scene.attachChild(faceSprite);

pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}


@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, ITouchArea pTouchArea, float pTouchAreaLocalX, float pTouchAreaLocalY) {
// TODO Auto-generated method stub
return false;
}
}

خب در ادامه ابتدا باید به متد onCreateScene متد زیر رو استفاده کنیم :

scene.setOnAreaTouchListener(this);

برای اینکه کلیک شدن روی هر Sprite تشخیص داده بشه ، باید مشخص کنیم که کدوم Sprite قراره روش کلیک بشه :

 scene.registerTouchArea(faceSprite);

 در نهایت اکتیوتی به شکل زیر داریم :

 public class TouchArea extends BaseGameActivity implements IOnAreaTouchListener {

private static final int WIDTH = 800;
private static final int HEIGHT = 480;

TiledTextureRegion faceRegion;
BitmapTextureAtlas atlas;


@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, WIDTH, HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
}


@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("res/");
atlas = new BitmapTextureAtlas(getTextureManager(), 64, 32);
faceRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_box_tiled.png", 0, 0, 2, 1);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}


@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.6f, 0.8f, 0.2f));
scene.setOnAreaTouchListener(this);

AnimatedSprite faceSprite = new AnimatedSprite((WIDTH / 2) - (faceRegion.getWidth() / 2), (HEIGHT / 2) - (faceRegion.getHeight() / 2), faceRegion, getVertexBufferObjectManager());
faceSprite.animate(100);

scene.attachChild(faceSprite);
scene.registerTouchArea(faceSprite);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}


@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}


@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, ITouchArea pTouchArea, float pTouchAreaLocalX, float pTouchAreaLocalY) {
Log.i("TouchArea", "New Event On Sprite");
return false;
}
}

 


پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .