cocos2d-x CCDirector在Windows平台,Android平台,ios平台分析和用途-沈大海cocos2d-x教程10

时间:2023-02-07 22:42:11

在一个Cocos2d-x的应用入口中,当应用环境加载完成会回调以下方法

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director 初始化导演对象
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); //设定窗口绑定

    // enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
//     pDirector->enableRetinaDisplay(true);  //是否处理大图

    // turn on display FPS
    pDirector->setDisplayStats(true);             //是否显示fps 3个CCLabelTTF

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60); //设定每秒绘制次数

    // create a scene. it's an autorelease object
    CCScene *pScene = HelloWorld::scene();//获取Node ,实际上Scene是要绘制所有 Node集合的第一个,在他里面AddChild了其他node,我们可以理解为一个tree

    // run
    pDirector->runWithScene(pScene);   ///实际上是把这个node tree 放入渲染车间,由opengl来加工,每秒绘制60次到窗口。
    return true;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CCDirector导演类

  1。访问和改变场景

  2。应用核心loop

  3.  绑定和访问窗口

  4。处理自动回收对象

  5。处理事件消息转发

  6。初始化各种管理器

 7。处理在各Node的计划任务执行

 8.在平台窗口绘图和opengl之间转换坐标

以下是CCDirector::init方法

bool CCDirector::init(void)
{
    CCLOG("cocos2d: %s", cocos2dVersion());
   
    // scenes 场景相关
    m_pRunningScene = NULL;
    m_pNextScene = NULL;

    m_pNotificationNode = NULL;

    m_dOldAnimationInterval = m_dAnimationInterval = 1.0 / kDefaultFPS;   
    m_pobScenesStack = new CCArray();
    m_pobScenesStack->init();

    // Set default projection (3D)
    m_eProjection = kCCDirectorProjectionDefault;

    // projection delegate if "Custom" projection is used
    m_pProjectionDelegate = NULL;

    // FPS  相关
    m_fAccumDt = 0.0f;
    m_fFrameRate = 0.0f;
    m_pFPSLabel = NULL;
    m_pSPFLabel = NULL;
    m_pDrawsLabel = NULL;
    m_bDisplayStats = false;
    m_uTotalFrames = m_uFrames = 0;
    m_pszFPS = new char[10];
    m_pLastUpdate = new struct cc_timeval();

    // paused ? 暂停
    m_bPaused = false;
  
    // purge ?
    m_bPurgeDirecotorInNextLoop = false;

    m_obWinSizeInPixels = m_obWinSizeInPoints = CCSizeZero;   

    m_pobOpenGLView = NULL;

    m_fContentScaleFactor = 1.0f;
    m_bIsContentScaleSupported = false;

    // scheduler 计划任务
    m_pScheduler = new CCScheduler();
    // action manager 动作管理器
    m_pActionManager = new CCActionManager();
    m_pScheduler->scheduleUpdateForTarget(m_pActionManager, kCCPrioritySystem, false);
    // touchDispatcher 触摸消息分发器
    m_pTouchDispatcher = new CCTouchDispatcher();
    m_pTouchDispatcher->init();

    // KeypadDispatcher 按键消息分发器
    m_pKeypadDispatcher = new CCKeypadDispatcher();

    // Accelerometer  重力加速器
    m_pAccelerometer = new CCAccelerometer();

    // create autorelease pool 对象自动释放池管理器
    CCPoolManager::sharedPoolManager()->push();

    return true;
}

/////////////////////////////////////////////////////////////

在Windows ,ios,android等各种平台都会有对应的入口程序,在windows平台为main.cpp

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

#ifdef USE_WIN32_CONSOLE
    AllocConsole();
    freopen("CONIN$", "r", stdin);
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);
#endif

    // create the application instance
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();
    eglView->setFrameSize(480, 320);

    int ret = CCApplication::sharedApplication()->run();

#ifdef USE_WIN32_CONSOLE
    FreeConsole();
#endif

    return ret;
}

CCApplication::sharedApplication()->run(); 该命令实现如下:int CCApplication::run()
{
    PVRFrameEnableControlWindow(false);

    // Main message loop:
    MSG msg;
    LARGE_INTEGER nFreq;
    LARGE_INTEGER nLast;
    LARGE_INTEGER nNow;

    QueryPerformanceFrequency(&nFreq);
    QueryPerformanceCounter(&nLast);

    // Initialize instance and cocos2d.
    if (!applicationDidFinishLaunching())
    {
        return 0;
    }

    CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();
    pMainWnd->centerWindow();
    ShowWindow(pMainWnd->getHWnd(), SW_SHOW);

    while (1)
    {
        if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // Get current time tick.
            QueryPerformanceCounter(&nNow);

            // If it's the time to draw next frame, draw it, else sleep a while.
            if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)
            {
                nLast.QuadPart = nNow.QuadPart;
                CCDirector::sharedDirector()->mainLoop();
            }
            else
            {
                Sleep(0);
            }
            continue;
        }

        if (WM_QUIT == msg.message)
        {
            // Quit message loop.
            break;
        }

        // Deal with windows message.
        if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

    /////////////////////////////////////////

熟悉windows开发的同学都清楚,这个是windows 消息循环,在消息循环中实现了FPS逻辑,以及消息分发,分发后会由windows窗口类定义的消息处理函数来完成,消息处理函数在哪里呢?

CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();
    pMainWnd->centerWindow();

可见在CCEGLView定义了窗口和窗口处理,看下源代码:

bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
{
    bool bRet = false;
    do
    {
        CC_BREAK_IF(m_hWnd);

        HINSTANCE hInstance = GetModuleHandle( NULL );
        WNDCLASS  wc;        // Windows Class Structure   定义窗口类

        // Redraw On Size, And Own DC For Window.
        wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; //窗口样式,如果你想让windows 上的窗口没有标题栏,改这里呀。  
        wc.lpfnWndProc    = _WindowProc;                    // WndProc Handles Messages   这个就是windows平台的消息处理函数,让我们下面看看_WindowProc源代码
        wc.cbClsExtra     = 0;                              // No Extra Window Data
        wc.cbWndExtra     = 0;                                // No Extra Window Data
        wc.hInstance      = hInstance;                        // Set The Instance
        wc.hIcon          = LoadIcon( NULL, IDI_WINLOGO );    // Load The Default Icon
        wc.hCursor        = LoadCursor( NULL, IDC_ARROW );    // Load The Arrow Pointer
        wc.hbrBackground  = NULL;                           // No Background Required For GL
        wc.lpszMenuName   = m_menu;                         //
        wc.lpszClassName  = kWindowClassName;               // Set The Class Name

        CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());        //注册窗口类

        // center window position
        RECT rcDesktop;
        GetWindowRect(GetDesktopWindow(), &rcDesktop);

        WCHAR wszBuf[50] = {0};
        MultiByteToWideChar(CP_UTF8, 0, m_szViewName, -1, wszBuf, sizeof(wszBuf));

        // create window  创建窗口
        m_hWnd = CreateWindowEx(
            WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,    // Extended Style For The Window
            kWindowClassName,                                    // Class Name
            wszBuf,                                                // Window Title
            WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX,        // Defined Window Style
            0, 0,                                                // Window Position
            0,                                                  // Window Width
            0,                                                  // Window Height
            NULL,                                                // No Parent Window
            NULL,                                                // No Menu
            hInstance,                                            // Instance
            NULL );

        CC_BREAK_IF(! m_hWnd);

        resize(w, h);

        bRet = initGL();  //在窗口初始化opengl
        CC_BREAK_IF(!bRet);
       
        s_pMainWindow = this;
        bRet = true;
    } while (0);

    return bRet;
}

//////////////////////////////////////////////////////////////////////////////////////

static LRESULT CALLBACK _WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (s_pMainWindow && s_pMainWindow->getHWnd() == hWnd)
    {
        return s_pMainWindow->WindowProc(uMsg, wParam, lParam);
    }
    else
    {
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

/////////////////////////////////////////////////////////////////////////////////////////

这个全局函数定义在cocos2dx/plantform/win32/CCGLView.cpp,我们看到,实际上 cocos2d-x窗口的处理函数为WindowProc

看下代码:

LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    BOOL bProcessed = FALSE;

    switch (message)
    {
    case WM_LBUTTONDOWN:
        if (m_pDelegate && MK_LBUTTON == wParam)
        {
            POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
            CCPoint pt(point.x/CC_CONTENT_SCALE_FACTOR(), point.y/CC_CONTENT_SCALE_FACTOR());
            CCPoint tmp = ccp(pt.x, m_obScreenSize.height - pt.y);
            if (m_obViewPortRect.equals(CCRectZero) || m_obViewPortRect.containsPoint(tmp))
            {
                m_bCaptured = true;
                SetCapture(m_hWnd);
                int id = 0;
                pt.x *= m_windowTouchScaleX;
                pt.y *= m_windowTouchScaleY;
                handleTouchesBegin(1, &id, &pt.x, &pt.y);
            }
        }
        break;

    case WM_MOUSEMOVE:
        if (MK_LBUTTON == wParam && m_bCaptured)
        {
            POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
            CCPoint pt(point.x/CC_CONTENT_SCALE_FACTOR(), point.y/CC_CONTENT_SCALE_FACTOR());
            int id = 0;
            pt.x *= m_windowTouchScaleX;
            pt.y *= m_windowTouchScaleY;
            handleTouchesMove(1, &id, &pt.x, &pt.y);
        }
        break;

    case WM_LBUTTONUP:
        if (m_bCaptured)
        {
            POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
            CCPoint pt(point.x/CC_CONTENT_SCALE_FACTOR(), point.y/CC_CONTENT_SCALE_FACTOR());
            int id = 0;
            pt.x *= m_windowTouchScaleX;
            pt.y *= m_windowTouchScaleY;
            handleTouchesEnd(1, &id, &pt.x, &pt.y);

            ReleaseCapture();
            m_bCaptured = false;
        }
        break;
    case WM_SIZE:
        switch (wParam)
        {
        case SIZE_RESTORED:
            CCApplication::sharedApplication()->applicationWillEnterForeground();
            break;
        case SIZE_MINIMIZED:
            CCApplication::sharedApplication()->applicationDidEnterBackground();
            break;
        }
        break;
    case WM_KEYDOWN:
        if (wParam == VK_F1 || wParam == VK_F2)
        {
            CCDirector* pDirector = CCDirector::sharedDirector();
            if (GetKeyState(VK_LSHIFT) < 0 ||  GetKeyState(VK_RSHIFT) < 0 || GetKeyState(VK_SHIFT) < 0)
                pDirector->getKeypadDispatcher()->dispatchKeypadMSG(wParam == VK_F1 ? kTypeBackClicked : kTypeMenuClicked);
        }
        if ( m_lpfnAccelerometerKeyHook!=NULL )
        {
            (*m_lpfnAccelerometerKeyHook)( message,wParam,lParam );
        }
        break;
    case WM_KEYUP:
        if ( m_lpfnAccelerometerKeyHook!=NULL )
        {
            (*m_lpfnAccelerometerKeyHook)( message,wParam,lParam );
        }
        break;
    case WM_CHAR:
        {
            if (wParam < 0x20)
            {
                if (VK_BACK == wParam)
                {
                    CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
                }
                else if (VK_RETURN == wParam)
                {
                    CCIMEDispatcher::sharedDispatcher()->dispatchInsertText("\n", 1);
                }
                else if (VK_TAB == wParam)
                {
                    // tab input
                }
                else if (VK_ESCAPE == wParam)
                {
                    // ESC input
                    //CCDirector::sharedDirector()->end();
                }
            }
            else if (wParam < 128)
            {
                // ascii char
                CCIMEDispatcher::sharedDispatcher()->dispatchInsertText((const char *)&wParam, 1);
            }
            else
            {
                char szUtf8[8] = {0};
                int nLen = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)&wParam, 1, szUtf8, sizeof(szUtf8), NULL, NULL);
                CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(szUtf8, nLen);
            }
            if ( m_lpfnAccelerometerKeyHook!=NULL )
            {
                (*m_lpfnAccelerometerKeyHook)( message,wParam,lParam );
            }
        }
        break;
    case WM_PAINT:
        PAINTSTRUCT ps;
        BeginPaint(m_hWnd, &ps);
        EndPaint(m_hWnd, &ps);
        break;

    case WM_CLOSE:          ///把WM_CLOSE,WM_DESTROY这2个消息注释,看看效果,是不是不能关闭了
        //CCDirector::sharedDirector()->end();
        break;

    case WM_DESTROY:///把WM_CLOSE,WM_DESTROY这2个消息注释,看看效果,是不是不能关闭了,这里
        //destroyGL();
        //PostQuitMessage(0);
        break;

    default:
        if (m_wndproc)
        {
           
            m_wndproc(message, wParam, lParam, &bProcessed);
            if (bProcessed) break;
        }
        return DefWindowProc(m_hWnd, message, wParam, lParam);
    }

    if (m_wndproc && !bProcessed)
    {
        m_wndproc(message, wParam, lParam, &bProcessed);
    }
    return 0;
}

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////不知道你懂了没

关注blog.csdn.net/sdhjob @weibo.com/shunfengche

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

下面看Android平台

package org.cocos2dx.hellocpp;

import org.cocos2dx.lib.Cocos2dxActivity;

import android.os.Bundle;

public class HelloCpp extends Cocos2dxActivity{

 protected void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
 }
 
   static {
         System.loadLibrary("hellocpp");
    }
}
入口类貌似很简单,说明了2件事情,

1,Cocos2dxActivity必定是核心

2,Coco2d-x的引擎就是在hellocpp.so中集成的,并且这里一定跟Cocos2dxActivity有者千丝万屡的联系,元方,你认为呢?

看代码

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/****************************************************************************
package org.cocos2dx.lib;

import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener;   //处理从java到C以及从C到Java的调用

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Message;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener {
 private static final String TAG = Cocos2dxActivity.class.getSimpleName();

 private Cocos2dxGLSurfaceView mGLSurefaceView;       //窗口GLSurfaceView
 private Cocos2dxHandler mHandler;                                   //窗口View的handler用来接收android系统的回调

 protected void onCreate(final Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  this.init();

 Cocos2dxHelper.init(this, this);
 }

 protected void onResume() {
  super.onResume();

  Cocos2dxHelper.onResume();
  this.mGLSurefaceView.onResume();
 }

  protected void onPause() {
  super.onPause();

  Cocos2dxHelper.onPause();
  this.mGLSurefaceView.onPause();
 }

 public void showDialog(final String pTitle, final String pMessage) {
  Message msg = new Message();
  msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG;
  msg.obj = new Cocos2dxHandler.DialogMessage(pTitle, pMessage);
  this.mHandler.sendMessage(msg);
 }

 public void showEditTextDialog(final String pTitle, final String pContent, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) {
  Message msg = new Message();
  msg.what = Cocos2dxHandler.HANDLER_SHOW_EDITBOX_DIALOG;
  msg.obj = new Cocos2dxHandler.EditBoxMessage(pTitle, pContent, pInputMode, pInputFlag, pReturnType, pMaxLength);
  this.mHandler.sendMessage(msg);
 }
 public void runOnGLThread(final Runnable pRunnable) { //这里可以让java的线程运行在cocos2d-x的loop中
  this.mGLSurefaceView.queueEvent(pRunnable);
 }

     public void init() {
     // Init handler
     this.mHandler = new Cocos2dxHandler(this);   //处理从C++发送过来消息调用Adnroid FrameWork显示Dialg
            ViewGroup.LayoutParams framelayout_params =
            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                                       ViewGroup.LayoutParams.FILL_PARENT);
        FrameLayout framelayout = new FrameLayout(this);   //FrameLayout可以实现绝对定位绘图,还可以实现多层覆盖
        framelayout.setLayoutParams(framelayout_params);

        // Cocos2dxEditText layout
        ViewGroup.LayoutParams edittext_layout_params =
            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                                       ViewGroup.LayoutParams.WRAP_CONTENT);
        Cocos2dxEditText edittext = new Cocos2dxEditText(this);
        edittext.setLayoutParams(edittext_layout_params);

        // ...add to FrameLayout
        framelayout.addView(edittext);                 //添加一层编辑框

        // Cocos2dxGLSurfaceView
        this.mGLSurefaceView = this.onCreateGLSurfaceView();

        // ...add to FrameLayout
        framelayout.addView(mGLSurefaceView); //添加一层GLSurfaceView

        mGLSurefaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
        mGLSurefaceView.setCocos2dxEditText(edittext);

        // Set framelayout as the content view
  setContentView(framelayout);
    }
   
    public Cocos2dxGLSurfaceView onCreateGLSurfaceView() {
     return new Cocos2dxGLSurfaceView(this);
    }

 // ===========================================================
 // Inner and Anonymous Classes
 // ===========================================================
}

//////////////////////////////////////////////////////////////////////

 protected void onResume() {
  super.onResume();

  Cocos2dxHelper.onResume();
  this.mGLSurefaceView.onResume();
 }

  protected void onPause() {
  super.onPause();

  Cocos2dxHelper.onPause();
  this.mGLSurefaceView.onPause();
 }

可见mGLSurefaceView一定会把应用窗口状态的变化传递给CCDirector,看看如何传递的:

/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 ****************************************************************************/
package org.cocos2dx.lib;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.inputmethod.InputMethodManager;

public class Cocos2dxGLSurfaceView extends GLSurfaceView {
 // ===========================================================
 // Constants
 // ===========================================================

 private static final String TAG = Cocos2dxGLSurfaceView.class.getSimpleName();

 private final static int HANDLER_OPEN_IME_KEYBOARD = 2;
 private final static int HANDLER_CLOSE_IME_KEYBOARD = 3;

 // ===========================================================
 // Fields
 // ===========================================================

 // TODO Static handler -> Potential leak!
 private static Handler sHandler;

 private static Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;
 private static Cocos2dxTextInputWraper sCocos2dxTextInputWraper;

 private Cocos2dxRenderer mCocos2dxRenderer;
 private Cocos2dxEditText mCocos2dxEditText;

 // ===========================================================
 // Constructors
 // ===========================================================

 public Cocos2dxGLSurfaceView(final Context context) {
  super(context);

  this.setEGLContextClientVersion(2);

  this.initView();
 }

 public Cocos2dxGLSurfaceView(final Context context, final AttributeSet attrs) {
  super(context, attrs);

  this.setEGLContextClientVersion(2);

  this.initView();
 }

 protected void initView() {
  this.setFocusableInTouchMode(true);

  Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView = this;
  Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper = new Cocos2dxTextInputWraper(this);

  Cocos2dxGLSurfaceView.sHandler = new Handler() {
   @Override
   public void handleMessage(final Message msg) {
    switch (msg.what) {
     case HANDLER_OPEN_IME_KEYBOARD:
      if (null != Cocos2dxGLSurfaceView.this.mCocos2dxEditText && Cocos2dxGLSurfaceView.this.mCocos2dxEditText.requestFocus()) {
       Cocos2dxGLSurfaceView.this.mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
       Cocos2dxGLSurfaceView.this.mCocos2dxEditText.setText("");
       final String text = (String) msg.obj;
       Cocos2dxGLSurfaceView.this.mCocos2dxEditText.append(text);
       Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper.setOriginText(text);
       Cocos2dxGLSurfaceView.this.mCocos2dxEditText.addTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
       final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
       imm.showSoftInput(Cocos2dxGLSurfaceView.this.mCocos2dxEditText, 0);
       Log.d("GLSurfaceView", "showSoftInput");
      }
      break;

     case HANDLER_CLOSE_IME_KEYBOARD:
      if (null != Cocos2dxGLSurfaceView.this.mCocos2dxEditText) {
       Cocos2dxGLSurfaceView.this.mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
       final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
       imm.hideSoftInputFromWindow(Cocos2dxGLSurfaceView.this.mCocos2dxEditText.getWindowToken(), 0);
       Log.d("GLSurfaceView", "HideSoftInput");
      }
      break;
    }
   }
  };
 }

 // ===========================================================
 // Getter & Setter
 // ===========================================================

 public void setCocos2dxRenderer(final Cocos2dxRenderer renderer) {
  this.mCocos2dxRenderer = renderer;
  this.setRenderer(this.mCocos2dxRenderer);
 }

 private String getContentText() {
  return this.mCocos2dxRenderer.getContentText();
 }

 public Cocos2dxEditText getCocos2dxEditText() {
  return this.mCocos2dxEditText;
 }

 public void setCocos2dxEditText(final Cocos2dxEditText pCocos2dxEditText) {
  this.mCocos2dxEditText = pCocos2dxEditText;
  if (null != this.mCocos2dxEditText && null != Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper) {
   this.mCocos2dxEditText.setOnEditorActionListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
   this.mCocos2dxEditText.setCocos2dxGLSurfaceView(this);
   this.requestFocus();
  }
 }

 // ===========================================================
 // Methods for/from SuperClass/Interfaces
 // ===========================================================

 @Override
 public void onResume() {
  super.onResume();

  this.queueEvent(new Runnable() {
   @Override
   public void run() {
    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnResume();
   }
  });
 }

 @Override
 public void onPause() {
  this.queueEvent(new Runnable() {
   @Override
   public void run() {
    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnPause();
   }
  });

  super.onPause();
 }

 @Override
 public boolean onTouchEvent(final MotionEvent pMotionEvent) {
  // these data are used in ACTION_MOVE and ACTION_CANCEL
  final int pointerNumber = pMotionEvent.getPointerCount();
  final int[] ids = new int[pointerNumber];
  final float[] xs = new float[pointerNumber];
  final float[] ys = new float[pointerNumber];

  for (int i = 0; i < pointerNumber; i++) {
   ids[i] = pMotionEvent.getPointerId(i);
   xs[i] = pMotionEvent.getX(i);
   ys[i] = pMotionEvent.getY(i);
  }

  switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {
   case MotionEvent.ACTION_POINTER_DOWN:
    final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
    final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
    final float xPointerDown = pMotionEvent.getX(indexPointerDown);
    final float yPointerDown = pMotionEvent.getY(indexPointerDown);

    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown);
     }
    });
    break;

   case MotionEvent.ACTION_DOWN:
    // there are only one finger on the screen
    final int idDown = pMotionEvent.getPointerId(0);
    final float xDown = xs[0];
    final float yDown = ys[0];

    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idDown, xDown, yDown);
     }
    });
    break;

   case MotionEvent.ACTION_MOVE:
    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionMove(ids, xs, ys);
     }
    });
    break;

   case MotionEvent.ACTION_POINTER_UP:
    final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
    final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
    final float xPointerUp = pMotionEvent.getX(indexPointUp);
    final float yPointerUp = pMotionEvent.getY(indexPointUp);

    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp);
     }
    });
    break;

   case MotionEvent.ACTION_UP:
    // there are only one finger on the screen
    final int idUp = pMotionEvent.getPointerId(0);
    final float xUp = xs[0];
    final float yUp = ys[0];

    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idUp, xUp, yUp);
     }
    });
    break;

   case MotionEvent.ACTION_CANCEL:
    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel(ids, xs, ys);
     }
    });
    break;
  }

        /*
  if (BuildConfig.DEBUG) {
   Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent);
  }
  */
  return true;
 }

 /*
  * This function is called before Cocos2dxRenderer.nativeInit(), so the
  * width and height is correct.
  */
 @Override
 protected void onSizeChanged(final int pNewSurfaceWidth, final int pNewSurfaceHeight, final int pOldSurfaceWidth, final int pOldSurfaceHeight) {
  if(!this.isInEditMode()) {
   this.mCocos2dxRenderer.setScreenWidthAndHeight(pNewSurfaceWidth, pNewSurfaceHeight);
  }
 }

 @Override
 public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
  switch (pKeyCode) {
   case KeyEvent.KEYCODE_BACK:
   case KeyEvent.KEYCODE_MENU:
    this.queueEvent(new Runnable() {
     @Override
     public void run() {
      Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);
     }
    });
    return true;
   default:
    return super.onKeyDown(pKeyCode, pKeyEvent);
  }
 }

 // ===========================================================
 // Methods
 // ===========================================================

 // ===========================================================
 // Inner and Anonymous Classes
 // ===========================================================

 public static void openIMEKeyboard() {
  final Message msg = new Message();
  msg.what = Cocos2dxGLSurfaceView.HANDLER_OPEN_IME_KEYBOARD;
  msg.obj = Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContentText();
  Cocos2dxGLSurfaceView.sHandler.sendMessage(msg);
 }

 public static void closeIMEKeyboard() {
  final Message msg = new Message();
  msg.what = Cocos2dxGLSurfaceView.HANDLER_CLOSE_IME_KEYBOARD;
  Cocos2dxGLSurfaceView.sHandler.sendMessage(msg);
 }

 public void insertText(final String pText) {
  this.queueEvent(new Runnable() {
   @Override
   public void run() {
    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleInsertText(pText);
   }
  });
 }

 public void deleteBackward() {
  this.queueEvent(new Runnable() {
   @Override
   public void run() {
    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleDeleteBackward();
   }
  });
 }

 private static void dumpMotionEvent(final MotionEvent event) {
  final String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
  final StringBuilder sb = new StringBuilder();
  final int action = event.getAction();
  final int actionCode = action & MotionEvent.ACTION_MASK;
  sb.append("event ACTION_").append(names[actionCode]);
  if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) {
   sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
   sb.append(")");
  }
  sb.append("[");
  for (int i = 0; i < event.getPointerCount(); i++) {
   sb.append("#").append(i);
   sb.append("(pid ").append(event.getPointerId(i));
   sb.append(")=").append((int) event.getX(i));
   sb.append(",").append((int) event.getY(i));
   if (i + 1 < event.getPointerCount()) {
    sb.append(";");
   }
  }
  sb.append("]");
  Log.d(Cocos2dxGLSurfaceView.TAG, sb.toString());
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////可见

无论是Activity的生命周期回调还是View的生命周期回调都给了Cocos2dxRenderer

/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 ****************************************************************************/
package org.cocos2dx.lib;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
 // ===========================================================
 // Constants
 // ===========================================================

 private final static long NANOSECONDSPERSECOND = 1000000000L;
 private final static long NANOSECONDSPERMICROSECOND = 1000000;

 private static long sAnimationInterval = (long) (1.0 / 60 * Cocos2dxRenderer.NANOSECONDSPERSECOND);

 // ===========================================================
 // Fields
 // ===========================================================

 private long mLastTickInNanoSeconds;
 private int mScreenWidth;
 private int mScreenHeight;

 // ===========================================================
 // Constructors
 // ===========================================================

 // ===========================================================
 // Getter & Setter
 // ===========================================================

 public static void setAnimationInterval(final double pAnimationInterval) {
  Cocos2dxRenderer.sAnimationInterval = (long) (pAnimationInterval * Cocos2dxRenderer.NANOSECONDSPERSECOND);
 }

 public void setScreenWidthAndHeight(final int pSurfaceWidth, final int pSurfaceHeight) {
  this.mScreenWidth = pSurfaceWidth;
  this.mScreenHeight = pSurfaceHeight;
 }

 // ===========================================================
 // Methods for/from SuperClass/Interfaces
 // ===========================================================

 @Override
 public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {
  Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);
  this.mLastTickInNanoSeconds = System.nanoTime();
 }

 @Override
 public void onSurfaceChanged(final GL10 pGL10, final int pWidth, final int pHeight) {
 }

 @Override
 public void onDrawFrame(final GL10 gl) {
  final long nowInNanoSeconds = System.nanoTime();
  final long interval = nowInNanoSeconds - this.mLastTickInNanoSeconds;

  // should render a frame when onDrawFrame() is called or there is a
  // "ghost"
  Cocos2dxRenderer.nativeRender();

  // fps controlling
  if (interval < Cocos2dxRenderer.sAnimationInterval) {
   try {
    // because we render it before, so we should sleep twice time interval
    Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval) * 2 / Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
   } catch (final Exception e) {
   }
  }

  this.mLastTickInNanoSeconds = nowInNanoSeconds;
 }

 // ===========================================================
 // Methods
 // ===========================================================

 private static native void nativeTouchesBegin(final int pID, final float pX, final float pY);
 private static native void nativeTouchesEnd(final int pID, final float pX, final float pY);
 private static native void nativeTouchesMove(final int[] pIDs, final float[] pXs, final float[] pYs);
 private static native void nativeTouchesCancel(final int[] pIDs, final float[] pXs, final float[] pYs);
 private static native boolean nativeKeyDown(final int pKeyCode);
 private static native void nativeRender();
 private static native void nativeInit(final int pWidth, final int pHeight);
 private static native void nativeOnPause();
 private static native void nativeOnResume();

 public void handleActionDown(final int pID, final float pX, final float pY) {
  Cocos2dxRenderer.nativeTouchesBegin(pID, pX, pY);
 }

 public void handleActionUp(final int pID, final float pX, final float pY) {
  Cocos2dxRenderer.nativeTouchesEnd(pID, pX, pY);
 }

 public void handleActionCancel(final int[] pIDs, final float[] pXs, final float[] pYs) {
  Cocos2dxRenderer.nativeTouchesCancel(pIDs, pXs, pYs);
 }

 public void handleActionMove(final int[] pIDs, final float[] pXs, final float[] pYs) {
  Cocos2dxRenderer.nativeTouchesMove(pIDs, pXs, pYs);
 }

 public void handleKeyDown(final int pKeyCode) {
  Cocos2dxRenderer.nativeKeyDown(pKeyCode);
 }

 public void handleOnPause() {
  Cocos2dxRenderer.nativeOnPause();
 }

 public void handleOnResume() {
  Cocos2dxRenderer.nativeOnResume();
 }

 private static native void nativeInsertText(final String pText);
 private static native void nativeDeleteBackward();
 private static native String nativeGetContentText();

 public void handleInsertText(final String pText) {
  Cocos2dxRenderer.nativeInsertText(pText);
 }

 public void handleDeleteBackward() {
  Cocos2dxRenderer.nativeDeleteBackward();
 }

 public String getContentText() {
  return Cocos2dxRenderer.nativeGetContentText();
 }

 // ===========================================================
 // Inner and Anonymous Classes
 // ===========================================================
}

看到没----------------------------------------一堆native关键字----------------------------------------------------------

 

///////////JNI目录下的main.cpp

#include "AppDelegate.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>

#include "HelloWorldScene.h"

#define  LOG_TAG    "main"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

using namespace cocos2d;

extern "C"
{

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JniHelper::setJavaVM(vm);

    return JNI_VERSION_1_4;
}

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
{
    if (!CCDirector::sharedDirector()->getOpenGLView())
    {
        CCEGLView *view = CCEGLView::sharedOpenGLView();
        view->setFrameSize(w, h);

        AppDelegate *pAppDelegate = new AppDelegate();
        CCApplication::sharedApplication()->run();
    }
    else
    {
        ccDrawInit();
        ccGLInvalidateStateCache();
       
        CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
        CCTextureCache::reloadAllTextures();
        CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
        CCDirector::sharedDirector()->setGLDefaultValues();
    }
}

}

/////////////////////////////////////////////////////////////////////////////////////

所以在 Android平台窗口和 View是在java中Android FrameWork定义的,窗口和View的事件回掉基于Android FrameWork,只不过通过JNI传递到CCDirector,再由CCDirector分发到各个Node.

IOS平台也相差不多看代码:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 #import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
   
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  //定义自动释放池
    int retVal = UIApplicationMain(argc, argv, nil, @"AppController"); //定义消息循环和入口控制器AppController
    [pool release];
    return retVal;
}

/////////////////////////////////////看看这个入口控制器AppController
AppController.h

@class RootViewController;

@interface AppController : NSObject <UIAccelerometerDelegate, UIAlertViewDelegate, UITextFieldDelegate,UIApplicationDelegate> {
    UIWindow *window;          //window处理事件
    RootViewController    *viewController;//跟控制器,作为窗口View的容器
}

@end

/////////////////////////////////////////////////////////////////////////////AppController.mm

#import <UIKit/UIKit.h>
#import "AppController.h"
#import "cocos2d.h"
#import "EAGLView.h"
#import "AppDelegate.h"

#import "RootViewController.h"

@implementation AppController

#pragma mark -
#pragma mark Application lifecycle

// cocos2d application instance
static AppDelegate s_sharedApplication;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   
   
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
    EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
                                        pixelFormat: kEAGLColorFormatRGBA8
                                        depthFormat: GL_DEPTH_COMPONENT16
                                 preserveBackbuffer: NO
                                                                                 sharegroup:nil
                                                                          multiSampling:NO
                                                                    numberOfSamples:0];
   
    // Use RootViewController manage EAGLView 创建了一个EAGLView 添加到viewController
    viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    viewController.wantsFullScreenLayout = YES;
    viewController.view = __glView;

    // Set RootViewController to window
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // warning: addSubView doesn't work on iOS6
        [window addSubview: viewController.view];
    }
    else
    {
        // use this method on ios6
        [window setRootViewController:viewController];
    }
   
    [window makeKeyAndVisible];              //处理用户事件

    [[UIApplication sharedApplication] setStatusBarHidden: YES];
   
    cocos2d::CCApplication::sharedApplication()->run();  ///看到没,都要执行CCApplication::sharedApplication()->run(); 
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
       cocos2d::CCDirector::sharedDirector()->pause();
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
       cocos2d::CCDirector::sharedDirector()->resume();
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
       cocos2d::CCApplication::sharedApplication()->applicationDidEnterBackground();
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
       cocos2d::CCApplication::sharedApplication()->applicationWillEnterForeground();
}

- (void)applicationWillTerminate:(UIApplication *)application {
  }


- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
   }


- (void)dealloc {
    [super dealloc];
}
@end

//////////////////////////////////////////////////RootViewController.h可以看到,其实什么都没有

#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController {

}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

cocos2d::CCApplication::sharedApplication()->run(); 究竟执行了什么呢?

。。。。。。。。。。。。。。。。。。。

 CCDirector::sharedDirector()->mainLoop();

。。。。。。。。。。。。。。。。。

是导演的主循环,导演很忙,下次再聊。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。