在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的大部分图形功能。