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