(轉自:http://blog.csdn.net/xyz_fly/article/details/7466643)
這次,我們來談談背景background的一些類及用法。關於background的用法,AndEngineExamples中有單獨的例子分別介紹了,在這裏,我們也只是將例子稍加改造。
AndEngineExamples中第一個例子便是AutoParallaxBackgroundExample——自動視差背景。也就是有層次感的背影移動變化。比如人在場景中跑動,我們爲了襯托出人物是在跑動,就會例如增加幾朵雲,讓它向人物跑動的方向移動,這樣人們就會認爲人物是跑起來的。但實際上,人物並沒有移動位置。
早期,做過橫版過關遊戲的人都要自己去實現視差背景,大致上講,就是讓人物座標基本不動,讓背景也保持不動,讓中間一層(街道,地面)向人物相反方向移動。如果想做得更精細些,就會增加一些雲彩,但云彩又不能和地面移動的速度一樣,就需要單獨設置雲彩的移動速度。
好了,andengine已經爲我設計好了這些接下來看看它是怎麼做的。
AutoParallaxBackground——自動視差背景類,我們所有操作都要基於它的對象來實現。
AutoParallaxBackground只有一個構造方法:
public AutoParallaxBackground(final float pRed, final float pGreen, final float pBlue, final float pParallaxChangePerSecond) :
前三個很簡單,分別對應的顏色數值;pParallaxChangePerSecond爲背景每秒移動的距離。
讓我很不解的是:以AutoParallaxBackground作者的風格,會封裝很多適合大家所需的方法。背景顏色一般沒人會去設置,所以,這裏其實還應該再增加一個構造方法:
- public AutoParallaxBackground(final float pParallaxChangePerSecond) {
- super(0, 0, 0);
- this.mParallaxChangePerSecond = pParallaxChangePerSecond;
- }
public void attachParallaxEntity(final ParallaxEntity pParallaxEntity),這個方法來自於其父類,需要傳入一個ParallaxEntity的對象。
從ParallaxEntity的構造方法來看:
public ParallaxEntity(final float pParallaxFactor, final IAreaShape pAreaShape) :pParallaxFactor背景移動的相對數值。pAreaShape一般爲精靈對象。
public void setParallaxValue(final float pParallaxValue):設置背景的初始位置。你可以理解成X軸的位置。
public void setParallaxChangePerSecond(final float pParallaxChangePerSecond):設置每秒移動的距離,這個和構造方法中的最後一個參數是一樣的。我們主要就是通過改變這個值來實現背景的移動。
這裏直接用AutoParallaxBackgroundExample的例子,並稍加改造:
- public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
- throws Exception {
- Scene mScene = new Scene();
- // 最後一個參數原來是5,我們這裏設爲0,意思是讓它一開始不要滾動
- final AutoParallaxBackground autoParallaxBackground = new AutoParallaxBackground(
- 0, 0, 0, 0);
- // 0.0f,-0.5f,-10.0f:你可以把它們理解爲相對位置差
- autoParallaxBackground
- .attachParallaxEntity(new ParallaxEntity(0.0f,
- new Sprite(0, CAMERA_HEIGHT
- - this.mParallaxLayerBack.getHeight(),
- this.mParallaxLayerBack,
- getVertexBufferObjectManager())));
- autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-5.0f,
- new Sprite(0, 80, this.mParallaxLayerMid,
- getVertexBufferObjectManager())));
- autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-10.0f,
- new Sprite(0, CAMERA_HEIGHT
- - this.mParallaxLayerFront.getHeight(),
- this.mParallaxLayerFront,
- getVertexBufferObjectManager())));
- // 設置背景
- mScene.setBackground(autoParallaxBackground);
- final int playerX = (int) (CAMERA_WIDTH - this.mPlayerTextureRegion
- .getWidth()) / 2;
- final int playerY = (int) (CAMERA_HEIGHT
- - this.mPlayerTextureRegion.getHeight() - 5);
- final AnimatedSprite player = new AnimatedSprite(playerX, playerY,
- this.mPlayerTextureRegion, getVertexBufferObjectManager());
- player.setScaleCenterY(this.mPlayerTextureRegion.getHeight());
- player.setScale(2);
- player.animate(new long[] { 200, 200, 200 }, 3, 5, true);
- mScene.attachChild(player);
- // 我們新增加一個觸摸事件監聽
- mScene.setOnSceneTouchListener(new IOnSceneTouchListener() {
- public boolean onSceneTouchEvent(Scene pScene,
- TouchEvent pSceneTouchEvent) {
- switch (pSceneTouchEvent.getAction()) {
- case TouchEvent.ACTION_UP:// 當觸屏擡起的時候
- // 如果在右邊觸摸,我們讓屏幕向左滾動
- if (pSceneTouchEvent.getX() > 400) {
- // 設置每秒鐘背景滾動的距離
- autoParallaxBackground.setParallaxChangePerSecond(10);
- // 設置一下小人的幀序列
- player.animate(new long[] { 200, 200, 200 }, 3, 5, true);
- }
- // 如果在左邊觸摸,我們讓屏幕向右滾動
- else {
- // 設置每秒鐘背景滾動的距離
- autoParallaxBackground.setParallaxChangePerSecond(-10);
- // 設置一下小人的幀序列
- player.animate(new long[] { 200, 200, 200 }, 9, 11,
- true);
- }
- break;
- }
- return true;
- }
- });
- pOnCreateSceneCallback.onCreateSceneFinished(mScene);
- }
好了,你看明白了嗎,以下是源代碼:
- package com.testsprite;
- import org.andengine.engine.camera.Camera;
- import org.andengine.engine.options.EngineOptions;
- import org.andengine.engine.options.EngineOptions.ScreenOrientation;
- import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
- import org.andengine.entity.modifier.LoopEntityModifier;
- import org.andengine.entity.scene.IOnSceneTouchListener;
- 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.input.touch.TouchEvent;
- 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.TextureRegion;
- import org.andengine.opengl.texture.region.TiledTextureRegion;
- import org.andengine.ui.activity.BaseGameActivity;
- public class TestSprite extends BaseGameActivity {
- private static final int CAMERA_WIDTH = 720;
- private static final int CAMERA_HEIGHT = 480;
- private BitmapTextureAtlas mBitmapTextureAtlas;
- private TiledTextureRegion mPlayerTextureRegion;
- private BitmapTextureAtlas mAutoParallaxBackgroundTexture;
- private TextureRegion mParallaxLayerBack;
- private TextureRegion mParallaxLayerMid;
- private TextureRegion mParallaxLayerFront;
- public EngineOptions onCreateEngineOptions() {
- Camera mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
- EngineOptions mEngineOptions = new EngineOptions(true,
- ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(),
- mCamera);
- return mEngineOptions;
- }
- public void onCreateResources(
- OnCreateResourcesCallback pOnCreateResourcesCallback)
- throws Exception {
- this.mBitmapTextureAtlas = new BitmapTextureAtlas(getTextureManager(),
- 128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
- this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory
- .createTiledFromAsset(this.mBitmapTextureAtlas, this,
- "player.png", 0, 0, 3, 4);
- this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(
- getTextureManager(), 1024, 1024, TextureOptions.DEFAULT);
- this.mParallaxLayerFront = (TextureRegion) BitmapTextureAtlasTextureRegionFactory
- .createFromAsset(this.mAutoParallaxBackgroundTexture, this,
- "parallax_background_layer_front.png", 0, 0);
- this.mParallaxLayerBack = (TextureRegion) BitmapTextureAtlasTextureRegionFactory
- .createFromAsset(this.mAutoParallaxBackgroundTexture, this,
- "parallax_background_layer_back.png", 0, 188);
- this.mParallaxLayerMid = (TextureRegion) BitmapTextureAtlasTextureRegionFactory
- .createFromAsset(this.mAutoParallaxBackgroundTexture, this,
- "parallax_background_layer_mid.png", 0, 669);
- mBitmapTextureAtlas.load();
- mAutoParallaxBackgroundTexture.load();
- pOnCreateResourcesCallback.onCreateResourcesFinished();
- }
- LoopEntityModifier mLoopEntityModifier;
- public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
- throws Exception {
- Scene mScene = new Scene();
- // 最後一個參數原來是5,我們這裏設爲0,意思是讓它一開始不要滾動
- final AutoParallaxBackground autoParallaxBackground = new AutoParallaxBackground(
- 0, 0, 0, 0);
- // 0.0f,-0.5f,-10.0f:你可以把它們理解爲相對位置差
- autoParallaxBackground
- .attachParallaxEntity(new ParallaxEntity(0.0f,
- new Sprite(0, CAMERA_HEIGHT
- - this.mParallaxLayerBack.getHeight(),
- this.mParallaxLayerBack,
- getVertexBufferObjectManager())));
- autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-5.0f,
- new Sprite(0, 80, this.mParallaxLayerMid,
- getVertexBufferObjectManager())));
- autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-10.0f,
- new Sprite(0, CAMERA_HEIGHT
- - this.mParallaxLayerFront.getHeight(),
- this.mParallaxLayerFront,
- getVertexBufferObjectManager())));
- // 設置背景
- mScene.setBackground(autoParallaxBackground);
- final int playerX = (int) (CAMERA_WIDTH - this.mPlayerTextureRegion
- .getWidth()) / 2;
- final int playerY = (int) (CAMERA_HEIGHT
- - this.mPlayerTextureRegion.getHeight() - 5);
- final AnimatedSprite player = new AnimatedSprite(playerX, playerY,
- this.mPlayerTextureRegion, getVertexBufferObjectManager());
- player.setScaleCenterY(this.mPlayerTextureRegion.getHeight());
- player.setScale(2);
- player.animate(new long[] { 200, 200, 200 }, 3, 5, true);
- mScene.attachChild(player);
- // 我們新增加一個觸摸事件監聽
- mScene.setOnSceneTouchListener(new IOnSceneTouchListener() {
- public boolean onSceneTouchEvent(Scene pScene,
- TouchEvent pSceneTouchEvent) {
- switch (pSceneTouchEvent.getAction()) {
- case TouchEvent.ACTION_UP:// 當觸屏擡起的時候
- // 如果在右邊觸摸,我們讓屏幕向左滾動
- if (pSceneTouchEvent.getX() > 400) {
- // 設置每秒鐘背景滾動的距離
- autoParallaxBackground.setParallaxChangePerSecond(10);
- // 設置一下小人的幀序列
- player.animate(new long[] { 200, 200, 200 }, 3, 5, true);
- }
- // 如果在左邊觸摸,我們讓屏幕向右滾動
- else {
- // 設置每秒鐘背景滾動的距離
- autoParallaxBackground.setParallaxChangePerSecond(-10);
- // 設置一下小人的幀序列
- player.animate(new long[] { 200, 200, 200 }, 9, 11,
- true);
- }
- break;
- }
- return true;
- }
- });
- pOnCreateSceneCallback.onCreateSceneFinished(mScene);
- }
- public void onPopulateScene(Scene pScene,
- OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
- pOnPopulateSceneCallback.onPopulateSceneFinished();
- }
- }
自動視差背景