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

Nicolas Gramlich
نصب APK از مثال ها (این نسخه قدیمی هست و آپدیت نشده !)
تعداد از بازی های ساخته شده با AndEngine از جمله عنکبوت حریص و Noogra Nuts
Blog (پیشنهاد میکنم تغییر آیپی بدید < که بتونید کلیپ های یوتیوب توی این آدرس رو ببینید)
این بازی هم با 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
تست و یادگیری بهتر
توی این قسمت سعی میکینم با کلیک شدن روی Scene یک sprite رو اضاف کنیم که تحت تاثیر جاذبه قرار بگیره توی این قسمت علاوه بر createBoxBody های که داشتیم ، body های دایره ایی هم میسازیم (createCircleBody) < همچنین EngineOptions رو از نوع Portrait انتخاب میکنیم ( اگر کمی خلاقیت داشته باشید میتونید مقادیر FixtureDef رو بصورت Random ست کنید )
public class PhysicsBoxBody extends BaseGameActivity {
private static final int WIDTH = 480;
private static final int HEIGHT = 800;
private BitmapTextureAtlas atlas;
private TiledTextureRegion regionBoxSprite;
private TiledTextureRegion regionCircleSprite;
@Override
public EngineOptions onCreateEngineOptions() {
Camera camera = new Camera(0, 0, WIDTH, HEIGHT);
return new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
}
@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
atlas = new BitmapTextureAtlas(getTextureManager(), 64, 64);
regionBoxSprite = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_box_tiled.png", 0, 0, 2, 1);
regionCircleSprite = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_circle_tiled.png", 0, 32, 2, 1);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.4f, 0.5f, 0.1f));
Rectangle ground = new Rectangle(0, HEIGHT - 6, WIDTH, 6, getVertexBufferObjectManager());
ground.setColor(Color.RED);
Rectangle left = new Rectangle(0, 0, 6, HEIGHT - 6, getVertexBufferObjectManager());
left.setColor(Color.BLUE);
Rectangle roof = new Rectangle(6, 0, WIDTH, 6, getVertexBufferObjectManager());
roof.setColor(Color.GREEN);
Rectangle right = new Rectangle(WIDTH - 6, 6, 6, HEIGHT - 12, getVertexBufferObjectManager());
right.setColor(Color.YELLOW);
final FixedStepPhysicsWorld myPhysicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0f, SensorManager.GRAVITY_EARTH), false, 10, 5);
scene.registerUpdateHandler(myPhysicsWorld);
FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.1f, 0.5f);
PhysicsFactory.createBoxBody(myPhysicsWorld, ground, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, roof, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, left, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, right, BodyType.StaticBody, WALL_FIXTURE_DEF);
scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
boolean bool = true;
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.isActionUp()) {
FixtureDef BODY_FIXTURE_DEF = PhysicsFactory.createFixtureDef(20f, 0.35f, 0.5f);
AnimatedSprite sprite = null;
Body dynamicBoxOrCircleBody = null;
if (bool) {
bool = false;
sprite = new AnimatedSprite(pSceneTouchEvent.getX() - regionCircleSprite.getWidth() / 2, pSceneTouchEvent.getY() - regionCircleSprite.getHeight() / 2, regionCircleSprite,
getVertexBufferObjectManager());
dynamicBoxOrCircleBody = PhysicsFactory.createCircleBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BODY_FIXTURE_DEF);
} else {
bool = true;
sprite = new AnimatedSprite(pSceneTouchEvent.getX() - regionBoxSprite.getWidth() / 2, pSceneTouchEvent.getY() - regionBoxSprite.getHeight() / 2, regionBoxSprite,
getVertexBufferObjectManager());
dynamicBoxOrCircleBody = PhysicsFactory.createBoxBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BODY_FIXTURE_DEF);
}
sprite.animate(150);
myPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(sprite, dynamicBoxOrCircleBody, PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
pScene.attachChild(sprite);
}
return false;
}
});
scene.attachChild(ground);
scene.attachChild(left);
scene.attachChild(roof);
scene.attachChild(right);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}
@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}
چیز جدیدی برای توضیح وجود نداره !
استفاده از سنسور و تغییر جاذبه
کافیه از Interface زیر implement کنیم
implements IAccelerationListener
دیگه فکر میکنم خودتون بتونید کد رو تحلیل کنید
public class PhysicsBodysAndSensor extends BaseGameActivity implements IAccelerationListener {
private static final int WIDTH = 800;
private static final int HEIGHT = 480;
private BitmapTextureAtlas atlas;
private TiledTextureRegion regionBoxSprite;
private TiledTextureRegion regionCircleSprite;
private FixedStepPhysicsWorld myPhysicsWorld;
@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("gfx/");
atlas = new BitmapTextureAtlas(getTextureManager(), 64, 64);
regionBoxSprite = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_box_tiled.png", 0, 0, 2, 1);
regionCircleSprite = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_circle_tiled.png", 0, 32, 2, 1);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.4f, 0.5f, 0.1f));
Rectangle ground = new Rectangle(0, HEIGHT - 6, WIDTH, 6, getVertexBufferObjectManager());
ground.setColor(Color.RED);
Rectangle left = new Rectangle(0, 0, 6, HEIGHT - 6, getVertexBufferObjectManager());
left.setColor(Color.BLUE);
Rectangle roof = new Rectangle(6, 0, WIDTH, 6, getVertexBufferObjectManager());
roof.setColor(Color.GREEN);
Rectangle right = new Rectangle(WIDTH - 6, 6, 6, HEIGHT - 12, getVertexBufferObjectManager());
right.setColor(Color.YELLOW);
myPhysicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0f, SensorManager.GRAVITY_EARTH), false, 10, 5);
scene.registerUpdateHandler(myPhysicsWorld);
FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.1f, 0.5f);
PhysicsFactory.createBoxBody(myPhysicsWorld, ground, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, roof, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, left, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, right, BodyType.StaticBody, WALL_FIXTURE_DEF);
scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
boolean bool = true;
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.isActionUp()) {
FixtureDef BODY_FIXTURE_DEF = PhysicsFactory.createFixtureDef(20f, 0.35f, 0.5f);
AnimatedSprite sprite = null;
Body dynamicBoxOrCircleBody = null;
if (bool) {
bool = false;
sprite = new AnimatedSprite(pSceneTouchEvent.getX() - regionCircleSprite.getWidth() / 2, pSceneTouchEvent.getY() - regionCircleSprite.getHeight() / 2, regionCircleSprite,
getVertexBufferObjectManager());
dynamicBoxOrCircleBody = PhysicsFactory.createCircleBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BODY_FIXTURE_DEF);
} else {
bool = true;
sprite = new AnimatedSprite(pSceneTouchEvent.getX() - regionBoxSprite.getWidth() / 2, pSceneTouchEvent.getY() - regionBoxSprite.getHeight() / 2, regionBoxSprite,
getVertexBufferObjectManager());
dynamicBoxOrCircleBody = PhysicsFactory.createBoxBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BODY_FIXTURE_DEF);
}
sprite.animate(150);
myPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(sprite, dynamicBoxOrCircleBody, PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
pScene.attachChild(sprite);
}
return false;
}
});
scene.attachChild(ground);
scene.attachChild(left);
scene.attachChild(roof);
scene.attachChild(right);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}
@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
@Override
public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
}
@Override
public void onAccelerationChanged(AccelerationData pAccelerationData) {
Vector2 gravity = Vector2Pool.obtain(pAccelerationData.getX(), pAccelerationData.getY());
myPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
@Override
public synchronized void onResumeGame() {
enableAccelerationSensor(this);
super.onResumeGame();
}
@Override
public synchronized void onPauseGame() {
disableAccelerationSensor();
super.onPauseGame();
}
}
تست و یادگیری بهتر
توی این تست سعی میکنیم از یک AnalogOnScreenContrlo استفاده کنیم و با کمک اون جاذبه رو تغییر بدیم ! چه بازی هایی که نمیشه با این ساخت !
public class PhysicsBodysGravityAnalog extends BaseGameActivity {
private static final int WIDTH = 800;
private static final int HEIGHT = 480;
private Camera camera;
private BitmapTextureAtlas atlas;
private TiledTextureRegion regionBoxSprite;
private TiledTextureRegion regionCircleSprite;
private ITextureRegion regionAnalogBase;
private ITextureRegion regionAnalogKnob;
private FixedStepPhysicsWorld myPhysicsWorld;
@Override
public EngineOptions onCreateEngineOptions() {
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("gfx/");
atlas = new BitmapTextureAtlas(getTextureManager(), 256, 164);
regionBoxSprite = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_box_tiled.png", 0, 0, 2, 1);
regionCircleSprite = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlas, this, "face_circle_tiled.png", 0, 32, 2, 1);
regionAnalogBase = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "onscreen_control_base.png", 64, 0);
regionAnalogKnob = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "onscreen_control_knob.png", 192, 0);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.4f, 0.5f, 0.1f));
Rectangle ground = new Rectangle(0, HEIGHT - 6, WIDTH, 6, getVertexBufferObjectManager());
ground.setColor(Color.RED);
Rectangle left = new Rectangle(0, 0, 6, HEIGHT - 6, getVertexBufferObjectManager());
left.setColor(Color.BLUE);
Rectangle roof = new Rectangle(6, 0, WIDTH, 6, getVertexBufferObjectManager());
roof.setColor(Color.GREEN);
Rectangle right = new Rectangle(WIDTH - 6, 6, 6, HEIGHT - 12, getVertexBufferObjectManager());
right.setColor(Color.YELLOW);
myPhysicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0f, SensorManager.GRAVITY_EARTH), false, 10, 5);
scene.registerUpdateHandler(myPhysicsWorld);
FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.1f, 0.5f);
PhysicsFactory.createBoxBody(myPhysicsWorld, ground, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, roof, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, left, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, right, BodyType.StaticBody, WALL_FIXTURE_DEF);
scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
boolean bool = true;
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.isActionUp()) {
FixtureDef BODY_FIXTURE_DEF = PhysicsFactory.createFixtureDef(20f, 0.35f, 0.5f);
AnimatedSprite sprite = null;
Body dynamicBoxOrCircleBody = null;
if (bool) {
bool = false;
sprite = new AnimatedSprite(pSceneTouchEvent.getX() - regionCircleSprite.getWidth() / 2, pSceneTouchEvent.getY() - regionCircleSprite.getHeight() / 2, regionCircleSprite,
getVertexBufferObjectManager());
dynamicBoxOrCircleBody = PhysicsFactory.createCircleBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BODY_FIXTURE_DEF);
} else {
bool = true;
sprite = new AnimatedSprite(pSceneTouchEvent.getX() - regionBoxSprite.getWidth() / 2, pSceneTouchEvent.getY() - regionBoxSprite.getHeight() / 2, regionBoxSprite,
getVertexBufferObjectManager());
dynamicBoxOrCircleBody = PhysicsFactory.createBoxBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BODY_FIXTURE_DEF);
}
sprite.animate(150);
myPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(sprite, dynamicBoxOrCircleBody, PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
pScene.attachChild(sprite);
}
return false;
}
});
AnalogOnScreenControl alanogLeft = new AnalogOnScreenControl(0, HEIGHT - regionAnalogBase.getHeight(), camera,
regionAnalogBase, regionAnalogKnob, 0.1f, 200, this.getVertexBufferObjectManager(),
new IAnalogOnScreenControlListener() {
@Override
public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
Vector2 gravity = Vector2Pool.obtain(0, 3);
if (pValueX != 0 || pValueY != 0) {
gravity = Vector2Pool.obtain(pValueX * 10, pValueY * 10);
}
myPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
@Override
public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {}
});
alanogLeft.getControlBase().setAlpha(0.2f);
alanogLeft.getControlKnob().setAlpha(0.2f);
alanogLeft.getControlBase().setScaleCenter(0, 128);
alanogLeft.refreshControlKnobPosition();
scene.setChildScene(alanogLeft);
scene.attachChild(ground);
scene.attachChild(left);
scene.attachChild(roof);
scene.attachChild(right);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}
@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}
LinearVelocity
این قابلیت رو میشه به body ست کرد این رو به آموزشی که قبلا توی کلاس PhysicsBoxBody توضیح داده بودم اضاف میکنیم
کد جدید به شکل زیر هست
scene.setOnAreaTouchListener(new IOnAreaTouchListener() {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, ITouchArea pTouchArea, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (pSceneTouchEvent.isActionUp()) {
dynamicBoxBody.setLinearVelocity(10, 20);
}
return false;
}
});
scene.registerTouchArea(sprite);
تمام کد :
public class PhysicsLinearVelocity extends BaseGameActivity {
private static final int WIDTH = 800;
private static final int HEIGHT = 480;
private BitmapTextureAtlas atlas;
private TiledTextureRegion regionSprite;
@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("gfx/");
atlas = new BitmapTextureAtlas(getTextureManager(), 64, 32);
regionSprite = 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.4f, 0.5f, 0.1f));
int CenterX = WIDTH / 2;
int CenterY = HEIGHT / 2;
AnimatedSprite sprite = new AnimatedSprite(CenterX - regionSprite.getWidth() / 2, CenterY - regionSprite.getHeight() / 2, regionSprite, getVertexBufferObjectManager());
sprite.animate(150);
Rectangle ground = new Rectangle(0, HEIGHT - 6, WIDTH, 6, getVertexBufferObjectManager());
ground.setColor(Color.RED);
Rectangle left = new Rectangle(0, 0, 6, HEIGHT - 6, getVertexBufferObjectManager());
left.setColor(Color.BLUE);
Rectangle roof = new Rectangle(6, 0, WIDTH, 6, getVertexBufferObjectManager());
roof.setColor(Color.GREEN);
Rectangle right = new Rectangle(WIDTH - 6, 6, 6, HEIGHT - 12, getVertexBufferObjectManager());
right.setColor(Color.YELLOW);
FixedStepPhysicsWorld myPhysicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0f, SensorManager.GRAVITY_EARTH), false, 8, 3);
scene.registerUpdateHandler(myPhysicsWorld);
FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.1f, 0.5f);
FixtureDef BOX_BODY_FIXTURE_DEF = PhysicsFactory.createFixtureDef(20f, 0.35f, 0.5f);
PhysicsFactory.createBoxBody(myPhysicsWorld, ground, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, roof, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, left, BodyType.StaticBody, WALL_FIXTURE_DEF);
PhysicsFactory.createBoxBody(myPhysicsWorld, right, BodyType.StaticBody, WALL_FIXTURE_DEF);
final Body dynamicBoxBody = PhysicsFactory.createBoxBody(myPhysicsWorld, sprite, BodyType.DynamicBody, BOX_BODY_FIXTURE_DEF);
myPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(sprite, dynamicBoxBody, PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
scene.setOnAreaTouchListener(new IOnAreaTouchListener() {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, ITouchArea pTouchArea, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (pSceneTouchEvent.isActionUp()) {
dynamicBoxBody.setLinearVelocity(10, 20);
}
return false;
}
});
scene.registerTouchArea(sprite);
scene.attachChild(sprite);
scene.attachChild(ground);
scene.attachChild(left);
scene.attachChild(roof);
scene.attachChild(right);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}
@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}
در آخر برای یادگیری بهتر و کاربردی کلاس PhysicsJumpExample رو هم ببینید
تعقیب کردن یک کاراکتر متحرک با دوربین
طبق این آموزش تنها به یک متد موجود در Camera نیاز داریم :
camera.setChaseEntity(myrec);
کد کامل به شکل زیر :
public class CameraFollowSprite extends BaseGameActivity {
private static final int WIDTH = 800;
private static final int HEIGHT = 480;
private Camera camera;
private BitmapTextureAtlas atlas;
private ITextureRegion regionAnalogBase;
private ITextureRegion regionAnalogKnob;
@Override
public EngineOptions onCreateEngineOptions() {
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("gfx/");
atlas = new BitmapTextureAtlas(getTextureManager(), 128, 192);
regionAnalogBase = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "onscreen_control_base.png", 0, 0);
regionAnalogKnob = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "onscreen_control_knob.png", 0, 128);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.3f, 0.35f, 0.0f));
final Rectangle myrec = new Rectangle(WIDTH / 2, HEIGHT / 2, 48, 48, getVertexBufferObjectManager());
myrec.setColor(Color.BLACK);
Rectangle rec1 = new Rectangle(50, HEIGHT / 2, 48, 48, getVertexBufferObjectManager());
rec1.setColor(Color.RED);
Rectangle rec2 = new Rectangle(850, HEIGHT / 2, 48, 48, getVertexBufferObjectManager());
rec2.setColor(Color.BLUE);
Rectangle rec3 = new Rectangle(1250, HEIGHT / 2, 48, 48, getVertexBufferObjectManager());
rec3.setColor(Color.YELLOW);
camera.setChaseEntity(myrec);
final PhysicsHandler physicsHandler = new PhysicsHandler(myrec);
myrec.registerUpdateHandler(physicsHandler);
AnalogOnScreenControl alanogLeft = new AnalogOnScreenControl(400 - regionAnalogBase.getWidth() / 2, HEIGHT - regionAnalogBase.getHeight() - 50, camera,
regionAnalogBase, regionAnalogKnob, 0.1f, 200, this.getVertexBufferObjectManager(),
new IAnalogOnScreenControlListener() {
@Override
public void onControlChange(BaseOnScreenControl pBaseOnScreenControl, float pValueX, float pValueY) {
physicsHandler.setVelocity(pValueX * 250, pValueY * 250);
}
@Override
public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
myrec.registerEntityModifier(new SequenceEntityModifier(new ScaleModifier(0.25f, 1, 1.5f), new ScaleModifier(0.25f, 1.5f, 1)));
}
});
alanogLeft.getControlBase().setAlpha(0.2f);
alanogLeft.getControlKnob().setAlpha(0.2f);
alanogLeft.getControlBase().setScaleCenter(0, 128);
alanogLeft.refreshControlKnobPosition();
scene.setChildScene(alanogLeft);
scene.attachChild(myrec);
scene.attachChild(rec1);
scene.attachChild(rec2);
scene.attachChild(rec3);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}
@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}
برای حرکت در جهت X به EngineOption کد های زیر رو اضاف کنید :
@Override
public EngineOptions onCreateEngineOptions() {
camera = new Camera(0, 0, WIDTH, HEIGHT) {
IEntity ie;
@Override
public void setChaseEntity(IEntity pChaseEntity) {
ie = pChaseEntity;
super.setChaseEntity(pChaseEntity);
}
@Override
public void updateChaseEntity() {
if (ie != null) {
float cord[] = ie.getSceneCenterCoordinates();
setCenter(cord[0], getCenterY());
}
}
};
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
}
CameraBound
توی آموزش های قبل دیدید که این Rectangle ما تا بینهایت میتونه ادامه پیدا کنه و همه جا سرک بشه ، به همراهش دوربین هم تعقیبش میکنه اما اگر قرار باشه با استفاده از دیوار مراحل بازی رو محدود کنیم که کاراکتر ما از بازی بیرون نره < باید دوربین رو هم براش مرز تعریف کنیم که تا یجایی به بعد دیگه کاراکتر رو هی تعقیب نکنه و اینجا آخر خط هستش
public class CameraBound extends BaseGameActivity {
private static final int WIDTH = 800;
private static final int HEIGHT = 480;
private BoundCamera camera;
private ITextureRegion regionAnalogBase;
private ITextureRegion regionAnalogKnob;
@Override
public EngineOptions onCreateEngineOptions() {
camera = new BoundCamera(0, 0, 800, 480);
camera.setBounds(0, 0, 1024, 800);
camera.setBoundsEnabled(true);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);
}
@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
BitmapTextureAtlas atlas = new BitmapTextureAtlas(getTextureManager(), 168, 192);
regionAnalogBase = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "onscreen_control_base.png", 0, 0);
regionAnalogKnob = BitmapTextureAtlasTextureRegionFactory.createFromAsset(atlas, this, "onscreen_control_knob.png", 0, 128);
atlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws Exception {
Scene scene = new Scene();
scene.setBackground(new Background(0.2f, 0.3f, 0.0f));
Rectangle rect = new Rectangle(50, HEIGHT / 2, 48, 48, getVertexBufferObjectManager());
Rectangle area = new Rectangle(0, 0, WIDTH, HEIGHT, getVertexBufferObjectManager());
area.setAlpha(0.2f);
camera.setChaseEntity(rect);
final PhysicsHandler physicsHandler = new PhysicsHandler(rect);
rect.registerUpdateHandler(physicsHandler);
AnalogOnScreenControl alanogLeft = new AnalogOnScreenControl(0, HEIGHT - regionAnalogBase.getHeight(), camera,
regionAnalogBase, regionAnalogKnob, 0.1f, 200, this.getVertexBufferObjectManager(),
new IAnalogOnScreenControlListener() {
@Override
public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
physicsHandler.setVelocity(pValueX * 100, pValueY * 100);
}
@Override
public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {}
});
alanogLeft.getControlBase().setAlpha(0.2f);
alanogLeft.getControlKnob().setAlpha(0.2f);
alanogLeft.getControlBase().setScaleCenter(0, 128);
alanogLeft.refreshControlKnobPosition();
scene.setChildScene(alanogLeft);
scene.attachChild(rect);
scene.attachChild(area);
pOnCreateSceneCallback.onCreateSceneFinished(scene);
}
@Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}
تست و یادگیری بهتر
ساخت دشمن هوشمند به روش صحیح
محاسبه و نمایش فاصله طی شده از نقطه شروع در HUD
نشانه گیری به سمت کاراکتر متحرک (چالش نیاز به وقت و تست ، محاسبه زاویه بین وتر و یک ضلع)
Draw On Scene (چالش ، نیاز به بررسی)
Health for each enemy
دشمن هوشمند ، محاسبه فاصله شعاعی یا ابداع روشی دیگر
معرفی بازی های ساخته شده با AndEngine و الهام گرفتن از ایده ها و طرح ها
و . . .
اشتباه در آموزش ها :
توی آموزش های قبلی به اشتباه خط زیر وجود داره : (که همشون رو اصلاح کردم !!)
AnimatedSprite sprite = new mySprite
که باید بصورت زیر باشه :
mySprite sprite = new mySprite
اگر شما ازش استفاده کردید < اصلاحش کنید
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .