这次,我们来谈谈背景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 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(); } }