一、安卓工程下的設置啓動activity爲src下面的AppActivity,啓動調用的onCreate並無作過多的事情,只是調用了父類Cocos2dxActivity的onCreate。AppActivity代碼以下:
import org.cocos2dx.lib.Cocos2dxActivity;
public class AppActivity extends Cocos2dxActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
}
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initFMOD(); //加載聲音庫
try {
Class.forName("android.os.AsyncTask");
} catch (Throwable ignor) {
ignor.printStackTrace();
}
sContext = this;
PSNetwork.init(sContext); //初始化安卓網絡鏈接服務
if (Build.VERSION.SDK_INT >= 23) {
requestUserPermissions(); //系統的部分受權
}
mMacAddress = MacAddressUtil.getMacAddress(sContext);//獲取wifi的MAC地址
CocosPlayClient.init(this, false); //暫時無用
boolean isLoadOK = onLoadNativeLibraries(); //把工程中libs下面的so文件load進來,定義在AndroidManifest, meta-data標籤下,android.app.lib_name. 最終在包的data/data/com.XXX.XXX/lib下面
if (false == isLoadOK) {
return;
}
this.mHandler = new Cocos2dxHandler(this);//處理安卓的彈窗等
Cocos2dxHelper.init(this);
this.mGLContextAttrs = getGLContextAttrs();//獲取OpenGLEs的相關屬性
this.init(); //說明以下文
if (mVideoHelper == null) {
mVideoHelper = new Cocos2dxVideoHelper(this, mFrameLayout);
}
if (mWebViewHelper == null) {
mWebViewHelper = new Cocos2dxWebViewHelper(mFrameLayout);
}
if(mEditBoxHelper == null){
mEditBoxHelper = new Cocos2dxEditBoxHelper(mFrameLayout);
}
if (null == mScreenListener) {
mScreenListener = new ScreenListener(this);
mScreenListener.begin(this);
}
}
三、Cocos2dxActivity的init函數以下:
public void init() {
// FrameLayout
ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mFrameLayout = new ResizeLayout(this); //繼承自FrameLayout,當作是一塊畫布(canvas),其餘控件添加在上面
mFrameLayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Cocos2dxEditBox edittext = new Cocos2dxEditBox(this);
edittext.setLayoutParams(edittext_layout_params);//輸入框
// ...add to FrameLayout
mFrameLayout.addView(edittext);
// Cocos2dxGLSurfaceView
this.mGLSurfaceView = this.onCreateView();//建立遊戲的渲染,接受輸入事件的OpenGL類
// ...add to FrameLayout
mFrameLayout.addView(this.mGLSurfaceView);//添加到畫布上
// Switch to supported OpenGL (ARGB888) mode on emulator
if (isAndroidEmulator())
this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());//註冊自主實現的渲染器,內容以下
this.mGLSurfaceView.setCocos2dxEditText(edittext);//輸入框
this.onCreateFrameLayout();
// Set framelayout as the content view
setContentView(mFrameLayout);//設置這個Activity的顯示界面
}
四、Cocos2dxRenderer,cocos2dx的渲染器,繼承自android.opengl.GLSurfaceView.Renderer,當3中的GLSurfaceView被建立的時候會調用render的onSurfaceCreated()方法; 當GLSurfaceView大小或者橫豎屏發生變化的時候調用render的onSurfaceChanged()方法; 當系統每一次從新畫GLSurfaceView的時候,調用onDrawFrame()方法。因此Cocos2dxRender對這三個方法進行了重寫。
@Override
public void onSurfaceCreated(final GL10 GL10, final EGLConfig EGLConfig) {
Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);//此處調用了一個定義爲native的函數,設置glview等,經過jni來訪問c++實現的方法,接口實如今cocos/platform/android/javaactivity-android.cpp裏面,下面的5會繼續講
this.mLastTickInNanoSeconds = System.nanoTime();
mNativeInitCompleted = true;
try{
Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
activity.onSurfaceCreated(this, GL10, EGLConfig);
}catch( Throwable e ){
e.printStackTrace();
}
}
@Override
public void onDrawFrame(final GL10 gl) { //系統自動每秒鐘調用60次這個函數
/*
* No need to use algorithm in default(60 FPS) situation, since
* onDrawFrame() was called by system 60 times per second by default.
*/
if( true == mIsPaused ){
return;
}
if( mDelayResumeCount <= DELAY_RESUME_COUNT ){
mDelayResumeCount = mDelayResumeCount + 1;
if( mDelayResumeCount == DELAY_RESUME_COUNT ){
Cocos2dxRenderer.nativeOnResume();
try{
Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
activity.nativeResume();
}catch( Throwable e ){
e.printStackTrace();
}
}
return;
}
if (sAnimationInterval <= 1.0 / 60 * Cocos2dxRenderer.NANOSECONDSPERSECOND) {
Cocos2dxRenderer.nativeRender(); //大於等於每秒60幀則不通過算法處理,直接執行nativeRender,將在6中有說明
} else {
final long now = System.nanoTime();
final long interval = now - this.mLastTickInNanoSeconds;
if (interval < Cocos2dxRenderer.sAnimationInterval) { //按照設置的幀數,若是沒有到時間,則sleep到相應的時間
try {
Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval)
/ Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
} catch (final Exception e) {
}
}
/*
* Render time MUST be counted in, or the FPS will slower than
* appointed.
*/
this.mLastTickInNanoSeconds = System.nanoTime();
Cocos2dxRenderer.nativeRender();
}
try{
Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
activity.onDrawFrame(this, gl);
}catch( Throwable e ){
e.printStackTrace();
}
}
@Override
public void onSurfaceChanged(final GL10 GL10, final int width,
final int height) {
Cocos2dxRenderer.nativeOnSurfaceChanged(width, height);
try{
Cocos2dxActivity activity = (Cocos2dxActivity) Cocos2dxActivity.getContext();
activity.onSurfaceChanged(this, GL10, width, height);
}catch( Throwable e ){
e.printStackTrace();
}
}
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
{
auto director = cocos2d::Director::getInstance();
auto glview = director->getOpenGLView();
if (!glview)
{
glview = cocos2d::GLViewImpl::create("Android app");
glview->setFrameSize(w, h);
director->setOpenGLView(glview); //設置glview
//cocos_android_app_init(env, thiz);
cocos2d::Application::getInstance()->run(); //程序開始運行,android的Application實現放在CCApplication-android.cpp,run的代碼以下
}
else
{
cocos2d::GL::invalidateStateCache();
cocos2d::GLProgramCache::getInstance()->reloadDefaultGLPrograms();
cocos2d::DrawPrimitives::init();
cocos2d::VolatileTextureMgr::reloadAllTextures();
cocos2d::EventCustom recreatedEvent(EVENT_RENDERER_RECREATED);
director->getEventDispatcher()->dispatchEvent(&recreatedEvent);
director->setGLDefaultValues();
}
}
int Application::run()
{
// Initialize instance and cocos2d.
if (! applicationDidFinishLaunching()) //applicationDidFinishLanunching在本身的Classes/AppDelegate進行重寫,遊戲已經啓動
{
return 0;
}
return -1;
}
bool AppDelegate::applicationDidDinishLaunching()
{
......
director->setOpenGLView(glview);
director->setAnimationInterval(1/30.f); //設置幀數,會調用Application-android的setAnimationInterval,再經過JniHelper調用Cocos2dxRenderer中的setAnimationInterval
director->runWithScene(scene); //
return true
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env) {
cocos2d::Director::getInstance()->mainLoop(); //進入遊戲的主循環,Director的mainLoop,事件的分發,渲染,內存池的管理
}