andEngine结构:
双线程:业务线程、渲染线程,使用ReentrantLock实现两个线程的交替执行。
渲染线程:使用GLSurfaceView提供的渲染功能,内置渲染绘图线程。
第一步:RenderSurfaceView为继承于GLSurfaceView的GL渲染视图,BaseGameActivity作为继承于Activity的活动,通过setContentView(RenderSurfaceView)将视图加入活动中。
BaseGameActivity中主要方法:
@Override
protected void onCreate(final Bundle pSavedInstanceState) {
if(BuildConfig.DEBUG) {
Debug.d(this.getClass().getSimpleName() + ".onCreate" + " @(Thread: '" + Thread.currentThread().getName() + "')");
}
super.onCreate(pSavedInstanceState);
//先处于暂停状态
this.mGamePaused = true;
//通过EngineOption定义,创建Engine
this.mEngine = this.onCreateEngine(this.onCreateEngineOptions());
//应用EngineOption定义到Activity
this.applyEngineOptions();
//添加RenderSurfaceView到Activity
this.onSetContentView();
}
protected void onSetContentView() {
this.mRenderSurfaceView = new RenderSurfaceView(this);
this.mRenderSurfaceView.setRenderer(this.mEngine, this);
this.setContentView(this.mRenderSurfaceView, BaseGameActivity.createSurfaceViewLayoutParams());
}
第二步:将渲染器EngineRenderer的加入RenderSurfaceView中,BaseGameActivity实现IRendererListener接口监听EngineRenderer。
EngineRenderer中的主要方法:
@Override
public void onSurfaceCreated(final GL10 pGL, final EGLConfig pEGLConfig) {
synchronized(GLState.class) {
final RenderOptions renderOptions = this.mEngine.getEngineOptions().getRenderOptions();
this.mGLState.reset(renderOptions, this.mConfigChooser, pEGLConfig);
// TODO Check if available and make available through EngineOptions-RenderOptions
// GLES20.glEnable(GLES20.GL_POLYGON_SMOOTH);
// GLES20.glHint(GLES20.GL_POLYGON_SMOOTH_HINT, GLES20.GL_NICEST);
// GLES20.glEnable(GLES20.GL_LINE_SMOOTH);
// GLES20.glHint(GLES20.GL_LINE_SMOOTH_HINT, GLES20.GL_NICEST);
// GLES20.glEnable(GLES20.GL_POINT_SMOOTH);
// GLES20.glHint(GLES20.GL_POINT_SMOOTH_HINT, GLES20.GL_NICEST);
//2D不需要深度
this.mGLState.disableDepthTest();
this.mGLState.enableBlend();
this.mGLState.setDitherEnabled(renderOptions.isDithering());
/* Enabling culling doesn't really make sense, because triangles are never drawn 'backwards' on purpose. */
// this.mGLState.enableCulling();
// GLES20.glFrontFace(GLES20.GL_CCW);
// GLES20.glCullFace(GLES20.GL_BACK);
//回调BaseGameActivity中onSurfaceCreated
if(this.mRendererListener != null) {
this.mRendererListener.onSurfaceCreated(this.mGLState);
}
}
}
@Override
public void onSurfaceChanged(final GL10 pGL, final int pWidth, final int pHeight) {
//确定因为和GL的显示区域大小
this.mEngine.setSurfaceSize(pWidth, pHeight);
GLES20.glViewport(0, 0, pWidth, pHeight);
this.mGLState.loadProjectionGLMatrixIdentity();
//回调BaseGameActivity中onSurfaceChanged
if(this.mRendererListener != null) {
this.mRendererListener.onSurfaceChanged(this.mGLState, pWidth, pHeight);
}
}
@Override
public void onDrawFrame(final GL10 pGL) {
synchronized(GLState.class) {
if (this.mMultiSampling && this.mConfigChooser.isCoverageMultiSampling()) {
final int GL_COVERAGE_BUFFER_BIT_NV = 0x8000;
GLES20.glClear(GL_COVERAGE_BUFFER_BIT_NV);
}
try {
//调用引擎中的方法
this.mEngine.onDrawFrame(this.mGLState);
} catch (final InterruptedException e) {
Debug.e("GLThread interrupted!", e);
}
}
}
Engine中的主要方法:
public void onDrawFrame(final GLState pGLState) throws InterruptedException {
final EngineLock engineLock = this.mEngineLock;
//绘制过程中为引擎加锁,等待绘制完成
engineLock.lock();
try {
engineLock.waitUntilCanDraw();
//更新顶点缓存,去除Unloaded的缓存
this.mVertexBufferObjectManager.updateVertexBufferObjects(pGLState);
//更新纹理,加载纹理到硬件
this.mTextureManager.updateTextures(pGLState);
//更新字体,绘制所有文字
this.mFontManager.updateFonts(pGLState);
//调用mDrawHandlers中注册的所有需要绘制的IDrawHandler的onDraw方法
this.onUpdateDrawHandlers(pGLState, this.mCamera);
//逐层调用Scene中IEntity的onDraw方法
this.onDrawScene(pGLState, this.mCamera);
engineLock.notifyCanUpdate();
} finally {
engineLock.unlock();
}
}
业务线程:Engine的初始化函数中启动业务执行线程UpdateThread,为注册到引擎中、或注册到引擎包含的实体中的IUpdateHandler接口执行onUpdate()方法,完成业务的更新操作。
UpdateThread中主要方法:
@Override
public void run() {
android.os.Process.setThreadPriority(this.mEngine.getEngineOptions().getUpdateThreadPriority());
try {
while(true) {
this.mRunnableHandler.onUpdate(0);
this.mEngine.onTickUpdate();
}
} catch (final InterruptedException e) {
if(BuildConfig.DEBUG) {
Debug.d(this.getClass().getSimpleName() + " interrupted. Don't worry - this " + e.getClass().getSimpleName() + " is most likely expected!", e);
}
this.interrupt();
}
}
Engine中的主要方法:
void onTickUpdate() throws InterruptedException {
//如果引擎正在运行,更新所有IUpdateHandler,否则Thread.sleep(16);什么也不做
if(this.mRunning) {
//从上传更新已经度过的时间(毫秒)
final long secondsElapsed = this.getNanosecondsElapsed();
this.mEngineLock.lock();
try {
//如果引擎已经被摧毁,抛出EngineDestroyedException异常
this.throwOnDestroyed();
//更新业务
this.onUpdate(secondsElapsed);
//如果引擎已经被摧毁,抛出EngineDestroyedException异常
this.throwOnDestroyed();
this.mEngineLock.notifyCanDraw();
this.mEngineLock.waitUntilCanUpdate();
} finally {
this.mEngineLock.unlock();
}
} else {
this.mEngineLock.lock();
try {
this.throwOnDestroyed();
this.mEngineLock.notifyCanDraw();
this.mEngineLock.waitUntilCanUpdate();
} finally {
this.mEngineLock.unlock();
}
Thread.sleep(16);
}
}
public void onUpdate(final long pNanosecondsElapsed) throws InterruptedException {
final float pSecondsElapsed = pNanosecondsElapsed * TimeConstants.SECONDS_PER_NANOSECOND;
this.mSecondsElapsedTotal += pSecondsElapsed;
this.mLastTick += pNanosecondsElapsed;
//更新触摸事件控制
this.mTouchController.onUpdate(pSecondsElapsed);
//更新注册的IUpdateHandler
this.onUpdateUpdateHandlers(pSecondsElapsed);
//更新屏幕
this.onUpdateScene(pSecondsElapsed);
}
Entity中的主要方法:
@Override
public final void onUpdate(final float pSecondsElapsed) {
if(!this.mIgnoreUpdate) {
this.onManagedUpdate(pSecondsElapsed);
}
}
/**
* 对实体的onUpdate方法的实际处理函数
*
* @param pSecondsElapsed 间隔秒数
*/
protected void onManagedUpdate(final float pSecondsElapsed) {
//本身注册的实体修改器的onUpdate
if(this.mEntityModifiers != null) {
this.mEntityModifiers.onUpdate(pSecondsElapsed);
}
//本身注册IUpdateHandler对象的onUpdate
if(this.mUpdateHandlers != null) {
this.mUpdateHandlers.onUpdate(pSecondsElapsed);
}
//调用子实体的onUpdate方法
if((this.mChildren != null) && !this.mChildrenIgnoreUpdate) {
final SmartList<IEntity> entities = this.mChildren;
final int entityCount = entities.size();
for(int i = 0; i < entityCount; i++) {
entities.get(i).onUpdate(pSecondsElapsed);
}
}
}
andEngine继承关系: