AndEngine 3강 - Examples(예제) 실행하기 (by wono77)
이제 처음 보고 군침을 흘렸던 AndEngine의 샘플들을 살펴보면서 공부할 차례입니다. 솔직히 우리는 이 멋있어 보이는 예제들 때문에 AndEngine을 시작하게 되었지요. 정말 멋진 샘플들인지 하나하나 음미해 볼 것입니다.
예제: https://github.com/nicolasgramlich/AndEngineExamples
[ 예제의 실행 화면 ]
위 예제는 처음 살펴본 AndEngine의 QRCode로 마켓에서 다운받아 설치가 가능합니다. 하나하나 실행을 해보면 그 매력에 놀라실 겁니다. 아직 해보지 않으셨다면 지금 바로 폰에 설치하셔서 하나하나 실행해 보시길 적극 추천드립니다. 우리는 이 중에서 백그라운드 이미지가 횡으로 스크롤되고, 스프라이트 이미지 2개가 즐겁게 걸어다니는 "BackGrounds > Using an AutoParallaxBackground" 를 실행해보고 입맛에 맞게 스프라이트 이미지와 배경 이미지를 변경해보도록 하겠습니다.
example을 직접 실행하기 위해서는 extention들을 다 다운 받아서 셋팅해야 합니다. 하지만, 앞서 우리가 만든 AESample 프로젝트에서 원하는 샘플을 가져다가 실행해 보는 것만으로도 extention을 추가하지 않고 몇가지 샘플의 실행은 가능합니다. 우리는 필요한 샘플을 하나하나 실행해보고, 샘플 실행에 필요한 elxtention이 있다면, 추가하는 방법으로 진행해보겠습니다.
[ BackGrounds > Using an AutoParallaxBackground ]
다운 받은 샘플을 import 하셨을 겁니다. 이중 어떤게 저 예제인지 찾는것도 일입니다. 정리된 리스트가 있는 것도 아니니 말이죠. 다음 빨간 소스가 해당되는 소스입니다.
소스를 한번 쭉~ 살펴봅니다.
자, 여기서 과제가 한번 나가야겠지요?
첫번째 과제입니다.
예제에 있는 AutoParallaxBackgroudExample.java를 앞서 작성한 샘플에 붙여서 작동되도록 만들어보세요. 필요한 이미지는 5개입니다. 예제 폴더의 asset에서 가져오셔야 합니다.
package org.andengine.examples;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.AutoParallaxBackground;
import org.andengine.entity.scene.background.ParallaxBackground.ParallaxEntity;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;
/**
* (c) 2010 Nicolas Gramlich
* (c) 2011 Zynga
*
* @author Nicolas Gramlich
* @since 19:58:39 - 19.07.2010
*/
public class AutoParallaxBackgroundExample extends SimpleBaseGameActivity {
// ===========================================================
// Constants
// ===========================================================
private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;
// ===========================================================
// Fields
// ===========================================================
private BitmapTextureAtlas mBitmapTextureAtlas;
private TiledTextureRegion mPlayerTextureRegion;
private TiledTextureRegion mEnemyTextureRegion;
private BitmapTextureAtlas mAutoParallaxBackgroundTexture;
private ITextureRegion mParallaxLayerBack;
private ITextureRegion mParallaxLayerMid;
private ITextureRegion mParallaxLayerFront;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@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
public void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "player.png", 0, 0, 3, 4);
this.mEnemyTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "enemy.png", 73, 0, 3, 4);
this.mBitmapTextureAtlas.load();
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(this.getTextureManager(), 1024, 1024);
this.mParallaxLayerFront = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "parallax_background_layer_front.png", 0, 0);
this.mParallaxLayerBack = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "parallax_background_layer_back.png", 0, 188);
this.mParallaxLayerMid = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "parallax_background_layer_mid.png", 0, 669);
this.mAutoParallaxBackgroundTexture.load();
}
@Override
public Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene();
final AutoParallaxBackground autoParallaxBackground = new AutoParallaxBackground(0, 0, 0, 5);
final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(0.0f, new Sprite(0, CAMERA_HEIGHT - this.mParallaxLayerBack.getHeight(), this.mParallaxLayerBack, vertexBufferObjectManager)));
autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-5.0f, new Sprite(0, 80, this.mParallaxLayerMid, vertexBufferObjectManager)));
autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-10.0f, new Sprite(0, CAMERA_HEIGHT - this.mParallaxLayerFront.getHeight(), this.mParallaxLayerFront, vertexBufferObjectManager)));
scene.setBackground(autoParallaxBackground);
/* Calculate the coordinates for the face, so its centered on the camera. */
final float playerX = (CAMERA_WIDTH - this.mPlayerTextureRegion.getWidth()) / 2;
final float playerY = CAMERA_HEIGHT - this.mPlayerTextureRegion.getHeight() - 5;
/* Create two sprits and add it to the scene. */
final AnimatedSprite player = new AnimatedSprite(playerX, playerY, this.mPlayerTextureRegion, vertexBufferObjectManager);
player.setScaleCenterY(this.mPlayerTextureRegion.getHeight());
player.setScale(2);
player.animate(new long[]{200, 200, 200}, 3, 5, true);
final AnimatedSprite enemy = new AnimatedSprite(playerX - 80, playerY, this.mEnemyTextureRegion, vertexBufferObjectManager);
enemy.setScaleCenterY(this.mEnemyTextureRegion.getHeight());
enemy.setScale(2);
enemy.animate(new long[]{200, 200, 200}, 3, 5, true);
scene.attachChild(player);
scene.attachChild(enemy);
return scene;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "player.png", 0, 0, 3, 4);
this.mBitmapTextureAtlas.load();
enemy.animate(new long[]{200, 200, 200}, 3, 5, true);
3장의 스프라이트 이미지를 각각 200프레임으로 총 갯수중 3~5번 이미지까지 뿌리라고 되어 있습니다.(배열의 첫 시작은 0입니다. player.png는 3x4 총 12장의 이미지이므로 3~5번 이미지이면, 위에서 2번째 줄의 3개 이미지가 되겠습니다.)
자, 이제 2번째 과제 나갑니다.
위 소스를 응용해서, 다음 이미지를 2개의 이미지가 반복되도록 출력해보세요~
[runner.png]
어렵지 않으니 직접 한번 고민해보신 다음 정답을 봐주세요.^^
[정답]
기존 소스는 파란색, 추가된 소스는 녹색으로 표시하였습니다.
this.mBitmapTextureAtlas = new BitmapTextureAtlas(
this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
this.mBitmapTextureAtlas2 = new BitmapTextureAtlas(
this.getTextureManager(), 111, 90, TextureOptions.BILINEAR);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createTiledFromAsset(this.mBitmapTextureAtlas, this,
"player.png", 0, 0, 3, 4);
// this.mEnemyTextureRegion = BitmapTextureAtlasTextureRegionFactory
// .createTiledFromAsset(this.mBitmapTextureAtlas, this,
// "enemy.png", 73, 0, 3, 4);
this.mEnemyTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createTiledFromAsset(this.mBitmapTextureAtlas2, this,
"runner.png", 0, 0, 2, 1);
this.mBitmapTextureAtlas.load();
this.mBitmapTextureAtlas2.load();
[이미지 선언부]
this.mBitmapTextureAtlas = new BitmapTextureAtlas(
this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
runner.png는 가로 111, 세로 90 픽셀의 이미지입니다. 이미지가 뿌려질 판을 선언하기 위해서는 TextureAtlas2를 선언합니다.
this.mEnemyTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createTiledFromAsset(this.mBitmapTextureAtlas2, this,
"runner.png", 0, 0, 2, 1);
runner.png의 이미지는 가로 2개, 세로 1줄의 스프라이트 이미지입니다.
// final AnimatedSprite enemy = new AnimatedSprite(playerX - 80, playerY,
// this.mEnemyTextureRegion, vertexBufferObjectManager);
final float playerY2 = CAMERA_HEIGHT
- this.mEnemyTextureRegion.getHeight() - 5;
final AnimatedSprite enemy = new AnimatedSprite(playerX - 80, playerY2,
this.mEnemyTextureRegion, vertexBufferObjectManager);
final AnimatedSprite enemy = new AnimatedSprite(playerX - 80, playerY2,
this.mEnemyTextureRegion, vertexBufferObjectManager);
enemy.setScaleCenterY(this.mEnemyTextureRegion.getHeight());
enemy.setScale(2);
//enemy.animate(new long[] { 200, 200, 200 }, 3, 5, true);
enemy.animate(new long[] { 200, 200 }, 0, 1, true);
[이미지 출력부]
final float playerY2
player 객체의 높이를 추가된 이미지인 palyerY2로 따로 선언했어요.
emy.animate(new long[] { 200, 200 }, 0, 1, true);
반복되는 이미지가 2개 이므로, 프로엠도 2개만 선언했고, 0~1번 이미지가 반복됩니다.
결과는 다음과 같은 화면이 보여지게 됩니다.
[결과]
이제 배경 이미지를 변경해 볼까요?
예제 소스에는 다음배경, 구름, 검은 땅 이미지의 3가지 이미지로 구성되어 있습니다.
[1. parallax_background_layer_back]
[2. parallax_background_layer_front]
[3. parallax_background_layer_middle]
즉, 1번 배경은 가만히 있고, 2번, 3번 이미지만 움직여서 배경이 이동하는 효과를 내고 있습니다. 자세히 보시면 2번, 3번 이미지에서 끝나는 부분은 시작과 끝이 교묘하게 계산되어 어색하지 않도록 되어 있습니다. front, middle만 움직입니다. 다음 코드가 front, middle 이미지의 스크롤 속도를 조절하고 있습니다.
autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(0.0f,
new Sprite(0, CAMERA_HEIGHT
- this.mParallaxLayerBack.getHeight(),
this.mParallaxLayerBack, vertexBufferObjectManager)));
//middle 이미지는 위에서 80 만큼 내려와서 출력합니다.
//-5 만큼 이동합니다.
autoParallaxBackground.attachParallaxEntity(new ParallaxEntity( -5.0f,
new Sprite(0, 80, this.mParallaxLayerMid,
vertexBufferObjectManager)));
//front 선인장 이미지는 전체 화면 높이에서 front 높이를 뺀 만큼 위에서 내려온 위치에 출력됩니다.
autoParallaxBackground.attachParallaxEntity(new ParallaxEntity( -10.0f,
new Sprite(0, CAMERA_HEIGHT
- this.mParallaxLayerFront.getHeight(),
this.mParallaxLayerFront, vertexBufferObjectManager)));
[배경 이미지 횡스크롤 속도 조절]
과제 3.
이제 배경 이미지를 변경해 보겠습니다. 마음에 드는 이미지로 배경 이미지를 변경해보세요.
쉬우셨나요?
기존 이미지는 640 *480을 사용하는데 저는 800*480으로 변경하고 관련 소스를 조금 변경해보았습니다.
private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;
[기존]
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
[변경]
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(
this.getTextureManager(), 1024, 1024);
this.mParallaxLayerBack = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mAutoParallaxBackgroundTexture, this,
"parallax_background_layer_back.png", 0, 188);
[기존]
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(
this.getTextureManager(), 1280, 800);
// 480 * 800 경주 안압지
this.mParallaxLayerBack = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mAutoParallaxBackgroundTexture, this,
"ky_an.png", 0, 188);
[변경]
그리고 일단 달리는 캐릭터를 차후에 화면 터치시 달리기 위해, 움직이지 않도록 다음 소스를 주석 달아보았습니다.
enemy.animate(new long[] { 200, 200 }, 0, 1, true);
* [ 블랙독의 "AndEngine으로 배우는 안드로이드 게임 프로그래밍"
- 나도 이제 안드로이드 게임개발자!! 강좌 리스트 ]
AndEngine 6강 - 충돌 구현 : http://blog.naver.com/wono77/140176342020
AndEngine 5강 - 점프 구현 : http://blog.naver.com/wono77/140174350342
AndEngine 4강 - 터치, 이미지 출력/해제, 폰트 변경 : http://blog.naver.com/wono77/140173160582
AndEngine 3강 - Examples(예제) 실행하기 : http://blog.naver.com/wono77/140172587747
AndEngine 2강 - 샘플 프로젝트 생성 : http://blog.naver.com/wono77/140172586342
AndEngine 1강 - andengine.jar 생성하기: http://blog.naver.com/wono77/140172582693
안드로이드 게임 sdk 소개 : http://blog.naver.com/wono77/140172218034
* 안드엔진 까페( http://andengine.co.kr)로 놀러 오세요~~~!!
참고 : saksin님의 예제 실행을 위해 extention을 셋팅하는 강좌:
http://saksin.tistory.com/m/post/view/id/905
블랙독의 "AndEngine 강좌"는
데브안드로이 까페(http://cafe.naver.com/devandroi)
AndEngine 까페(http://cafe.naver.com/andenginekorea)
에서 연재되고 있습니다.
안녕하세요, 블랙독입니다.
일주일간 준비한 강좌는 여기까지입니다. 반응 좋으면 다음 강좌까지 힘내어 계속 전진합니다.~
댓글로 아무글이나 많은 응원 부탁드립니다.
"이게 뭐냐~!" "똑바로해라!" "그걸 강좌라고!!!" "잘했다" "힘내요 오빠~"
등 다양한 댓글 대환영입니다!! 뉴.뉴
안드엔진 한국 사용자 모임을 개설해보았습니다. 아직은 회원이 저 혼자입니다.=ㅂ=a;'
회원이 많이 모이면, 오프 모임이나 AndEngine 개발자 니콜라스님의 축전등도 받아보고, ...
혹시 알아요~ 개발자 니콜라스님을 한국에 모셔서 세미나를 열수 있을지도;;
안드엔진의 고수, 혹은 저같은 초보 모두 오셔서 많은 정보 공유하고 같이 공부해보았으면 합니다.
- Screenshot_2012-11-13-18-49-23.png (169.2KB)(10)
- Screenshot_2012-11-13-18-49-29.png (52.3KB)(3)
- sample_list.png (12.6KB)(5)
- player.png (2.3KB)(5)
- runner.png (873Bytes)(5)
- Screenshot_2012-11-14-14-37-14.png (58.3KB)(1)
- Screenshot_2012-11-17-02-45-34.png (323.7KB)(1)
- parallax_background_layer_back.png (14.9KB)(6)
- parallax_background_layer_front.png (8.0KB)(6)
- parallax_background_layer_mid.png (10.6KB)(7)
- blackdog.png (2.1KB)(5)
좋은 강좌 감사합니다.^^
저도 한때 AndEngine을 썼었거든요,ㅎㅎㅎ
그 때는 국내에 참고할 자료가 거의 없었는데, 좋은 일 하고 계시네요^^