• Linux下搭建 Cocos2d-x-2.1.4 编译环境


    【tonyfield 2013.09.04 】

    参考 Linux下搭建 Cocos2d-x-2.1.4 编译环境 导入 HelloCpp 例程

    1. Java 入口 HelloCpp.java

      HelloCpp类很简单,因为它继承的父类 Cocos2dxActivity 揽下了所有的内部操作,并建立了和JNI各类接口的关系,显示的工作也是通过 Cocos2dxActivity 的OnCreate函数来完成的。具体可以参考其实现。

      System.loadLibrary("hellocpp");这句将载入项目内的 JNI 库,执行 JNI 中 JNI_OnLoad 函数接口。

    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");
        }
    }

      除了上述所述功能,如果你发布的应用是收费的,那在这个类型中还需要添加验证过程,具体请参考 Android 开发文档。

    2. JNI 入口 main.cpp

      main.cpp 路径是 jni/hellocpp/main.cpp,载入库时刻,JNI_OnLoad 将被调用 ,它做的很重要的事情就是保存javaVM值,通过这个值你可以在JNI空间任何地方去的有效的JNIEnv环境变量 。相反,试图保存 JNIEnv在未来调用的做法是危险的。

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


      另一件必须完成的工作就是实现虚函数 Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit,显然 上节提到的 Cocos2dxActivity 将会调用这个函数。

    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();
        }
    }


      函数先检查 OpenGL View 是否可以正常获得,对于 Android API版本较低的手机这个函数可能无法通过,这时,在模拟器上看到的是黑屏。你可以自己修改来是上层显示一点提示,免得用户以为是程序有问题。

      下面就是最重要的事情,创建自己的应用代表(Application Delegate)实例。这个实例中你需要做的就是实现初始化,消息响应函数等接口。CCApplication::sharedApplication()->run();会帮你让程序运转起来。CCApplication 这个类很简单,也有些诡异,它继承的 CCApplicationProtocol 类型就是一个纯虚的接口定义,这个父类是为跨平台设计的。CCApplication 中有一个静态函数 sharedApplication(),始终返回最近一次创建该类型对象的 this指针。这意味着 cocos2dx 在创建完这个对象后就想把这个对象的指针交给开发者,再由开发者调用 run成员函数来运转程序。

    int CCApplication::run()
    {
        // Initialize instance and cocos2d.
        if (! applicationDidFinishLaunching())
        {
            return 0;
        }    
        return -1;
    }

      你有理由相信你获得的这个指针实际上指向了一个 CCApplication 子类,它来完成实际的消息处理循环过程。

      好了,下面来研究 AppDelegate 类型。

    3. AppDelegate 类型

      AppDelegate 类型在 jni/Classes/AppDelegate.h 中定义,在 jni/Classes/AppDelegate.cpp 中实现。先看下面的定义,发现原来上节的 CCApplication 在这里果然变成了AppDelegate 的父类。你需要实现 applicationDidFinishLaunching 等 3个接口函数。上节中run函数中的调用关系问题到这里迎刃而解。(我想cocos2dx是否可以象 MFC 接口那样完成的更优美一些,将接口的调用过程完全隐藏起来。)

    class  AppDelegate : private cocos2d::CCApplication
    {
    public:
        AppDelegate();
        virtual ~AppDelegate();
    
        /**
        @brief    实现 CCDirector 和 CCScene 初始化代码
        @return true    初始化成功, app 继续.
        @return false   初始化失败, app 终止.
        */
        virtual bool applicationDidFinishLaunching();
    
        /**
        @brief  当应用进入后台执行该函数
        @param  the pointer of the application  ?? 我怎么没看到参数
        */
        virtual void applicationDidEnterBackground();
    
        /**
        @brief  当应用即将进入后台执行该函数
        @param  the pointer of the application
        */
        virtual void applicationWillEnterForeground();
    };


    AppDelegate的接口函数实现就像一个模版,在建立自己的应用时,你完全可以拿来主义。

    bool AppDelegate::applicationDidFinishLaunching() {
        // initialize director
        CCDirector* pDirector = CCDirector::sharedDirector();
        CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
    
        pDirector->setOpenGLView(pEGLView);
    
        // Set the design resolution
        pEGLView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, kResolutionNoBorder);
    
        CCSize frameSize = pEGLView->getFrameSize();
        
        vector<string> searchPath;
    
        // In this demo, we select resource according to the frame's height.
        // If the resource size is different from design resolution size, you need to set contentScaleFactor.
        // We use the ratio of resource's height to the height of design resolution,
        // this can make sure that the resource's height could fit for the height of design resolution.
    
        // if the frame's height is larger than the height of medium resource size, select large resource.
        if (frameSize.height > mediumResource.size.height)
        {
            searchPath.push_back(largeResource.directory);
    
            pDirector->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));
        }
        // if the frame's height is larger than the height of small resource size, select medium resource.
        else if (frameSize.height > smallResource.size.height)
        {
            searchPath.push_back(mediumResource.directory);
            
            pDirector->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));
        }
        // if the frame's height is smaller than the height of medium resource size, select small resource.
    	else
        {
            searchPath.push_back(smallResource.directory);
    
            pDirector->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));
        }
        
        // set searching path
        CCFileUtils::sharedFileUtils()->setSearchPaths(searchPath);
    	
        // turn on display FPS
        pDirector->setDisplayStats(true);
    
        // 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();
    
        // run
        pDirector->runWithScene(pScene);
    
        return true;
    }
    
    // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
    void AppDelegate::applicationDidEnterBackground() {
        CCDirector::sharedDirector()->stopAnimation();
    
        // if you use SimpleAudioEngine, it must be pause
        // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
    }
    
    // this function will be called when the app is active again
    void AppDelegate::applicationWillEnterForeground() {
        CCDirector::sharedDirector()->startAnimation();
    
        // if you use SimpleAudioEngine, it must resume here
        // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
    }


      其中比较重要的是 CCScene *pScene = HelloWorld::scene(); 这个语句,因为它涉及到另一个自定义类型 HelloWorld。

    4. HelloWorld 类型

      HelloWorld 类型在 jni/Classes/HelloWorldScene.h 中定义,在 jni/Classes/HelloWorldScene.cpp 中实现。


    class HelloWorld : public cocos2d::CCLayer
    {
    public:
        // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
        virtual bool init();  
    
        // there's no 'id' in cpp, so we recommend returning the class instance pointer
        static cocos2d::CCScene* scene();
        
        // a selector callback
        void menuCloseCallback(CCObject* pSender);
        
        // implement the "static node()" method manually
        CREATE_FUNC(HelloWorld);
    };


    CREATE_FUNC(HelloWorld) 展开后代码如下,基本意思就是定义静态函数create()创建HelloWorld 类对象并初始化。

    static HelloWorld* create() 
    { 
        HelloWorld *pRet = new HelloWorld(); 
        if (pRet && pRet->init()) 
        { 
            pRet->autorelease(); 
            return pRet; 
        } 
        else 
        { 
            delete pRet; 
            pRet = NULL; 
            return NULL; 
        } 
    }


      在另一个静态函数 sence中,将创建一个 CCScene 对象 和 HelloWorld 对象,HelloWorld 对象被组合到 CCScene 对象中,它也是 cocos2dx内部操作的对象。






    【转载请注明来自blog.csdn.net/tonyfield 谢谢 2013.09.04 】

  • 相关阅读:
    有点郁闷,但是又不能表现出来,好难过
    搞平衡,我们公司跟国企也没有啥区别
    找兼职遇到的尴尬
    两岁的儿子
    Shark DB Expert 2.6数据库客户端工具终结者 问世
    .Net 中访问Oracle 数据表,出现OCI22053: overflow error
    Oracle冷备迁移过程和在线日志损坏处理
    转:Oracle数据库的优化之数据库磁盘I/O
    Linux批量移动文件grep+mv
    Oracle下导入txt的shell脚本以及配置
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3301868.html
Copyright © 2020-2023  润新知