cocos2dx的第一个helloworld程序

1.simple_main.cpp

/**
 * @file simple_main.cpp
 * @brief Cocos2d-x简单测试程序的主函数
 * 
 * 这是最简单的Cocos2d-x程序入口,直接使用现有的AppDelegate类。
 * 程序创建一个AppDelegate实例并运行Cocos2d-x应用。
 */

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

USING_NS_CC;

/**
 * @brief 程序主函数
 * 
 * Cocos2d-x应用的入口点,负责:
 * 1. 输出启动信息
 * 2. 创建AppDelegate应用委托实例
 * 3. 运行Cocos2d-x应用
 * 4. 输出退出信息并返回退出码
 * 
 * @param argc 命令行参数个数
 * @param argv 命令行参数数组
 * @return int 应用程序退出码
 */
int main(int argc, char **argv)
{
    // 输出程序启动信息
    printf("=== Cocos2d-x Hello World ===\n");
    printf("创建AppDelegate应用委托...\n");
    
    // 创建应用委托实例
    // AppDelegate类继承自cocos2d::Application,负责管理应用生命周期
    AppDelegate app;
    
    printf("运行应用程序...\n");
    
    // 运行Cocos2d-x应用
    // Application::getInstance()->run()启动应用主循环
    int result = Application::getInstance()->run();
    
    // 输出应用程序退出码
    printf("应用程序退出,退出码: %d\n", result);
    
    // 返回退出码
    return result;
}

2.Classes/AppDelegate.h

#ifndef  _APP_DELEGATE_H_
#define  _APP_DELEGATE_H_

#include "cocos2d.h"

/**
 * @brief Cocos2d-x应用委托类
 * 
 * 应用委托类,继承自cocos2d::Application,负责管理应用的生命周期。
 * 私有继承隐藏了Director的部分接口。
 */
class  AppDelegate : private cocos2d::Application
{
public:
    /**
     * @brief 构造函数
     * 初始化应用委托实例
     */
    AppDelegate();
    
    /**
     * @brief 析构函数
     * 清理应用委托资源
     */
    virtual ~AppDelegate();

    /**
     * @brief 初始化OpenGL上下文属性
     * 
     * 设置OpenGL上下文的各种属性,如颜色深度、深度缓冲、模板缓冲等。
     */
    virtual void initGLContextAttrs();
    
    /**
     * @brief 应用启动完成回调
     * 
     * 应用启动完成后调用,在这里实现Director和Scene的初始化代码。
     * @return true    初始化成功,应用继续运行
     * @return false   初始化失败,应用终止
     */
    virtual bool applicationDidFinishLaunching();

    /**
     * @brief 应用进入后台回调
     * 
     * 当应用移动到后台时调用(例如接听电话时)。
     * @param  the pointer of the application 应用指针
     */
    virtual void applicationDidEnterBackground();

    /**
     * @brief 应用进入前台回调
     * 
     * 当应用重新进入前台时调用。
     * @param  the pointer of the application 应用指针
     */
    virtual void applicationWillEnterForeground();
};

#endif // _APP_DELEGATE_H_

3.Classes/AppDelegate.cpp

#include "AppDelegate.h"

#include <vector>
#include <string>

#include "HelloWorldScene.h"
#include "AppMacros.h"

// 取消注释以下行以使用本地化管理器
// #include "editor-support/cocostudio/LocalizationManager.h"

USING_NS_CC;
using namespace std;

/**
 * @brief AppDelegate构造函数
 * 
 * 初始化应用委托实例
 */
AppDelegate::AppDelegate() {

}

/**
 * @brief AppDelegate析构函数
 * 
 * 清理应用委托资源
 */
AppDelegate::~AppDelegate() 
{
}

/**
 * @brief 初始化OpenGL上下文属性
 * 
 * 设置OpenGL上下文的各种属性:
 * - 红色通道位数:8
 * - 绿色通道位数:8  
 * - 蓝色通道位数:8
 * - Alpha通道位数:8
 * - 深度缓冲位数:24
 * - 模板缓冲位数:8
 */
void AppDelegate::initGLContextAttrs()
{
    // 设置OpenGL上下文属性
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

    // 应用OpenGL上下文属性设置
    GLView::setGLContextAttrs(glContextAttrs);
}

/**
 * @brief 应用启动完成回调
 * 
 * 应用启动完成后调用,在这里实现Director和Scene的初始化代码。
 * 包括:
 * 1. 初始化Director和OpenGL视图
 * 2. 设置设计分辨率
 * 3. 根据设备屏幕尺寸选择资源路径
 * 4. 设置内容缩放因子
 * 5. 创建并运行主场景
 * 
 * @return true 初始化成功,应用继续运行
 * @return false 初始化失败,应用终止
 */
bool AppDelegate::applicationDidFinishLaunching()
{
    // 初始化Director(导演)
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    
    // 如果OpenGL视图不存在,则创建它
    if(!glview) {
        glview = GLViewImpl::create("Cpp Empty Test");
        director->setOpenGLView(glview);
    }

    director->setOpenGLView(glview);

    // 设置设计分辨率
    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);

    // 获取实际帧尺寸
    Size frameSize = glview->getFrameSize();
    
    // 资源搜索路径
    vector<string> searchPath;

    // 在这个示例中,我们根据帧的高度选择资源
    // 如果资源尺寸与设计分辨率尺寸不同,需要设置内容缩放因子
    // 我们使用资源高度与设计分辨率高度的比率,
    // 这样可以确保资源高度适合设计分辨率高度

    // 如果帧高度大于中等资源尺寸的高度,选择大资源
    if (frameSize.height > mediumResource.size.height)
    {
        searchPath.push_back(largeResource.directory);

        // 设置内容缩放因子
        director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));
    }
    // 如果帧高度大于小资源尺寸的高度,选择中等资源
    else if (frameSize.height > smallResource.size.height)
    {
        searchPath.push_back(mediumResource.directory);
        
        // 设置内容缩放因子
        director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));
    }
    // 如果帧高度小于中等资源尺寸的高度,选择小资源
    else
    {
        searchPath.push_back(smallResource.directory);

        // 设置内容缩放因子
        director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));
    }
    
    // 设置资源搜索路径
    FileUtils::getInstance()->setSearchPaths(searchPath);

    // 取消注释以下块以使用本地化管理器设置本地化字符串

    // 如果要加载JSON本地化数据,使用以下块
    /*
    cocostudio::ILocalizationManager * lm = cocostudio::JsonLocalizationManager::getInstance();
    lm->initLanguageData("your localize file name.lang.json");
    cocostudio::LocalizationHelper::setCurrentManager(lm, false);
    */

    // 如果要加载二进制本地化数据,使用以下块
    /*
    cocostudio::ILocalizationManager * lm = cocostudio::BinLocalizationManager::getInstance();
    lm->initLanguageData("your localize file name.lang.csb");
    cocostudio::LocalizationHelper::setCurrentManager(lm, true);
    */

    // 要启用VR,取消注释以下行
    // auto vrImpl = new VRGenericRenderer;
    // glview->setVR(vrImpl);

    // 开启显示FPS(每秒帧数)
    director->setDisplayStats(true);

    // 设置FPS,默认值是1.0/60,如果不调用此方法
    director->setAnimationInterval(1.0f / 60);

    // 创建一个场景,这是一个自动释放对象
    auto scene = HelloWorld::scene();

    // 运行场景
    director->runWithScene(scene);

    return true;
}

/**
 * @brief 应用进入后台回调
 * 
 * 当应用变为不活跃时调用(例如接听电话时)。
 * 注意:当接听电话时,此函数被调用。
 */
void AppDelegate::applicationDidEnterBackground()
{
    // 停止动画
    Director::getInstance()->stopAnimation();

    // 如果使用SimpleAudioEngine,必须暂停背景音乐
    // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

/**
 * @brief 应用进入前台回调
 * 
 * 当应用再次变为活跃时调用。
 */
void AppDelegate::applicationWillEnterForeground() {
    // 开始动画
    Director::getInstance()->startAnimation();

    // 如果使用SimpleAudioEngine,必须恢复背景音乐
    // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

4.Classes/AppMacros.h

#ifndef __APPMACROS_H__
#define __APPMACROS_H__

#include "cocos2d.h"

/**
 * @file AppMacros.h
 * @brief 应用宏定义文件
 * 
 * 这个文件包含了Cocos2d-x应用的各种宏定义和配置。
 * 主要用于演示如何使用一个设计分辨率匹配不同的资源,
 * 或者使用一个资源匹配不同的设计分辨率。
 * 
 * [情况1] 使用一个设计分辨率匹配不同的资源。
 *   请查看Appdelegate::applicationDidFinishLaunching。
 *   我们检查当前设备帧大小来决定需要选择哪个资源。
 *   所以如果你想测试标题中说的'[情况1]',
 *   你应该将iOS模拟器更改为不同的设备(例如iphone, iphone-retina3.5, iphone-retina4.0, ipad, ipad-retina),
 *   或者如果你使用win32或linux平台,通过"CCEGLView::setFrameSize"更改"proj.XXX/main.cpp"中的窗口大小,
 *   并通过更改窗口矩形修改"proj.mac/AppController.mm"。
 * 
 * [情况2] 使用一个资源匹配不同的设计分辨率。
 *   你代码中的坐标基于当前设计分辨率而不是资源大小。
 *   因此,你的设计分辨率可能非常大,而你的资源大小可能很小。
 *   要测试这个,只需将宏'TARGET_DESIGN_RESOLUTION_SIZE'定义为'DESIGN_RESOLUTION_2048X1536'
 *   并打开iPhone模拟器或创建一个480x320大小的窗口。
 * 
 * [注意] 通常,开发人员只需要定义一个设计分辨率(例如960x640)和一个或多个资源。
 */

/**
 * @brief 设计分辨率宏定义
 * 
 * 定义不同的设计分辨率选项:
 * - DESIGN_RESOLUTION_480X320: 480x320分辨率
 * - DESIGN_RESOLUTION_1024X768: 1024x768分辨率  
 * - DESIGN_RESOLUTION_2048X1536: 2048x1536分辨率
 */
#define DESIGN_RESOLUTION_480X320    0
#define DESIGN_RESOLUTION_1024X768   1
#define DESIGN_RESOLUTION_2048X1536  2

/**
 * @brief 目标设计分辨率大小
 * 
 * 如果要切换设计分辨率,请更改下一行。
 * 默认使用480x320分辨率。
 */
#define TARGET_DESIGN_RESOLUTION_SIZE  DESIGN_RESOLUTION_480X320

/**
 * @brief 资源结构体
 * 
 * 用于存储资源信息的结构体。
 * 包含资源尺寸和对应的资源目录。
 */
typedef struct tagResource
{
    cocos2d::Size size;      ///< 资源尺寸
    char directory[100];     ///< 资源目录路径
} Resource;

/**
 * @brief 小资源配置
 * 
 * 480x320分辨率对应的资源,使用iphone目录。
 */
static Resource smallResource  =  { cocos2d::Size(480, 320),   "iphone" };

/**
 * @brief 中等资源配置
 * 
 * 1024x768分辨率对应的资源,使用ipad目录。
 */
static Resource mediumResource =  { cocos2d::Size(1024, 768),  "ipad"   };

/**
 * @brief 大资源配置
 * 
 * 2048x1536分辨率对应的资源,使用ipadhd目录。
 */
static Resource largeResource  =  { cocos2d::Size(2048, 1536), "ipadhd" };

/**
 * @brief 设计分辨率尺寸
 * 
 * 根据TARGET_DESIGN_RESOLUTION_SIZE宏定义选择对应的设计分辨率尺寸。
 */
#if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320)
static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320);
#elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_1024X768)
static cocos2d::Size designResolutionSize = cocos2d::Size(1024, 768);
#elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_2048X1536)
static cocos2d::Size designResolutionSize = cocos2d::Size(2048, 1536);
#else
#error unknown target design resolution!  // 未知的目标设计分辨率!
#endif

/**
 * @brief 标题字体大小宏
 * 
 * 字体大小24是为小分辨率设计的,所以我们应该更改它以适应当前的设计分辨率。
 * 计算公式:当前设计分辨率宽度 / 小资源宽度 * 24
 */
#define TITLE_FONT_SIZE  (cocos2d::Director::getInstance()->getOpenGLView()->getDesignResolutionSize().width / smallResource.size.width * 24)

#endif /* __APPMACROS_H__ */

5.Classes/HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

/**
 * @brief HelloWorld场景类
 * 
 * 继承自cocos2d::Scene,表示游戏的主场景。
 * 包含一个"Hello World"标签和一个关闭按钮。
 */
class HelloWorld : public cocos2d::Scene
{
public:
    /**
     * @brief 初始化场景
     * 
     * 重写Scene的init方法,用于初始化场景内容。
     * 包括创建标签、菜单和精灵等UI元素。
     * 
     * @return true 初始化成功
     * @return false 初始化失败
     */
    virtual bool init() override;

    /**
     * @brief 创建场景的静态方法
     * 
     * 工厂方法,用于创建HelloWorld场景实例。
     * 这是一个便利方法,内部调用create()方法。
     * 
     * @return cocos2d::Scene* 返回创建的场景指针
     */
    static cocos2d::Scene* scene();

    /**
     * @brief 菜单关闭回调函数
     * 
     * 当用户点击关闭按钮时调用的回调函数。
     * 用于处理关闭按钮的点击事件。
     * 
     * @param sender 触发回调的对象指针
     */
    void menuCloseCallback(cocos2d::Ref* sender);

    /**
     * @brief CREATE_FUNC宏
     * 
     * Cocos2d-x的便利宏,自动实现静态create()方法。
     * 使用此宏可以方便地创建节点对象。
     */
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

6.Classes/HelloWorldScene.cpp

#include "HelloWorldScene.h"
#include "AppMacros.h"

USING_NS_CC;

/**
 * @brief 创建HelloWorld场景的静态方法
 * 
 * 工厂方法,用于创建HelloWorld场景实例。
 * 这是一个便利方法,内部调用create()方法。
 * 
 * @return Scene* 返回创建的HelloWorld场景指针
 */
Scene* HelloWorld::scene()
{
     return HelloWorld::create();
}

/**
 * @brief 初始化HelloWorld场景
 * 
 * 重写Scene的init方法,用于初始化场景内容。
 * 包括以下步骤:
 * 1. 调用父类的init方法
 * 2. 添加关闭按钮菜单项
 * 3. 创建"Hello World"标签
 * 4. 添加精灵图片
 * 
 * @return true 初始化成功
 * @return false 初始化失败
 */
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. 首先调用父类的init方法
    if ( !Scene::init() )
    {
        return false;
    }
    
    // 获取可见区域尺寸和原点坐标
    auto visibleSize = Director::getInstance()->getVisibleSize();
    auto origin = Director::getInstance()->getVisibleOrigin();

    /////////////////////////////
    // 2. 添加带有"X"图片的菜单项,点击退出程序
    //    你可以修改它

    // 添加一个"关闭"图标来退出程序,这是一个自动释放对象
    auto closeItem = MenuItemImage::create(
                                        "CloseNormal.png",      // 正常状态图片
                                        "CloseSelected.png",    // 选中状态图片
                                        CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); // 回调函数
    
    // 设置关闭按钮位置(屏幕右上角)
    closeItem->setPosition(origin + Vec2(visibleSize) - Vec2(closeItem->getContentSize() / 2));

    // 创建菜单,这是一个自动释放对象
    auto menu = Menu::create(closeItem, nullptr);
    menu->setPosition(Vec2::ZERO);  // 设置菜单位置为原点
    this->addChild(menu, 1);        // 将菜单添加到场景,z-order为1
    
    /////////////////////////////
    // 3. 在下面添加你的代码...

    // 添加一个显示"Hello World"的标签
    // 创建并初始化一个标签
    
    auto label = Label::createWithTTF("Hello World", "fonts/arial.ttf", TITLE_FONT_SIZE);
    
    // 将标签定位在屏幕中央
    label->setPosition(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height);

    // 将标签作为子节点添加到场景
    this->addChild(label, 1);  // z-order为1,确保在背景之上

    // 添加"HelloWorld"启动画面精灵
    auto sprite = Sprite::create("HelloWorld.png");

    // 将精灵定位在屏幕中央
    sprite->setPosition(Vec2(visibleSize / 2) + origin);

    // 将精灵作为子节点添加到场景
    this->addChild(sprite);  // 默认z-order为0,作为背景
    
    return true;
}

/**
 * @brief 菜单关闭回调函数
 * 
 * 当用户点击关闭按钮时调用的回调函数。
 * 用于处理关闭按钮的点击事件,结束应用程序。
 * 
 * @param sender 触发回调的对象指针(关闭按钮)
 */
void HelloWorld::menuCloseCallback(cocos2d::Ref* sender)
{
    // 结束Director,退出应用程序
    Director::getInstance()->end();

    // 在iOS平台上,需要调用exit(0)来确保完全退出
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

7.Makefile

# Makefile for Cocos2d-x Simple Test Project
# 基于cocos2d-x 3.16的Cocos2d-x简单测试项目的Makefile

# ============================================
# 编译器和标志配置
# ============================================

# C++编译器
CXX = g++

# 编译标志:
# -g: 生成调试信息
# -DLINUX: 定义LINUX平台宏
# -std=c++11: 使用C++11标准
# -Wall -Wextra: 启用所有警告
CXXFLAGS = -g -DLINUX -std=c++11 -Wall -Wextra

# 链接标志(当前为空)
LDFLAGS = 

# ============================================
# Cocos2d-x路径配置
# ============================================

# Cocos2d-x根目录
COCOS2DX_ROOT = /home/helen/cocos2d-x-cocos2d-x-3.16

# 包含路径:Cocos2d-x核心头文件、外部依赖、GLFW和项目类文件
COCOS_INCLUDE = -I$(COCOS2DX_ROOT)/cocos \
                -I$(COCOS2DX_ROOT)/external \
                -I$(COCOS2DX_ROOT)/external/glfw3/include/linux \
                -I/usr/include/GLFW \
                -I/usr/local/include/GLFW \
                -IClasses

# 库文件路径:测试项目库和Cocos2d-x构建库
LIB_PATHS = -L$(COCOS2DX_ROOT)/tests/cpp-empty-test/proj.linux \
            -L$(COCOS2DX_ROOT)/cocos2d/build/linux

# 需要链接的库文件
LIBS = -lcocos2d -lcocos2dInternal \
       -lGL -lX11 -lGLEW \
       -ltinyxml2 -lxxhash -lunzip -lz \
       -ljscocos2d -lluacocos2d -lrecast \
       -lfontconfig -lfreetype -lpng16 -ljpeg -ltiff -lwebp \
       -lBulletDynamics -lBulletCollision -lLinearMath \
       -lchipmunk -lglfw -lpthread

# ============================================
# 项目文件配置
# ============================================

# 目标可执行文件名
TARGET = simple_cocos_test

# 源文件列表:主程序、应用委托、HelloWorld场景
SRCS = simple_main.cpp \
       Classes/AppDelegate.cpp \
       Classes/HelloWorldScene.cpp

# 对象文件列表(自动从SRCS生成)
OBJS = $(SRCS:.cpp=.o)

# 头文件列表
HEADERS = Classes/AppDelegate.h \
          Classes/HelloWorldScene.h \
          Classes/AppMacros.h

# ============================================
# 构建目标规则
# ============================================

# 默认目标:构建整个项目
all: $(TARGET)

# 链接对象文件创建可执行文件
$(TARGET): $(OBJS)
    $(CXX) -g -o $@ $^ $(LIB_PATHS) $(LIBS)
    @echo "构建成功!可执行文件: $(TARGET)"
    @echo ""
    @echo "要运行程序:"
    @echo "  export RESOURCE_PATH=Resources"
    @echo "  ./$(TARGET)"

# 编译.cpp文件为.o文件的模式规则
# 任何.cpp文件都依赖对应的头文件
%.o: %.cpp $(HEADERS)
    $(CXX) $(CXXFLAGS) $(COCOS_INCLUDE) -c $< -o $@

# ============================================
# 实用目标
# ============================================

# 清理构建文件
clean:
    rm -f $(OBJS) $(TARGET)
    @echo "已清理构建文件"

# 运行程序(如果需要先构建)
run: $(TARGET)
    @echo "设置RESOURCE_PATH并运行$(TARGET)..."
    RESOURCE_PATH=Resources ./$(TARGET)

# 调试版本构建:添加调试标志,关闭优化
debug: CXXFLAGS += -DDEBUG -O0
debug: clean $(TARGET)

# 发布版本构建:最高优化级别,定义NDEBUG宏
release: CXXFLAGS += -O3 -DNDEBUG
release: clean $(TARGET)

# 显示项目信息
info:
    @echo "Cocos2d-x简单测试项目"
    @echo "======================"
    @echo "Cocos2d-x路径: $(COCOS2DX_ROOT)"
    @echo "源文件:"
    @for src in $(SRCS); do echo "  $$src"; done
    @echo "头文件:"
    @for hdr in $(HEADERS); do echo "  $$hdr"; done

# 显示帮助信息
help:
    @echo "可用目标:"
    @echo "  all     - 构建程序(默认目标)"
    @echo "  clean   - 删除对象文件和可执行文件"
    @echo "  run     - 构建并运行程序"
    @echo "  debug   - 构建带调试符号的版本"
    @echo "  release - 构建完全优化的版本"
    @echo "  info    - 显示项目信息"
    @echo "  help    - 显示此帮助信息"

# 伪目标声明(不是实际文件)
.PHONY: all clean run debug release info help
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容