题记:对于技术,我们大可不必挖得那么深,但一定要具备可以挖得很深的能力
- print('Hello World!')
- // AppDelegate.cpp 文件
- AppDelegate::AppDelegate()
- {
- CCLog("AppDelegate()"); // AppDelegate 构造函数打印
- }
- AppDelegate::~AppDelegate()
- {
- CCLog("AppDelegate().~()"); // AppDelegate 析构函数打印
- }
- // 程序入口
- bool AppDelegate::applicationDidFinishLaunching()
- {
- // initialize director
- CCDirector *pDirector = CCDirector::sharedDirector();
- pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
- // 初始化,资源适配,屏幕适配,运行第一个场景等代码
- ...
- ...
- ...
- return true;
- }
- void AppDelegate::applicationDidEnterBackground()
- {
- CCDirector::sharedDirector()->pause();
- }
- void AppDelegate::applicationWillEnterForeground()
- {
- CCDirector::sharedDirector()->resume();
- }
- #include "main.h"
- #include "../Classes/AppDelegate.h"
- #include "cocos2d.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string>
- USING_NS_CC;
- // 500 is enough?
- #define MAXPATHLEN 500
- int main(int argc, char **argv)
- {
- // get application path
- int length;
- char fullpath[MAXPATHLEN];
- length = readlink("/proc/self/exe", fullpath, sizeof(fullpath));
- fullpath[length] = '\0';
- std::string resourcePath = fullpath;
- resourcePath = resourcePath.substr(0, resourcePath.find_last_of("/"));
- resourcePath += "/../../../Resources/";
- // create the application instance
- AppDelegate app;
- CCApplication::sharedApplication()->setResourceRootPath(resourcePath.c_str());
- CCEGLView* eglView = CCEGLView::sharedOpenGLView();
- eglView->setFrameSize(720, 480);
- // eglView->setFrameSize(480, 320);
- return CCApplication::sharedApplication()->run();
- }
- #include "cocos2d.h"
- #include "AppDelegate.h"
- #include "platform/android/jni/JniHelper.h"
- #include <jni.h>
- #include <android/log.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();
- }
- }
- // Linux 平台关键代码
- int main(int argc, char **argv)
- {
- // 初始化等内容
- ...
- ...
- // 创建 app 变量
- AppDelegate app;
- ...
- ...
- // 执行 核心 run() 方法
- return CCApplication::sharedApplication()->run();
- }
- // Android 平台关键代码
- 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 对象
- AppDelegate *pAppDelegate = new AppDelegate();
- // 执行 核心 run() 方法
- CCApplication::sharedApplication()->run();
- }
- else
- {
- ...
- ...
- }
- }
- // [cocos2dx-path]/cocos2dx/platform/linux/CCApplication.cpp
- ...
- // 此变量为定义了一个 CCApplication 的静态变量,也及时自己类型本身,实现单例模式
- CCApplication * CCApplication::sm_pSharedApplication = 0;
- ...
- // 构造函数,将所创建的 对象直接付给其静态变量
- CCApplication::CCApplication()
- {
- // 断言在此决定着此构造函数只能运行一次
- CC_ASSERT(! sm_pSharedApplication);
- sm_pSharedApplication = this;
- }
- CCApplication::~CCApplication()
- {
- CC_ASSERT(this == sm_pSharedApplication);
- sm_pSharedApplication = NULL;
- m_nAnimationInterval = 1.0f/60.0f*1000.0f;
- }
- // run 方法,整个 cocos2d-x 的主循环在这里开始
- int CCApplication::run()
- {
- // 首次启动调用初始化函数
- if (! applicationDidFinishLaunching())
- {
- return 0;
- }
- // 游戏主循环,这里 Linux 的实现相比其它平台的实现,简单明了
- for (;;) {
- long iLastTime = getCurrentMillSecond();
- // 在循环之内调用每一帧的逻辑,组织并且控制 cocos2d-x 之中各个组件
- CCDirector::sharedDirector()->mainLoop();
- long iCurTime = getCurrentMillSecond();
- // 这里的几个时间变量,可以控制每一帧所运行的 最小 时间,从而控制游戏的帧率
- if (iCurTime-iLastTime<m_nAnimationInterval){
- usleep((m_nAnimationInterval - iCurTime+iLastTime)*1000);
- }
- }
- // 注意,这里的 for 循环,并没有退出循环条件,这也决定着 run() 方法永远也不会返回
- return -1;
- }
- // 方法直接返回了静态对象,并且做了断言,也既是在调用此方法之前,
- // 必须事先创建一个 CCApplication 的对象,以保证其静态变量能够初始化,否则返回空
- CCApplication* CCApplication::sharedApplication()
- {
- CC_ASSERT(sm_pSharedApplication);
- return sm_pSharedApplication;
- }
- // [cocos2dx-path]/cocos2dx/CCDirector.cpp
- ...
- // 定义静态变量,实现单例模式
- static CCDisplayLinkDirector *s_SharedDirector = NULL;
- ...
- // 返回 CCDirector 实例
- CCDirector* CCDirector::sharedDirector(void)
- {
- // 判断静态变量,以保证只有一个实例
- if (!s_SharedDirector)
- {
- s_SharedDirector = new CCDisplayLinkDirector();
- s_SharedDirector->init();
- }
- // CCDisplayLinkDirector 为 CCDirector 的子类,这里返回了其子类
- return s_SharedDirector;
- }
- // mainLoop 方法的具体实现
- void CCDisplayLinkDirector::mainLoop(void)
- {
- // 此变量是我们需要关注,并且跟踪的,因为它决定着程序的结束时机
- if (m_bPurgeDirecotorInNextLoop)
- {
- m_bPurgeDirecotorInNextLoop = false;
- // 运行到此,说明程序的运行,已经没有逻辑代码需要处理了
- purgeDirector();
- }
- else if (! m_bInvalid)
- {
- // 屏幕绘制,并做一些相应的逻辑处理,其内部处理,这里暂且不做过多探讨
- drawScene();
- // 这里实现了 cocos2d-x CCObject 对象的内存管理机制,对此有兴趣者,可以深入下去
- CCPoolManager::sharedPoolManager()->pop();
- }
- }
- // 弹出场景 CCScene
- void CCDirector::popScene(void)
- {
- CCAssert(m_pRunningScene != NULL, "running scene should not null");
- m_pobScenesStack->removeLastObject();
- unsigned int c = m_pobScenesStack->count();
- if (c == 0)
- {
- // 如果没有场景,调用 end() 方法
- end();
- }
- else
- {
- m_bSendCleanupToScene = true;
- m_pNextScene = (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);
- }
- }
- void CCDirector::end()
- {
- // 在 end 方法中,设置了变量为 true,这所致的结果,在 mainLoop 函数中,达成了运行 purgeDirector 方法的条件
- m_bPurgeDirecotorInNextLoop = true;
- }
- // 此方法做些收尾清理的工作
- void CCDirector::purgeDirector()
- {
- ...
- if (m_pRunningScene)
- {
- m_pRunningScene->onExit();
- m_pRunningScene->cleanup();
- m_pRunningScene->release();
- }
- // 做一些清理的工作
- ...
- // OpenGL view
- // ###此句代码关键###
- m_pobOpenGLView->end();
- m_pobOpenGLView = NULL;
- // delete CCDirector
- release();
- }
- // 设置 openglview
- void CCDirector::setOpenGLView(CCEGLView *pobOpenGLView)
- {
- CCAssert(pobOpenGLView, "opengl view should not be null");
- if (m_pobOpenGLView != pobOpenGLView)
- {
- // EAGLView is not a CCObject
- delete m_pobOpenGLView; // [openGLView_ release]
- // 为当前 CCDirector m_pobOpenGLView 赋值
- m_pobOpenGLView = pobOpenGLView;
- // set size
- m_obWinSizeInPoints = m_pobOpenGLView->getDesignResolutionSize();
- createStatsLabel();
- if (m_pobOpenGLView)
- {
- setGLDefaultValues();
- }
- CHECK_GL_ERROR_DEBUG();
- m_pobOpenGLView->setTouchDelegate(m_pTouchDispatcher);
- m_pTouchDispatcher->setDispatchEvents(true);
- }
- }
- // AppDelegate.cpp
- CCDirector *pDirector = CCDirector::sharedDirector();
- pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
- // [cocos2dx-path]/cocos2dx/platform/linux.CCEGLView.cpp
- ...
- CCEGLView* CCEGLView::sharedOpenGLView()
- {
- static CCEGLView* s_pEglView = NULL;
- if (s_pEglView == NULL)
- {
- s_pEglView = new CCEGLView();
- }
- return s_pEglView;
- }
- ...
- // openglview 结束方法
- void CCEGLView::end()
- {
- /* Exits from GLFW */
- glfwTerminate();
- delete this;
- exit(0);
- }