在EntityModifier部分已经提到过他,IEaseFunction是定义修改器数值随时间变化的计算函数。例子中使用了多个EaseFunction,并使用一个MoveModifier展示他们的不同。就本身来说这个例子没有什么可说的了,但是在其中有两个新的概率,一个是字体和文字;一个是摄像机的HUD(heads-up display)。下面做个说明吧。
Text是一种矩形形状,有坐标、有宽高,还拥有特有的TextVertexBufferObject,也就是说他也是能够渲染的图像而已。然后和Sprite不同,他的Texture和TextureRegion并不来自于ITextureRegion,而是来自于Font和Letter这两个类。Font(字体)包含了纹理以及bind在纹理上的文字位图,还包含了字体大小、间距、字体等信息,并提供了getLetter()方式的实现。Letter相当于纹理范围,当Text需要渲染是会通过Font找到纹理,通过Font产生Letter(显示范围)。
摄像机的HUD相当于在你的视野上添加一个图层,这个图层用处很多,比如相机上的十字线,汽车模拟游戏里面的仪表盘。在AndEngine中实际是在Camera中添加一个叫HUD的屏幕实体。
好了介绍了这么多总算可以上代码了:
package org.andengine.examples; import org.andengine.engine.camera.Camera; import org.andengine.engine.camera.hud.HUD; import org.andengine.engine.options.EngineOptions; import org.andengine.engine.options.ScreenOrientation; import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; import org.andengine.entity.modifier.MoveModifier; import org.andengine.entity.primitive.Line; import org.andengine.entity.scene.Scene; import org.andengine.entity.sprite.Sprite; import org.andengine.entity.text.Text; import org.andengine.entity.util.FPSLogger; import org.andengine.input.touch.TouchEvent; import org.andengine.opengl.font.Font; import org.andengine.opengl.texture.ITexture; 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.ui.activity.SimpleBaseGameActivity; import org.andengine.util.modifier.ease.EaseBackIn; import org.andengine.util.modifier.ease.EaseBackInOut; import org.andengine.util.modifier.ease.EaseBackOut; import org.andengine.util.modifier.ease.EaseBounceIn; import org.andengine.util.modifier.ease.EaseBounceInOut; import org.andengine.util.modifier.ease.EaseBounceOut; import org.andengine.util.modifier.ease.EaseCircularIn; import org.andengine.util.modifier.ease.EaseCircularInOut; import org.andengine.util.modifier.ease.EaseCircularOut; import org.andengine.util.modifier.ease.EaseCubicIn; import org.andengine.util.modifier.ease.EaseCubicInOut; import org.andengine.util.modifier.ease.EaseCubicOut; import org.andengine.util.modifier.ease.EaseElasticIn; import org.andengine.util.modifier.ease.EaseElasticInOut; import org.andengine.util.modifier.ease.EaseElasticOut; import org.andengine.util.modifier.ease.EaseExponentialIn; import org.andengine.util.modifier.ease.EaseExponentialInOut; import org.andengine.util.modifier.ease.EaseExponentialOut; import org.andengine.util.modifier.ease.EaseLinear; import org.andengine.util.modifier.ease.EaseQuadIn; import org.andengine.util.modifier.ease.EaseQuadInOut; import org.andengine.util.modifier.ease.EaseQuadOut; import org.andengine.util.modifier.ease.EaseQuartIn; import org.andengine.util.modifier.ease.EaseQuartInOut; import org.andengine.util.modifier.ease.EaseQuartOut; import org.andengine.util.modifier.ease.EaseQuintIn; import org.andengine.util.modifier.ease.EaseQuintInOut; import org.andengine.util.modifier.ease.EaseQuintOut; import org.andengine.util.modifier.ease.EaseSineIn; import org.andengine.util.modifier.ease.EaseSineInOut; import org.andengine.util.modifier.ease.EaseSineOut; import org.andengine.util.modifier.ease.EaseStrongIn; import org.andengine.util.modifier.ease.EaseStrongInOut; import org.andengine.util.modifier.ease.EaseStrongOut; import org.andengine.util.modifier.ease.IEaseFunction; import android.graphics.Color; import android.graphics.Typeface; public class EaseFunctionExample extends SimpleBaseGameActivity { private static final int CAMERA_WIDTH = 720; private static final int CAMERA_HEIGHT = 480; private Camera mCamera; //字体 private Font mFont; private BitmapTextureAtlas mBitmapTextureAtlas; //徽记的纹理范围 private ITextureRegion mBadgeTextureRegion; //next按钮的纹理范围 private ITextureRegion mNextTextureRegion; //各种EaseFunction的实现 private static final IEaseFunction[][] EASEFUNCTIONS = new IEaseFunction[][]{ new IEaseFunction[] { EaseLinear.getInstance(), EaseLinear.getInstance(), EaseLinear.getInstance() }, new IEaseFunction[] { EaseBackIn.getInstance(), EaseBackOut.getInstance(), EaseBackInOut.getInstance() }, new IEaseFunction[] { EaseBounceIn.getInstance(), EaseBounceOut.getInstance(), EaseBounceInOut.getInstance() }, new IEaseFunction[] { EaseCircularIn.getInstance(), EaseCircularOut.getInstance(), EaseCircularInOut.getInstance() }, new IEaseFunction[] { EaseCubicIn.getInstance(), EaseCubicOut.getInstance(), EaseCubicInOut.getInstance() }, new IEaseFunction[] { EaseElasticIn.getInstance(), EaseElasticOut.getInstance(), EaseElasticInOut.getInstance() }, new IEaseFunction[] { EaseExponentialIn.getInstance(), EaseExponentialOut.getInstance(), EaseExponentialInOut.getInstance() }, new IEaseFunction[] { EaseQuadIn.getInstance(), EaseQuadOut.getInstance(), EaseQuadInOut.getInstance() }, new IEaseFunction[] { EaseQuartIn.getInstance(), EaseQuartOut.getInstance(), EaseQuartInOut.getInstance() }, new IEaseFunction[] { EaseQuintIn.getInstance(), EaseQuintOut.getInstance(), EaseQuintInOut.getInstance() }, new IEaseFunction[] { EaseSineIn.getInstance(), EaseSineOut.getInstance(), EaseSineInOut.getInstance() }, new IEaseFunction[] { EaseStrongIn.getInstance(), EaseStrongOut.getInstance(), EaseStrongInOut.getInstance() } }; private int mCurrentEaseFunctionSet = 0; //三个徽记 private final Sprite[] mBadges = new Sprite[3]; //三段EaseFunction名称文本 private final Text[] mEaseFunctionNameTexts = new Text[3]; @Override public EngineOptions onCreateEngineOptions() { this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera); } @Override public void onCreateResources() { /* The font. */ //字体中包含的纹理,绑定文字的位图 final ITexture fontTexture = new BitmapTextureAtlas(this.getTextureManager(), 256, 256, TextureOptions.BILINEAR); this.mFont = new Font(this.getFontManager(), fontTexture, Typeface.create(Typeface.DEFAULT, Typeface.BOLD), 32, true, Color.WHITE); this.mFont.load(); /* The textures. */ this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 256, 128, TextureOptions.BILINEAR); BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/"); //next按钮的纹理范围 this.mNextTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "next.png", 0, 0); //产生移动徽记的纹理范围 this.mBadgeTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "badge.png", 97, 0); this.mBitmapTextureAtlas.load(); } @Override public Scene onCreateScene() { this.mEngine.registerUpdateHandler(new FPSLogger()); final Scene scene = new Scene(); //摄像机的HUD层 final HUD hud = new HUD(); final Sprite nextSprite = new Sprite(CAMERA_WIDTH - 100 - this.mNextTextureRegion.getWidth(), 0, this.mNextTextureRegion, this.getVertexBufferObjectManager()) { @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { if(pSceneTouchEvent.isActionDown()) { EaseFunctionExample.this.next(); } return true; }; }; final Sprite previousSprite = new Sprite(100, 0, this.mNextTextureRegion, this.getVertexBufferObjectManager()) { @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { if(pSceneTouchEvent.isActionDown()) { EaseFunctionExample.this.previous(); } return true; }; }; previousSprite.setFlippedHorizontal(true); //添加两个按钮在其中 hud.attachChild(nextSprite); hud.attachChild(previousSprite); hud.registerTouchArea(nextSprite); hud.registerTouchArea(previousSprite); this.mCamera.setHUD(hud); /* Create the sprites that will be moving. */ this.mBadges[0] = new Sprite(0, CAMERA_HEIGHT - 300, this.mBadgeTextureRegion, this.getVertexBufferObjectManager()); this.mBadges[1] = new Sprite(0, CAMERA_HEIGHT - 200, this.mBadgeTextureRegion, this.getVertexBufferObjectManager()); this.mBadges[2] = new Sprite(0, CAMERA_HEIGHT - 100, this.mBadgeTextureRegion, this.getVertexBufferObjectManager()); this.mEaseFunctionNameTexts[0] = new Text(0, CAMERA_HEIGHT - 250, this.mFont, "Function", 20, this.getVertexBufferObjectManager()); this.mEaseFunctionNameTexts[1] = new Text(0, CAMERA_HEIGHT - 150, this.mFont, "Function", 20, this.getVertexBufferObjectManager()); this.mEaseFunctionNameTexts[2] = new Text(0, CAMERA_HEIGHT - 50, this.mFont, "Function", 20, this.getVertexBufferObjectManager()); scene.attachChild(this.mBadges[0]); scene.attachChild(this.mBadges[1]); scene.attachChild(this.mBadges[2]); scene.attachChild(this.mEaseFunctionNameTexts[0]); scene.attachChild(this.mEaseFunctionNameTexts[1]); scene.attachChild(this.mEaseFunctionNameTexts[2]); scene.attachChild(new Line(0, CAMERA_HEIGHT - 110, CAMERA_WIDTH, CAMERA_HEIGHT - 110, this.getVertexBufferObjectManager())); scene.attachChild(new Line(0, CAMERA_HEIGHT - 210, CAMERA_WIDTH, CAMERA_HEIGHT - 210, this.getVertexBufferObjectManager())); scene.attachChild(new Line(0, CAMERA_HEIGHT - 310, CAMERA_WIDTH, CAMERA_HEIGHT - 310, this.getVertexBufferObjectManager())); return scene; } @Override public void onGameCreated() { this.reanimate(); } public void next() { this.mCurrentEaseFunctionSet++; this.mCurrentEaseFunctionSet %= EASEFUNCTIONS.length; this.reanimate(); } public void previous() { this.mCurrentEaseFunctionSet--; if(this.mCurrentEaseFunctionSet < 0) { this.mCurrentEaseFunctionSet += EASEFUNCTIONS.length; } this.reanimate(); } /** * 徽记坐标归位,并重新设置EaseFunction定义移动修改器。 */ private void reanimate() { this.runOnUpdateThread(new Runnable() { @Override public void run() { final IEaseFunction[] currentEaseFunctionsSet = EASEFUNCTIONS[EaseFunctionExample.this.mCurrentEaseFunctionSet]; final Text[] easeFunctionNameTexts = EaseFunctionExample.this.mEaseFunctionNameTexts; final Sprite[] faces = EaseFunctionExample.this.mBadges; for(int i = 0; i < 3; i++) { easeFunctionNameTexts[i].setText(currentEaseFunctionsSet[i].getClass().getSimpleName()); final Sprite face = faces[i]; face.clearEntityModifiers(); final float y = face.getY(); face.setPosition(0, y); face.registerEntityModifier(new MoveModifier(3, 0, CAMERA_WIDTH - face.getWidth(), y, y, currentEaseFunctionsSet[i])); } } }); } }学习到这个Demo后,已经可以看懂大部分的程序结构了,覆盖了AndEngine的大部分图形功能。