cocos2d-x游戏开发(四)游戏主循环

前端之家收集整理的这篇文章主要介绍了cocos2d-x游戏开发(四)游戏主循环前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

欢迎转载:http://blog.csdn.net/fylz1125/article/details/8518737


终于抽时间把这个游戏写完了。由于没有自拍神器,所以把它移植到了Android上,用我的戴妃跑的很欢啊。自此,我算是完成了一个功能比较完善的游戏了。

麻雀虽小,五脏俱全,该有的都有,不该有的估计也有,嘿嘿。这几天把写这个游戏的经历和学习过程整理一下,多写几篇博客,就当做记笔记了。


首先还是就我个人的理解,讲讲游戏引擎的处理流程。

其实游戏逻辑简单化就是一个死循环,如下:

  1. @H_301_47@
  2. boolgame_is_running=true;@H_301_47@
  3. @H_301_47@
  4. while(game_is_running){@H_301_47@
  5. update_game();@H_301_47@
  6. display_game();@H_301_47@
  7. }@H_301_47@

我们所看到的游戏画面,游戏音乐,以及一些触控,输入等。在逻辑上就是这么一个死循环。这个循环一直在跑,期间会处理一些列的事件,简化之就是上面的两个函数

cocos2d-x引擎也是如此,所有的逻辑都是在这个主循环下实现的。下面看看cocos2dx在各平台上的主循环实现。


1.Win

看它的main.cpp

?
    #include"main.h"@H_301_47@
  1. #include"../Classes/AppDelegate.h"@H_301_47@
  2. #include"CCEGLView.h"@H_301_47@
  3. @H_301_47@
  4. USING_NS_CC;@H_301_47@
  5. intAPIENTRY_tWinMain(HINSTANCEhInstance,@H_301_47@
  6. HINSTANCEhPrevInstance,@H_301_47@
  7. LPTSTRlpCmdLine,87); font-weight:bold; background-color:inherit">intnCmdShow)@H_301_47@
  8. {@H_301_47@
  9. UNREFERENCED_PARAMETER(hPrevInstance);@H_301_47@
  10. UNREFERENCED_PARAMETER(lpCmdLine);@H_301_47@
  11. //createtheapplicationinstance@H_301_47@
  12. AppDelegateapp;@H_301_47@
  13. CCEGLView*eglView=CCEGLView::sharedOpenGLView();@H_301_47@
  14. eglView->setFrameSize(2048,1536);@H_301_47@
  15. //Theresolutionofipad3isverylarge.Ingeneral,PC'sresolutionissmallerthanit.@H_301_47@
  16. //Soweneedtoinvoke'setFrameZoomFactor'(onlyvalidondesktop(win32,mac,linux))tomakethewindowsmaller.@H_301_47@
  17. eglView->setFrameZoomFactor(0.4f);@H_301_47@
  18. returnCCApplication::sharedApplication()->run();//注意这里@H_301_47@
  19. }@H_301_47@

前面都不要关心,只是用来传递OpenGL窗口的,关键是最后一句,CCApplication::sharedApplication()->run()。看这个run函数

?
    intCCApplication::run()@H_301_47@
  1. {@H_301_47@
  2. PVRFrameEnableControlWindow(false);@H_301_47@
  3. //Mainmessageloop:@H_301_47@
  4. MSGmsg;@H_301_47@
  5. LARGE_INTEGERnFreq;@H_301_47@
  6. LARGE_INTEGERnLast;@H_301_47@
  7. LARGE_INTEGERnNow;@H_301_47@
  8. QueryPerformanceFrequency(&nFreq);@H_301_47@
  9. QueryPerformanceCounter(&nLast);@H_301_47@
  10. //Initializeinstanceandcocos2d.@H_301_47@
  11. if(!applicationDidFinishLaunching())@H_301_47@
  12. return0;@H_301_47@
  13. }@H_301_47@
  14. CCEGLView*pMainWnd=CCEGLView::sharedOpenGLView();@H_301_47@
  15. pMainWnd->centerWindow();@H_301_47@
  16. ShowWindow(pMainWnd->getHWnd(),SW_SHOW);@H_301_47@
  17. while(1)//注意这里,主循环来了@H_301_47@
  18. if(!PeekMessage(&msg,NULL,PM_REMOVE))@H_301_47@
  19. //Getcurrenttimetick.@H_301_47@
  20. QueryPerformanceCounter(&nNow);@H_301_47@
  21. //Ifit'sthetimetodrawnextframe,drawit,elsesleepawhile.@H_301_47@
  22. if(nNow.QuadPart-nLast.QuadPart>m_nAnimationInterval.QuadPart)@H_301_47@
  23. nLast.QuadPart=nNow.QuadPart;@H_301_47@
  24. CCDirector::sharedDirector()->mainLoop();//看看这是神马@H_301_47@
  25. else@H_301_47@
  26. Sleep(0);@H_301_47@
  27. continue;@H_301_47@
  28. if(WM_QUIT==msg.message)@H_301_47@
  29. //Quitmessageloop.@H_301_47@
  30. break;@H_301_47@
  31. //Dealwithwindowsmessage.@H_301_47@
  32. if(!m_hAccelTable||!TranslateAccelerator(msg.hwnd,m_hAccelTable,&msg))@H_301_47@
  33. TranslateMessage(&msg);@H_301_47@
  34. DispatchMessage(&msg);@H_301_47@
  35. }@H_301_47@
  36. return(int)msg.wParam;@H_301_47@
  37. }@H_301_47@

不熟悉windows的童鞋估计都知道windows是消息驱动的。这个死循环就是用来处理windows的消息循环的,在其中处理了FPS逻辑,消息分发等。注意看其中红色标标注的
?
    CCDirector::sharedDirector()->mainLoop();@H_301_47@

这是神马东西啊!这个就是cocos2d-x的主循环了,由导演负责维护。从此就进入了cocos2d-x的世界,跟windows没有一毛钱关系了。


2.Android

Android平台的游戏是从一个Activity开始的。(话说好像Android的所有应用都是从Activity开始的吧)。

在引擎源码下有个目录是android的java代码,是模板代码,几乎所有的游戏都用这个,不怎么变。不信可以你可以看

YourCocos2dxDir/cocos2dx/platform/android/java这个目录,就是创建android工程的时候会去这个目录拷贝java代码作为模板。

来看看HelloCpp的代码

[java] ?
    packageorg.cocos2dx.hellocpp;@H_301_47@
  1. importorg.cocos2dx.lib.Cocos2dxActivity;@H_301_47@
  2. importandroid.os.Bundle;@H_301_47@
  3. publicclassHelloCppextendsCocos2dxActivity{@H_301_47@
  4. protectedvoidonCreate(BundlesavedInstanceState){@H_301_47@
  5. super.onCreate(savedInstanceState);@H_301_47@
  6. static{@H_301_47@
  7. System.loadLibrary("hellocpp");@H_301_47@
  8. }@H_301_47@

很简单,对吧。几行代码而已,这里说明了两个问题

1. Cocos2dxActivity才是核心的Activity。

2. 游戏的C++部分包括引擎部分,被编译成了动态链接库hellocpp。这里就是加载了hellocpp动态链接库。

这个动态链接库是在用NDK编译的时候生成的,就是libs/armeabi/libhellocpp.so。(扯远了)


还是来看看Cocos2dxActivity这个Activity。

?
    publicabstractclassCocos2dxActivityextendsActivityimplementsCocos2dxHelperListener{@H_301_47@
  1. //===========================================================@H_301_47@
  2. //Constants@H_301_47@
  3. privatestaticfinalStringTAG=Cocos2dxActivity.class.getSimpleName();@H_301_47@
  4. //Fields@H_301_47@
  5. privateCocos2dxGLSurfaceViewmGLSurfaceView;//注意这个SurfaceView@H_301_47@
  6. privateCocos2dxHandlermHandler;@H_301_47@
  7. //===========================================================@H_301_47@
  8. //Constructors@H_301_47@
  9. @Override@H_301_47@
  10. protectedvoidonCreate(finalBundlesavedInstanceState){@H_301_47@
  11. super.onCreate(savedInstanceState);@H_301_47@
  12. this.mHandler=newCocos2dxHandler(this);@H_301_47@
  13. this.init();@H_301_47@
  14. Cocos2dxHelper.init(this,this);@H_301_47@
  15. //Getter&Setter@H_301_47@
  16. //Methodsfor/fromSuperClass/Interfaces@H_301_47@
  17. @Override@H_301_47@
  18. protectedvoidonResume(){@H_301_47@
  19. super.onResume();@H_301_47@
  20. Cocos2dxHelper.onResume();@H_301_47@
  21. this.mGLSurfaceView.onResume();@H_301_47@
  22. protectedvoidonPause(){@H_301_47@
  23. super.onPause();@H_301_47@
  24. Cocos2dxHelper.onPause();@H_301_47@
  25. this.mGLSurfaceView.onPause();@H_301_47@
  26. publicvoidshowDialog(finalStringpTitle,finalStringpMessage){@H_301_47@
  27. Messagemsg=newMessage();@H_301_47@
  28. msg.what=Cocos2dxHandler.HANDLER_SHOW_DIALOG;@H_301_47@
  29. msg.obj=newCocos2dxHandler.DialogMessage(pTitle,pMessage);@H_301_47@
  30. this.mHandler.sendMessage(msg);@H_301_47@
  31. publicvoidshowEditTextDialog(finalStringpTitle,finalStringpContent,finalintpInputMode,finalintpInputFlag,finalintpReturnType,finalintpMaxLength){@H_301_47@
  32. msg.what=Cocos2dxHandler.HANDLER_SHOW_EDITBox_DIALOG;@H_301_47@
  33. msg.obj=newCocos2dxHandler.EditBoxMessage(pTitle,pContent,pInputMode,pInputFlag,pReturnType,pMaxLength);@H_301_47@
  34. publicvoidrunOnGLThread(finalRunnablepRunnable){@H_301_47@
  35. this.mGLSurfaceView.queueEvent(pRunnable);@H_301_47@
  36. //Methods@H_301_47@
  37. publicvoidinit(){@H_301_47@
  38. //FrameLayout@H_301_47@
  39. ViewGroup.LayoutParamsframelayout_params=@H_301_47@
  40. newViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,153); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> ViewGroup.LayoutParams.FILL_PARENT);@H_301_47@
  41. FrameLayoutframelayout=newFrameLayout(this);//帧布局,可一层一层覆盖@H_301_47@
  42. framelayout.setLayoutParams(framelayout_params);@H_301_47@
  43. //Cocos2dxEditTextlayout@H_301_47@
  44. ViewGroup.LayoutParamsedittext_layout_params=@H_301_47@
  45. newViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,248)"> ViewGroup.LayoutParams.WRAP_CONTENT);@H_301_47@
  46. Cocos2dxEditTextedittext=newCocos2dxEditText(this);@H_301_47@
  47. edittext.setLayoutParams(edittext_layout_params);@H_301_47@
  48. //...addtoFrameLayout@H_301_47@
  49. framelayout.addView(edittext);@H_301_47@
  50. //Cocos2dxGLSurfaceView@H_301_47@
  51. this.mGLSurfaceView=this.onCreateView();@H_301_47@
  52. framelayout.addView(this.mGLSurfaceView);//添加GLSurfaceView@H_301_47@
  53. this.mGLSurfaceView.setCocos2dxRenderer(newCocos2dxRenderer());//意这行,一个渲染器@H_301_47@
  54. this.mGLSurfaceView.setCocos2dxEditText(edittext);@H_301_47@
  55. //Setframelayoutasthecontentview@H_301_47@
  56. setContentView(framelayout);@H_301_47@
  57. publicCocos2dxGLSurfaceViewonCreateView(){@H_301_47@
  58. returnnewCocos2dxGLSurfaceView(this);@H_301_47@
  59. //InnerandAnonymousClasses@H_301_47@
  60. }@H_301_47@

代码很多,呵呵。其实核心就是那个mGLSurfaceView和它的渲染器new Cocos2dxRenderer()。在Android上,OpenGL的渲染是由一个GLSurfaceView和其渲染器Render组成。GLSurfaceView显示界面,Render渲染更新。这个Render其实是一个渲染线程,不停再跑,由框架层维护。这里不多讲。

来看这个Cocos2dxRenderer

?
    packageorg.cocos2dx.lib;@H_301_47@
  1. importjavax.microedition.khronos.egl.EGLConfig;@H_301_47@
  2. importjavax.microedition.khronos.opengles.GL10;@H_301_47@
  3. importandroid.opengl.GLSurfaceView;@H_301_47@
  4. publicclassCocos2dxRendererimplementsGLSurfaceView.Renderer{@H_301_47@
  5. //Constants@H_301_47@
  6. privatefinalstaticlongNANOSECONDSPERSECOND=1000000000L;@H_301_47@
  7. privatefinalstaticlongNANOSECONDSPERMICROSECOND=1000000;@H_301_47@
  8. privatestaticlongsAnimationInterval=(long)(1.0/60*Cocos2dxRenderer.NANOSECONDSPERSECOND);@H_301_47@
  9. privatelongmLastTickInNanoSeconds;@H_301_47@
  10. privateintmScreenWidth;@H_301_47@
  11. privateintmScreenHeight;@H_301_47@
  12. //Constructors@H_301_47@
  13. publicstaticvoidsetAnimationInterval(finaldoublepAnimationInterval){@H_301_47@
  14. Cocos2dxRenderer.sAnimationInterval=(long)(pAnimationInterval*Cocos2dxRenderer.NANOSECONDSPERSECOND);@H_301_47@
  15. publicvoidsetScreenWidthAndHeight(finalintpSurfaceWidth,finalintpSurfaceHeight){@H_301_47@
  16. this.mScreenWidth=pSurfaceWidth;@H_301_47@
  17. this.mScreenHeight=pSurfaceHeight;@H_301_47@
  18. //Methodsfor/fromSuperClass/Interfaces@H_301_47@
  19. @Override//①注意这里@H_301_47@
  20. publicvoidonSurfaceCreated(finalGL10pGL10,finalEGLConfigpEGLConfig){@H_301_47@
  21. Cocos2dxRenderer.nativeInit(this.mScreenWidth,this.mScreenHeight);//②初始化窗口@H_301_47@
  22. this.mLastTickInNanoSeconds=System.nanoTime();@H_301_47@
  23. publicvoidonSurfaceChanged(finalGL10pGL10,finalintpWidth,finalintpHeight){@H_301_47@
  24. //③注意这里@H_301_47@
  25. publicvoidonDrawFrame(finalGL10gl){@H_301_47@
  26. /*@H_301_47@
  27. *FPScontrollingalgorithmisnotaccurate,anditwillslowdownFPS@H_301_47@
  28. *onsomedevices.SocommentFPScontrollingcode.@H_301_47@
  29. */@H_301_47@
  30. /*@H_301_47@
  31. finallongnowInNanoSeconds=System.nanoTime();@H_301_47@
  32. finallonginterval=nowInNanoSeconds-this.mLastTickInNanoSeconds;@H_301_47@
  33. */@H_301_47@
  34. //shouldrenderaframewhenonDrawFrame()iscalledorthereisa@H_301_47@
  35. //"ghost"@H_301_47@
  36. Cocos2dxRenderer.nativeRender();//④特别注意这个@H_301_47@
  37. //fpscontrolling@H_301_47@
  38. if(interval<Cocos2dxRenderer.sAnimationInterval){@H_301_47@
  39. try{@H_301_47@
  40. //becausewerenderitbefore,soweshouldsleeptwicetimeinterval@H_301_47@
  41. Thread.sleep((Cocos2dxRenderer.sAnimationInterval-interval)/Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);@H_301_47@
  42. }catch(finalExceptione){@H_301_47@
  43. }@H_301_47@
  44. }@H_301_47@
  45. @H_301_47@
  46. this.mLastTickInNanoSeconds=nowInNanoSeconds;@H_301_47@
  47. //Methods@H_301_47@
  48. privatestaticnativevoidnativeTouchesBegin(finalintpID,finalfloatpX,finalfloatpY);@H_301_47@
  49. privatestaticnativevoidnativeTouchesEnd(finalintpID,finalfloatpY);@H_301_47@
  50. privatestaticnativevoidnativeTouchesMove(finalint[]pIDs,finalfloat[]pXs,finalfloat[]pYs);@H_301_47@
  51. privatestaticnativevoidnativeTouchesCancel(finalint[]pIDs,finalfloat[]pYs);@H_301_47@
  52. privatestaticnativebooleannativeKeyDown(finalintpKeyCode);@H_301_47@
  53. privatestaticnativevoidnativeRender();@H_301_47@
  54. privatestaticnativevoidnativeInit(finalintpWidth,finalintpHeight);@H_301_47@
  55. privatestaticnativevoidnativeOnPause();@H_301_47@
  56. privatestaticnativevoidnativeOnResume();@H_301_47@
  57. publicvoidhandleActionDown(finalintpID,finalfloatpY){@H_301_47@
  58. Cocos2dxRenderer.nativeTouchesBegin(pID,pX,pY);@H_301_47@
  59. publicvoidhandleActionUp(finalintpID,153); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> Cocos2dxRenderer.nativeTouchesEnd(pID,248)"> publicvoidhandleActionCancel(finalint[]pIDs,finalfloat[]pYs){@H_301_47@
  60. Cocos2dxRenderer.nativeTouchesCancel(pIDs,pXs,pYs);@H_301_47@
  61. publicvoidhandleActionMove(finalint[]pIDs,153); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> Cocos2dxRenderer.nativeTouchesMove(pIDs,248)"> publicvoidhandleKeyDown(finalintpKeyCode){@H_301_47@
  62. Cocos2dxRenderer.nativeKeyDown(pKeyCode);@H_301_47@
  63. publicvoidhandleOnPause(){@H_301_47@
  64. Cocos2dxRenderer.nativeOnPause();@H_301_47@
  65. publicvoidhandleOnResume(){@H_301_47@
  66. Cocos2dxRenderer.nativeOnResume();@H_301_47@
  67. privatestaticnativevoidnativeInsertText(finalStringpText);@H_301_47@
  68. privatestaticnativevoidnativeDeleteBackward();@H_301_47@
  69. privatestaticnativeStringnativeGetContentText();@H_301_47@
  70. publicvoidhandleInsertText(finalStringpText){@H_301_47@
  71. Cocos2dxRenderer.nativeInsertText(pText);@H_301_47@
  72. publicvoidhandleDeleteBackward(){@H_301_47@
  73. Cocos2dxRenderer.nativeDeleteBackward();@H_301_47@
  74. publicStringgetContentText(){@H_301_47@
  75. returnCocos2dxRenderer.nativeGetContentText();@H_301_47@
  76. }@H_301_47@

代码很多,一副貌似很复杂的样子。其实脉络很清晰的,我们只看脉络,不考虑细节哈。我们顺藤摸瓜来...

首先要知道GLSurfaceView的渲染器必须实现GLSurfaceView.Renderer接口。就是上面的三个Override方法

onSurfaceCreated在窗口建立的时候调用,onSurfaceChanged在窗口建立和大小变化是调用,onDrawFrame这个方法就跟普通View的Ondraw方法一样,窗口建立初始化完成后渲染线程不停的调这个方法。这些都是框架决定的,就是这个样子。下面分析下代码几处标记的地方:

标记,窗口建立,这个时候要进行初始化。这个时候它调用了一个native函数,就是标记。看到这个函数形式是不是能想到什么呢,等下再说。

标记,前面说了,这个函数会被渲染线程不停调用像不像主循环的死循环啊)。然后里面有个很牛擦的函数

这又是一个native的函数,呵呵。

native的代码是神马啊,就是C++啊。知之为知之,不知谷歌之。

既然是java调用C++,那就是jni调用了。

我们来看看jni/hellocpp/下的main.cpp

?
    #include"AppDelegate.h"@H_301_47@
  1. #include"platform/android/jni/JniHelper.h"@H_301_47@
  2. #include<jni.h>@H_301_47@
  3. #include<android/log.h>@H_301_47@
  4. #include"HelloWorldScene.h"@H_301_47@
  5. #defineLOG_TAG"main"@H_301_47@
  6. #defineLOGD(...)__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)@H_301_47@
  7. usingnamespacecocos2d;@H_301_47@
  8. extern"C"@H_301_47@
  9. jintJNI_OnLoad(JavaVM*vm,void*reserved)@H_301_47@
  10. JniHelper::setJavaVM(vm);@H_301_47@
  11. returnJNI_VERSION_1_4;@H_301_47@
  12. voidJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*env,jobjectthiz,jintw,jinth)@H_301_47@
  13. if(!CCDirector::sharedDirector()->getOpenGLView())@H_301_47@
  14. CCEGLView*view=CCEGLView::sharedOpenGLView();@H_301_47@
  15. view->setFrameSize(w,h);@H_301_47@
  16. CCLog("with%d,height%d",w,h);@H_301_47@
  17. AppDelegate*pAppDelegate=newAppDelegate();@H_301_47@
  18. CCApplication::sharedApplication()->run();//看这里⑤@H_301_47@
  19. else@H_301_47@
  20. ccDrawInit();@H_301_47@
  21. ccGLInvalidateStateCache();@H_301_47@
  22. CCShaderCache::sharedShaderCache()->reloadDefaultShaders();@H_301_47@
  23. CCTextureCache::reloadAllTextures();@H_301_47@
  24. CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND,NULL);@H_301_47@
  25. CCDirector::sharedDirector()->setGLDefaultValues();@H_301_47@
  26. }@H_301_47@

根据Jni的命名规则,那个标注的nativeInit方法就是上面红色一长串(呵呵)。窗口建立起来后调用nativeInit方法,就是调用这个C++的实现。这里做了窗口的初始化处理。

看标注,你以为这个run函数就进入主循环了么,呵呵

看这个run

?
    <spanstyle="font-size:18px;">//Initializeinstanceandcocos2d.@H_301_47@
  1. if(!applicationDidFinishLaunching())@H_301_47@
  2. return0;@H_301_47@
  3. return-1;@H_301_47@
  4. }</span>@H_301_47@

我们看到了神马!实质上就调了一下applicationDidFinishLaunching,别的什么也没干。所以这里没有进入主循环。

现在再看。这个逻辑貌似就是主循环。

这个nativeRender()函数的实现在Yourcocos2dDir/cocos2dx/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp

?
    #include"text_input_node/CCIMEDispatcher.h"@H_301_47@
  1. #include"CCDirector.h"@H_301_47@
  2. #include"../CCApplication.h"@H_301_47@
  3. #include"platform/CCFileUtils.h"@H_301_47@
  4. #include"CCEventType.h"@H_301_47@
  5. #include"support/CCNotificationCenter.h"@H_301_47@
  6. #include"JniHelper.h"@H_301_47@
  7. #include<jni.h>@H_301_47@
  8. usingnamespacecocos2d;@H_301_47@
  9. extern"C"{@H_301_47@
  10. JNIEXPORTvoidJNICALLJava_org_cocos2dx_lib_<spanstyle="color:#ff0000;">Cocos2dxRenderer_nativeRender</span>(JNIEnv*env){@H_301_47@
  11. <spanstyle="color:#ff0000;">cocos2d::CCDirector::sharedDirector()->mainLoop();//看到木有,这是什么</span>@H_301_47@
  12. JNIEXPORTvoidJNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause(){@H_301_47@
  13. CCApplication::sharedApplication()->applicationDidEnterBackground();@H_301_47@
  14. CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_BACKGROUND,NULL);@H_301_47@
  15. JNIEXPORTvoidJNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume(){@H_301_47@
  16. if(CCDirector::sharedDirector()->getOpenGLView()){@H_301_47@
  17. CCApplication::sharedApplication()->applicationWillEnterForeground();@H_301_47@
  18. JNIEXPORTvoidJNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeInsertText(JNIEnv*env,jstringtext){@H_301_47@
  19. constchar*pszText=env->GetStringUTFChars(text,NULL);@H_301_47@
  20. cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(pszText,strlen(pszText));@H_301_47@
  21. env->ReleaseStringUTFChars(text,pszText);@H_301_47@
  22. JNIEXPORTvoidJNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeDeleteBackward(JNIEnv*env,jobjectthiz){@H_301_47@
  23. cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();@H_301_47@
  24. JNIEXPORTjstringJNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeGetContentText(){@H_301_47@
  25. JNIEnv*env=0;@H_301_47@
  26. if(JniHelper::getJavaVM()->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK||!env){@H_301_47@
  27. constchar*pszText=cocos2d::CCIMEDispatcher::sharedDispatcher()->getContentText();@H_301_47@
  28. returnenv->NewStringUTF(pszText);@H_301_47@
  29. }@H_301_47@

看上面标注,找到导演了,导演又开始主循环了。真是众里寻他千百度,那人却在灯火阑珊处啊。

到这里可以发现,Android上的主循环跟win上的不太一样,它不是一个简单的while就完了。它是由java的渲染线程发起的,通过不断调用render来驱动。


3.iOs

ios上面和Android上类似。看AppController.mm

?
    #import<UIKit/UIKit.h>@H_301_47@
  1. #import"AppController.h"@H_301_47@
  2. #import"cocos2d.h"@H_301_47@
  3. #import"EAGLView.h"@H_301_47@
  4. #import"AppDelegate.h"@H_301_47@
  5. #import"RootViewController.h"@H_301_47@
  6. @implementationAppController@H_301_47@
  7. @synthesizewindow;@H_301_47@
  8. @synthesizeviewController;@H_301_47@
  9. #pragmamark-@H_301_47@
  10. #pragmamarkApplicationlifecycle@H_301_47@
  11. //cocos2dapplicationinstance@H_301_47@
  12. staticAppDelegates_sharedApplication;@H_301_47@
  13. -(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{@H_301_47@
  14. //Overridepointforcustomizationafterapplicationlaunch.@H_301_47@
  15. //Addtheviewcontroller'sviewtothewindowanddisplay.@H_301_47@
  16. window=[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];@H_301_47@
  17. EAGLView*__glView=[EAGLViewviewWithFrame:[windowbounds]@H_301_47@
  18. pixelFormat:kEAGLColorFormatRGBA8@H_301_47@
  19. depthFormat:GL_DEPTH_COMPONENT16@H_301_47@
  20. preserveBackbuffer:NO@H_301_47@
  21. sharegroup:nil@H_301_47@
  22. multiSampling:NO@H_301_47@
  23. numberOfSamples:0];@H_301_47@
  24. //UseRootViewControllermanageEAGLView@H_301_47@
  25. viewController=[[RootViewControlleralloc]initWithNibName:nilbundle:nil];@H_301_47@
  26. viewController.wantsFullScreenLayout=YES;@H_301_47@
  27. viewController.view=__glView;@H_301_47@
  28. //SetRootViewControllertowindow@H_301_47@
  29. if([[UIDevicecurrentDevice].systemVersionfloatValue]<6.0)@H_301_47@
  30. //warning:addSubViewdoesn'tworkoniOS6@H_301_47@
  31. [windowaddSubview:viewController.view];@H_301_47@
  32. //usethismethodonios6@H_301_47@
  33. [windowsetRootViewController:viewController];@H_301_47@
  34. [windowmakeKeyAndVisible];@H_301_47@
  35. [[UIApplicationsharedApplication]setStatusBarHidden:YES];@H_301_47@
  36. <spanstyle="color:#ff0000;">cocos2d::CCApplication::sharedApplication()->run();</span>//<spanstyle="color:#ff0000;">看这里</span>@H_301_47@
  37. returnYES;@H_301_47@
  38. -(void)applicationWillResignActive:(UIApplication*)application{@H_301_47@
  39. Sentwhentheapplicationisabouttomovefromactivetoinactivestate.Thiscanoccurforcertaintypesoftemporaryinterruptions(suchasanincomingphonecallorSMSmessage)orwhentheuserquitstheapplicationanditbeginsthetransitiontothebackgroundstate.@H_301_47@
  40. UsethismethodtopauSEOngoingtasks,disabletimers,andthrottledownOpenGLESframerates.Gamesshouldusethismethodtopausethegame.@H_301_47@
  41. cocos2d::CCDirector::sharedDirector()->pause();@H_301_47@
  42. -(void)applicationDidBecomeActive:(UIApplication*)application{@H_301_47@
  43. Restartanytasksthatwerepaused(ornotyetstarted)whiletheapplicationwasinactive.IftheapplicationwasprevIoUslyinthebackground,optionallyrefreshtheuserinterface.@H_301_47@
  44. cocos2d::CCDirector::sharedDirector()->resume();@H_301_47@
  45. -(void)applicationDidEnterBackground:(UIApplication*)application{@H_301_47@
  46. Usethismethodtoreleasesharedresources,saveuserdata,invalidatetimers,andstoreenoughapplicationstateinformationtorestoreyourapplicationtoitscurrentstateincaseitisterminatedlater.@H_301_47@
  47. Ifyourapplicationsupportsbackgroundexecution,calledinsteadofapplicationWillTerminate:whentheuserquits.@H_301_47@
  48. cocos2d::CCApplication::sharedApplication()->applicationDidEnterBackground();@H_301_47@
  49. -(void)applicationWillEnterForeground:(UIApplication*)application{@H_301_47@
  50. Calledaspartoftransitionfromthebackgroundtotheinactivestate:hereyoucanundomanyofthechangesmadeonenteringthebackground.@H_301_47@
  51. cocos2d::CCApplication::sharedApplication()->applicationWillEnterForeground();@H_301_47@
  52. -(void)applicationWillTerminate:(UIApplication*)application{@H_301_47@
  53. Calledwhentheapplicationisabouttoterminate.@H_301_47@
  54. SeealsoapplicationDidEnterBackground:.@H_301_47@
  55. #pragmamark-@H_301_47@
  56. #pragmamarkMemorymanagement@H_301_47@
  57. -(void)applicationDidReceiveMemoryWarning:(UIApplication*)application{@H_301_47@
  58. Freeupasmuchmemoryaspossiblebypurgingcacheddataobjectsthatcanberecreated(orreloadedfromdisk)later.@H_301_47@
  59. cocos2d::CCDirector::sharedDirector()->purgeCachedData();@H_301_47@
  60. -(void)dealloc{@H_301_47@
  61. [superdealloc];@H_301_47@
  62. @end@H_301_47@

直接看标注,跟进run()

?
    if(applicationDidFinishLaunching())@H_301_47@
  1. <spanstyle="color:#ff0000;">[[CCDirectorCallersharedDirectorCaller]startMainLoop]</span>;@H_301_47@
  2. }</span>@H_301_47@
再跟标注的startMainLoop()

?
    -(void)startMainLoop@H_301_47@
  1. //CCDirector::setAnimationInterval()iscalled,weshouldinvalidateitfirst@H_301_47@
  2. [displayLinkinvalidate];@H_301_47@
  3. displayLink=nil;@H_301_47@
  4. NSLog(@"runloop!");@H_301_47@
  5. displayLink=[NSClassFromString(@"CADisplayLink")displayLinkWithTarget:selfselector:@selector(doCaller:)];//看这里@H_301_47@
  6. [displayLinksetFrameInterval:self.interval];@H_301_47@
  7. [displayLinkaddToRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];@H_301_47@
  8. }@H_301_47@
好了,看红色标注。这个貌似循环不起来啊,呵呵。

仔细看他加载的这个类CADisplayLink,就是这个东西循环起来的。这其实就是个定时器,默认每秒运行60次,其有个属性可以设置FPS。看后面有个回调函数doCaller,跟进

?
    -(void)doCaller:(id)sender@H_301_47@
  1. cocos2d::CCDirector::sharedDirector()->mainLoop(); }@H_301_47@
好了,终于又看到导演了。导演很忙,又开始主循环了。


一旦进入主循环,游戏就开始我们自己设计的游戏逻辑。

打字打的睡着了....不打了

猜你在找的Cocos2d-x相关文章