public class LineExample extends SimpleBaseGameActivity { /* Initializing the Random generator produces a comparable result over different versions. */ private static final long RANDOM_SEED = 1234567890; private static final int CAMERA_WIDTH = 720; private static final int CAMERA_HEIGHT = 480; private static final int LINE_COUNT = 100; @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() { } @Override public Scene onCreateScene() { this.mEngine.registerUpdateHandler(new FPSLogger()); final Scene scene = new Scene(); scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f)); final Random random = new Random(RANDOM_SEED); final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager(); for(int i = 0; i < LINE_COUNT; i++) { final float x1 = random.nextFloat() * CAMERA_WIDTH; final float x2 = random.nextFloat() * CAMERA_WIDTH; final float y1 = random.nextFloat() * CAMERA_HEIGHT; final float y2 = random.nextFloat() * CAMERA_HEIGHT; final float lineWidth = random.nextFloat() * 5; final Line line = new Line(x1, y1, x2, y2, lineWidth, vertexBufferObjectManager); line.setColor(random.nextFloat(), random.nextFloat(), random.nextFloat()); scene.attachChild(line); } return scene; } }
这是AndEngine给我们的第一个例子,在屏幕中画100条随机的线,使用的当然是OpenGL进行渲染。程序的业务线程什么都不做,工作的只有GLSurfaceView的渲染线程。让我们来一层一层解开这个列子。
首先例子中使用了SimpleBaseGameActivity作为外壳,作为继承于BaseGameActivity这个Engine实例最基础的载体,并没有太多的扩展。他实现了IGameInterface接口中BaseGameActivity未实现的onCreateResources、onCreateScene、onPopulateScene,整个加载顺序如下:
(1)Activity.onCreate --这个必然是一切的开端
(2)onCreateEngineOptions --onCreate方法中首先要求用户指定EngineOptions配置信息,构建Engine和Acivity。
(3)onSetContentView --> onSurfaceCreated--> onReloadResources --> onCreateGame--这部分调用并没有要求我们实现任何东西,第一个是创建GLSurfaceView加入Activity中;第二个是GLSurfaceView创建完成的回调方法,调用后面两个方法;第三个是要求Engine重载资源;第四个中开始一组回调。
(4)onCreateResources --要求用户创建资源,完成后回调onCreateResourcesCallback。
(5)onCreateScene --要求用户创建屏幕,完成后回调onCreateSceneCallback。
(6)onPopulateScene --要求用户填充屏幕,完成后回调onPopulateSceneCallback。
(7)onGameCreated --所有创建过程完成。 onResumeGame --引擎开始运作
再看程序实现,只进行了EngineOptions的创建和Scene的创建,那就分别看下这两个对象,再以后的例子中补充完整其他部分。
EngineOptions是引擎的配置项,构造函数的几个参数表示设置的各种配置,下面看看构造函数。
/** * EngineOptions的构造函数 * @param pFullscreen 是否全屏 * @param pScreenOrientation 屏幕的方向(固定横向、可变横向、固定纵向、可变纵向) * @param pResolutionPolicy 分辨率策略,实现繁多 * @param pCamera 视野 */ public EngineOptions(final boolean pFullscreen, final ScreenOrientation pScreenOrientation, final IResolutionPolicy pResolutionPolicy, final Camera pCamera) { }
分辨率策略都是继承于BaseResolutionPolicy,实现了IResolutionPolicy中的onMeasure方法,对GLSurfaceView进行调整。
Scene对象也是一个用于绘制的Entity,我会新开一篇说明,这里就不细说了。
哦好像说完了...但是我们好像吧主角落下了,这个不是话线的程序吗,那线呢?这个东西又是一时说不完的东西,等明天早上接着写完。
接着写,Line继承于Shape,Shape继承于Entity,拥有被Engine管理的种种特性,当然最重要的是可以被绘制;其次Shape实现了IShape接口:
public interface IShape extends IEntity, ITouchArea { public static final int BLENDFUNCTION_SOURCE_DEFAULT = GLES20.GL_SRC_ALPHA; public static final int BLENDFUNCTION_DESTINATION_DEFAULT = GLES20.GL_ONE_MINUS_SRC_ALPHA; public static final int BLENDFUNCTION_SOURCE_PREMULTIPLYALPHA_DEFAULT = GLES20.GL_ONE; public static final int BLENDFUNCTION_DESTINATION_PREMULTIPLYALPHA_DEFAULT = GLES20.GL_ONE_MINUS_SRC_ALPHA; //冲撞检查 public boolean collidesWith(final IShape pOtherShape); //设置色彩混合 public boolean isBlendingEnabled(); public void setBlendingEnabled(final boolean pBlendingEnabled); public int getBlendFunctionSource(); public int getBlendFunctionDestination(); public void setBlendFunctionSource(final int pBlendFunctionSource); public void setBlendFunctionDestination(final int pBlendFunctionDestination); public void setBlendFunction(final int pBlendFunctionSource, final int pBlendFunctionDestination); //顶点缓存管理 public VertexBufferObjectManager getVertexBufferObjectManager(); //实际的顶点缓存对象 public IVertexBufferObject getVertexBufferObject(); //GL2.0的着色器程序 public ShaderProgram getShaderProgram(); public void setShaderProgram(final ShaderProgram pShaderProgram); }
这里顶点缓存管理器和顶点缓存对象是引擎提供的缓存机制,缓存管理器又Engine控制,监控缓存对象的状态。缓存对象中保存着即将被渲染的数据,并提供更新缓存的方法,让渲染的时候直接使用已经生成好的数据,提供速度。
色彩融合是指出现互相掩盖时候“源因子”和“目标因子”的色彩融合办法,具体请阅读“OpenGL颜色混合——glBlendFunc()”。
着色器程序是GL2.0提供的新特征,包含很多控制,如视图、模式、映射矩阵等等。
回到Line对象中,他使用了HighPerformanceLineVertexBufferObject(高性能线形顶点缓存对象),其中的缓存数据mBufferData保存了颜色和起始坐标与结束坐标,并提供了onUpdateColor与onUpdateVertices两个办法修改缓存。Engine运行后所有Entity会被绘制,依次调用preDraw、draw、PostDraw方法,此时mBufferData就会被加入OpenGL中进行绘制,具体实现的地点在HighPerformanceLineVertexBufferObject 的onBufferData中。