cocos2d-x学习(二)helloworld代码的解析一

海灵均
2023-12-01

1、 main.h

#ifndef __MAIN_H__
#define __MAIN_H__

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers

// Windows Header Files:
#include <windows.h>
#include <tchar.h>

// C RunTime Header Files
#include "platform/CCStdC.h"

#endif    // __MAIN_H__

(1)ifndef/define/endif

功能:主要目的是防止头文件的重复包含和编译。(以前都是只写在一个文件里的,没有这样的问题)

问题举例:a.cpp的头部是:#include "b.h " 和#include "c.h ",但是b.h和c.h里面都有#include "d.h "。这样就会导致在b中编译后,c中发现d已经被编译过了,就会报错“重定义”。(这个例子来自于脚本之家,写的挺好的)

使用:使用格式,下面标识的格式是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线。(这里标识代表的文件相当于上面例子中的d.h)

#ifndef <标识>
#define <标识>
......
......
#endif <标识>

(2)#define WIN32_LEAN_AND_MEAN 

功能:WIN32_LEAN_AND_MEAN 是针对 Win32 相关的头文件的, 可以通过预处理来关闭掉一些不太常用的系统接口或参数, 这样可以加快编译的速度。

(3)#include <tchar.h>

功能:目的是为了简化代码方便国际使用。TCHAR是unicode字符、宽字符。tchar.h头文件提供了一个数据类型TCHAR, 这个类型在UNICODE环境下将映射为wchar_t类型;在ASCII环境下映射为char类型。另外, tchar.h还提供了一组C语言字符串操作符的替代宏, 以_t开头, 例如_tcslen函数, 在UNICODE环境下被映射成为wcslen函数, 在ASCII环境下被映射成为strlen函数。

2、main.cpp

这是应用程序的入口。

#include "main.h"
#include "AppDelegate.h"
#include "cocos2d.h"

USING_NS_CC;
//入口程序
int WINAPI _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // create the application instance
    //创建这个App实例 使其进入消息循环
    AppDelegate app;
    return Application::getInstance()->run();
}

(1)USING_NS_CC

#ifdef __cplusplus

    #define NS_CC_BEGIN                    namespace cocos2d {

    #define NS_CC_END                       }

    #define USING_NS_CC                     usingnamespace cocos2d

#else

    #define NS_CC_BEGIN

    #define NS_CC_END

    #define USING_NS_CC

#endif

USING_NS_CC是什么:USING_NS_CC就是使用了cocos2d的命名空间。(命名空间:让相同的标识符在不同命名空间中的含义是互不干扰的)

为什么这里用USING_NS_CC:如果我们要使用CCSprite.h内的任何数据,都必须使用cocos2d空间, 即using namespace cocos2d,就是USING_NS_CC。(CCSprite是整个游戏开发处理的主要对象)

3、AppDelegate.h

#ifndef  _APP_DELEGATE_H_
#define  _APP_DELEGATE_H_

#include "cocos2d.h"

class  AppDelegate : private cocos2d::Application
{
public:
    AppDelegate();
    virtual ~AppDelegate();

    //该方法主要设置 OpenGL的一些属性。
    virtual void initGLContextAttrs();

    //不同的平台的应用程序初始化
    //如果导演和场景初始化成功返回true继续运行,失败就停止运行
    virtual bool applicationDidFinishLaunching();

    //当程序进入后太自动调用
    virtual void applicationDidEnterBackground();
    //当引用程序恢复到前台会自动调用
    virtual void applicationWillEnterForeground();
};

#endif // _APP_DELEGATE_H_

(1)class

功能:和c语言的struct很像。主要是数据抽象和封装,类是一组对象的抽象,并且把这些数据封装成一个整体。

使用:

类名:遵守一般的命名规则。

public 与 private :为属性/方法限制的关键字(private表示该部分不能被外部所用只能被内部所用,public表示该部分可以被外部和内部使用)。(类数据成员不能用auto、extern和register等修饰,也不能定义初始化)

结尾:“  ; ”和c语言里面struct一样不能省略。

下面是模板。

class 类名
    {
        public:
            //公共的行为或属性
 
        private:
            //公共的行为或属性
    };

(2)class  AppDelegate : private cocos2d::Application

C++双冒号:在上面中,是命名空间作用域符。cocos2d是一个命名空间。(也还有其它的用法)

C++单冒号:在上面中,是用来声明基类的。在基类类名前面可以加public\private\protected等标签,用于标识继承的类型,也可以省略,省略的话,用class定义的类默认为private,用struct定义的类默认为public。(还有很多其它的用法)

这句话的解读:Application类中的private、protected、public属性的成员在AppDelegate都会变成private的。(在论坛上看到的神奕用户的理解,感觉挺有道理的)

4、AppDelegate.cpp

#include "AppDelegate.h"
#include "HelloWorldScene.h"

#if USE_AUDIO_ENGINE && USE_SIMPLE_AUDIO_ENGINE
#error "Don't use AudioEngine and SimpleAudioEngine at the same time. Please just select one in your game!"
#endif

#if USE_AUDIO_ENGINE
#include "audio/include/AudioEngine.h"
using namespace cocos2d::experimental;
#elif USE_SIMPLE_AUDIO_ENGINE
#include "audio/include/SimpleAudioEngine.h"
using namespace CocosDenshion;
#endif

USING_NS_CC;

static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320);
static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320);
static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768);
static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536);

AppDelegate::AppDelegate()
{
	//构造函数
}

AppDelegate::~AppDelegate() 
{
	//析构函数
#if USE_AUDIO_ENGINE
    AudioEngine::end();
#elif USE_SIMPLE_AUDIO_ENGINE
    SimpleAudioEngine::end();
#endif
}

//设置 OpenGL context,如果要设置不同的context,请修改GalCutExtTrac的值。
//这个设置对所有平台都有效
void AppDelegate::initGLContextAttrs()
{
    //设置 OpenGL context 属性,目前只能设置7个属性
    //red,green,blue,alpha,depth,stencil,multisamplesCount
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8, 0};
	
    GLView::setGLContextAttrs(glContextAttrs);
}

//如果要使用包管理器安装更多的包,请不要修改或删除此函数。
static int register_all_packages()
{
    return 0; //flag for packages manager
}
//程序启动完全后,游戏启动的入口
bool AppDelegate::applicationDidFinishLaunching() {
    
	//初始化导演类
    auto director = Director::getInstance();
	//设置opengl视图
    auto glview = director->getOpenGLView();
	
    if(!glview) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
        glview = GLViewImpl::createWithRect("HelloWorld", cocos2d::Rect(0, 0, designResolutionSize.width, designResolutionSize.height));
#else
        glview = GLViewImpl::create("HelloWorld");
#endif
        director->setOpenGLView(glview);
    }

	//是否打开fps,屏幕上可以看到帧数
    director->setDisplayStats(true);
	//设置帧数 默认每秒60帧
    director->setAnimationInterval(1.0f / 60);
	//创建一个场景
    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);
    auto frameSize = glview->getFrameSize();
    // 如果框架的高度大于中等大小的高度。
    if (frameSize.height > mediumResolutionSize.height)
    {        
        director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));
    }
    // 如果框架的高度大于小尺寸的高度。
    else if (frameSize.height > smallResolutionSize.height)
    {        
        director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));
    }
    // 如果框架的高度小于中等大小的高度。
    else
    {        
        director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));
    }

    register_all_packages();

    // 创建一个场景。这是一个自动保存对象。    
    auto scene = HelloWorld::createScene();

	//游戏真正开始
    director->runWithScene(scene);

    return true;
}

//当程序切换到后台之后,它会运行这个,比如玩着玩着电话来了
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();
	//声音暂停
#if USE_AUDIO_ENGINE
    AudioEngine::pauseAll();
#elif USE_SIMPLE_AUDIO_ENGINE
    SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    SimpleAudioEngine::getInstance()->pauseAllEffects();
#endif
}
//当程序重新被激活,音乐和画面重新激活
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();

#if USE_AUDIO_ENGINE
    AudioEngine::resumeAll();
#elif USE_SIMPLE_AUDIO_ENGINE
    SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    SimpleAudioEngine::getInstance()->resumeAllEffects();
#endif
}

总结:学习到了一些之前不会的,之前使用的c++都是c+stl,没有对类(class)这方面有更深入的学习,还是给自己补充了一下这方面的知识。

 类似资料: