杰瑞科技汇

Cocos2d-x开发教程该怎么学?

Cocos2d-x 开发完整教程

Cocos2d-x 是一个开源的、跨平台的 2D 游戏引擎,使用 C++ 语言开发,它支持 Windows, macOS, Linux, iOS, Android, Web 等多个平台,并且拥有非常活跃的社区和丰富的文档。

Cocos2d-x开发教程该怎么学?-图1
(图片来源网络,侵删)

目录

  1. 第一部分:入门准备

    • 什么是 Cocos2d-x?
    • 为什么选择 Cocos2d-x?
    • 开发环境要求
    • 安装与配置 (Cocos Console, Visual Studio)
  2. 第二部分:核心概念与第一个游戏

    • 创建第一个项目
    • 理解项目结构
    • 场景、导演与图层
    • 创建精灵
    • 添加事件监听
    • 让精灵动起来 (动作)
    • 第一个游戏:Flappy Bird 基础版
  3. 第三部分:进阶核心知识

    • 节点与场景
      • Node: 万物之源
      • Scene: 游戏的舞台
      • Layer: 功能层
      • Menu: 菜单系统
    • 精灵与渲染
      • Sprite: 精灵详解
      • SpriteFrameSpriteFrameCache: 精灵帧缓存
      • 粒子系统
    • 用户交互
      • 触摸事件
      • 鼠标事件
      • 键盘事件
    • 动作系统
      • 基础动作 (移动、旋转、缩放)
      • 序列动作
      • 重复动作
      • 自定义动作
    • 数据持久化
      • UserDefault: 简单数据存储
      • FileUtils: 文件操作
    • 音效与音乐
      • SimpleAudioEngine: 播放背景音乐和音效
  4. 第四部分:项目实战:打地鼠游戏

    Cocos2d-x开发教程该怎么学?-图2
    (图片来源网络,侵删)
    • 游戏设计思路
    • 创建项目与场景
    • 创建地鼠洞和地鼠
    • 实现地鼠随机出现逻辑
    • 添加点击事件
    • 计分系统
    • 游戏开始与结束逻辑
  5. 第五部分:发布与打包

    • 打包到 Windows
    • 打包到 Android (需要额外配置)
    • 打包到 iOS (需要 Mac 和 Xcode)
  6. 第六部分:学习资源与社区

    • 官方文档
    • 社区与论坛
    • 视频教程
    • 推荐书籍

第一部分:入门准备

什么是 Cocos2d-x?

Cocos2d-x 是一个基于 C++ 的 2D 游戏引擎,它封装了底层的图形渲染、事件处理、文件访问等复杂操作,让开发者可以专注于游戏逻辑和创意,它的设计理念是简单、易用、高效。

为什么选择 Cocos2d-x?

  • 跨平台: 一套代码,多端运行。
  • 高性能: C++ 语言保证了底层性能。
  • 成熟稳定: 发展多年,经过大量商业项目验证。
  • 社区活跃: 拥有庞大的开发者社区,遇到问题容易找到解决方案。
  • 免费开源: 无需授权费用,适合个人开发者和小型团队。

开发环境要求

  • 操作系统: Windows 7/8/10 (64-bit), macOS, Linux。
  • 编译器:
    • Windows: Visual Studio 2025 (推荐) 或更高版本,需要安装 "使用 C++ 的桌面开发" 工作负载。
    • macOS: Xcode。
    • Linux: GCC 4.8+ 或 Clang 3.3+。
  • 其他: Cocos Console (命令行工具)。

安装与配置 (以 Windows 为例)

安装 Cocos Console Cocos Console 是官方的命令行工具,用于创建、构建和发布项目。

  1. 安装 Python: Cocos Console 依赖于 Python,请确保你的系统已安装 Python 3.6 或更高版本,并将其添加到系统环境变量 PATH 中。
  2. 安装 Cocos Console: 打开命令行(CMD 或 PowerShell),执行以下命令:
    pip install cocostudio
    pip install cocos

    安装完成后,可以通过 cocos -v 命令来验证是否安装成功。

创建项目并使用 Visual Studio 打开

  1. 在命令行中,进入你想要创建项目的目录,然后运行:

    cocos new MyFirstGame -p com.mycompany.mygame -l cpp -d .
    • MyFirstGame: 项目名称。
    • -p com.mycompany.mygame: 项目包名(唯一标识符)。
    • -l cpp: 使用 C++ 作为开发语言。
    • -d .: 在当前目录下创建项目。
  2. 命令执行后,会生成一个名为 MyFirstGame 的文件夹,这就是你的项目根目录。

  3. 使用 Visual Studio 打开项目,进入 MyFirstGame/build 目录,找到 MyFirstGame.sln 文件,用 Visual Studio 打开它。

编译运行

  1. 在 Visual Studio 的解决方案资源管理器中,确保选中 MyFirstGame 项目。
  2. 选择 Debug -> x64 (或 Win32) 配置。
  3. 按下 F5 键或点击“开始调试”按钮。
  4. 如果一切顺利,一个窗口会弹出,显示一个蓝色的背景和 "Hello World" 字样,恭喜你,环境已经配置成功!

第二部分:核心概念与第一个游戏

创建第一个项目

(参考第一部分的步骤二)

理解项目结构

  • Classes/: 存放你的 C++ 源代码文件,这是你主要编写游戏逻辑的地方。
  • proj.windows/: Windows 平台的项目文件。
  • proj.android-studio/: Android 平台的项目文件。
  • proj.ios_mac/: iOS/macOS 平台的项目文件。
  • res/: 存放所有资源文件,如图片、音频、字体、配置文件等。
  • cocos2d/: Cocos2d-x 引擎的核心源代码。
  • tools/: 一些辅助工具。

场景、导演与图层

  • 导演 (Director): 游戏的总指挥,它负责管理场景的切换、控制游戏循环、获取窗口尺寸等,你可以通过 Director::getInstance() 获取它的单例。
  • 场景 (Scene): 游戏的舞台,一个游戏通常由多个场景组成,比如主菜单场景、游戏场景、结束场景等,场景是 Node 的容器。
  • 图层 (Layer): 场景中的一个层,你可以把不同功能的元素放在不同的层上,比如背景层、UI层、游戏逻辑层。Layer 也是 Node 的子类,默认可以接收触摸和键盘事件。

创建精灵

精灵是游戏中最基本的可视元素,通常代表一个角色、一个道具或一张背景图。

// 在 MyFirstGameScene.cpp 中
#include "HelloWorldScene.h"
#include "cocos2d.h" // 引入核心头文件
USING_NS_CC; // 使用 Cocos2d-x 命名空间
Scene* HelloWorld::createScene()
{
    // 创建一个场景
    auto scene = Scene::create();
    // 创建一个层
    auto layer = HelloWorld::create();
    // 将层添加到场景中
    scene->addChild(layer);
    // 返回场景
    return scene;
}
// 在 HelloWorld::init() 函数中
bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    // 获取导演实例和窗口尺寸
    auto director = Director::getInstance();
    auto visibleSize = director->getVisibleSize();
    Vec2 origin = director->getVisibleOrigin();
    // 创建一个精灵
    // 注意:图片路径是相对于 res/ 目录的
    auto sprite = Sprite::create("HelloWorld.png");
    if (sprite == nullptr)
    {
        problemLoading("'HelloWorld.png'");
    }
    else
    {
        // 设置精灵的锚点,默认是 (0.5, 0.5),即中心点
        sprite->setAnchorPoint(Vec2(0.5f, 0.5f));
        // 设置精灵的位置
        sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
        // 将精灵添加到当前层中
        this->addChild(sprite);
    }
    return true;
}

添加事件监听

让精灵对用户的操作做出反应。

// 在 HelloWorld::init() 函数中,添加精灵之后
// 创建一个 "MenuItemImage" 作为按钮
auto closeItem = MenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
if (closeItem == nullptr ||
    closeItem->getContentSize().width <= 0 ||
    closeItem->getContentSize().height <= 0)
{
    problemLoading("'CloseNormal.png' and 'CloseSelected.png'");
}
else
{
    float x = origin.x + visibleSize.width - closeItem->getContentSize().width/2;
    float y = origin.y + closeItem->getContentSize().height/2;
    closeItem->setPosition(Vec2(x,y));
    // 创建一个菜单并添加按钮
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
}
// 添加一个触摸事件监听
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
// 将监听器注册到事件分发器
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
// 在 HelloWorldScene.h 中声明回调函数
// class HelloWorld : public Layer
// {
// public:
//     // ...
//     virtual bool onTouchBegan(Touch* touch, Event* event);
//     // ...
// };
// 在 HelloWorldScene.cpp 中实现回调函数
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
    // 获取触摸点的坐标
    auto touchLocation = touch->getLocation();
    // 检查是否点击了精灵
    if (sprite->getBoundingBox().containsPoint(touchLocation))
    {
        // 点击精灵后,让它消失
        sprite->runAction(RemoveSelf::create());
    }
    return true;
}

让精灵动起来 (动作)

Cocos2d-x 提供了强大的动作系统。

// 在 HelloWorld::init() 中,创建精灵之后
// 创建一个移动动作:在2秒内,移动到屏幕右侧
auto moveBy = MoveBy::create(2, Vec2(200, 0));
// 创建一个旋转动作:在1秒内,旋转360度
auto rotateBy = RotateBy::create(1, 360);
// 创建一个序列动作:先移动,再旋转
auto sequence = Sequence::create(moveBy, rotateBy, nullptr);
// 创建一个无限重复的动作
auto repeat = RepeatForever::create(sequence);
// 让精灵执行这个动作
sprite->runAction(repeat);

第一个游戏:Flappy Bird 基础版

结合以上知识,我们可以做一个最简化的 Flappy Bird。

  1. 场景: 一个 Scene,一个 Layer
  2. 小鸟: 一个 Sprite
  3. 重力: 使用 MoveByMoveTo 模拟重力,持续向下移动。
  4. 点击: 监听触摸事件,点击时给小鸟一个向上的速度(MoveBy::create(0.2, Vec2(0, 100)))。
  5. 管道: 两个 Sprite(上管道和下管道),从右向左移动。
  6. 碰撞检测: 检测小鸟是否碰到管道或屏幕边界,如果碰撞,游戏结束。

第三部分:进阶核心知识

节点与场景

  • Node: 所有可见对象的基类,它拥有位置、旋转、缩放、颜色等属性,并且可以包含子节点。Scene, Layer, Sprite 都是 Node 的子类。
  • Scene: 通常作为游戏流程的容器,不直接包含游戏元素,而是通过添加 Layer 来组织。
  • Layer: 功能层,可以包含游戏元素,并且可以接收事件。
  • Menu: 专门用于创建菜单的 Node,包含多个 MenuItem

精灵与渲染

  • Sprite: 精灵,可以加载图片,并进行裁剪、旋转等操作。

  • SpriteFrameSpriteFrameCache:

    • 当你使用一张包含多个小图的大图(精灵表/Texture Packer)时,你需要使用 SpriteFrame 来定义每个小图的区域。
    • SpriteFrameCache 用于缓存和管理这些 SpriteFrame,提高性能。
      // 加载精灵表
      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("sprites.plist", "sprites.png");

    // 从缓存中创建精灵 auto bird = Sprite::createWithSpriteFrameName("bird.png");

用户交互

  • 触摸事件: EventListenerTouchOneByOne (单点), EventListenerTouchAllAtOnce (多点)。
  • 鼠标事件: EventListenerMouse
  • 键盘事件: EventListenerKeyboard
  • 自定义事件: 可以在不同对象之间传递自定义消息,实现解耦。

动作系统

  • 即时动作: 立即完成,如 Show, Hide, Place
  • 延时动作: 在一段时间内完成,如 MoveTo, RotateBy, ScaleTo, FadeIn/Out
  • 组合动作:
    • Sequence: 按顺序执行。
    • Spawn: 同时执行。
    • Repeat: 重复指定次数。
    • RepeatForever: 无限重复。
    • DelayTime: 延时。

数据持久化

  • UserDefault: 类似于一个轻量级的本地数据库,用于存储简单的键值对数据(如最高分、音效开关等)。

    // 保存数据
    UserDefault::getInstance()->setIntegerForKey("high_score", 100);
    UserDefault::getInstance()->setBoolForKey("sound_on", true);
    // 读取数据
    int highScore = UserDefault::getInstance()->getIntegerForKey("high_score", 0);
    bool soundOn = UserDefault::getInstance()->getBoolForKey("sound_on", true);
    // 刷新到磁盘
    UserDefault::getInstance()->flush();
  • FileUtils: 用于读写文件,可以保存更复杂的数据结构(如 JSON 文件)。

音效与音乐

  • SimpleAudioEngine: 一个简单的音频引擎单例。

    // 获取实例
    auto audio = SimpleAudioEngine::getInstance();
    // 播放背景音乐 (循环)
    audio->playBackgroundMusic("background.mp3", true);
    // 播放音效
    audio->playEffect("jump.wav");
    // 暂停/恢复
    audio->pauseBackgroundMusic();
    audio->resumeBackgroundMusic();
    // 设置音量
    audio->setBackgroundMusicVolume(0.5);
    audio->setEffectsVolume(0.8);

第四部分:项目实战:打地鼠游戏

游戏设计思路

  • 一个固定大小的游戏区域。
  • 区域内有9个地鼠洞(3x3网格)。
  • 地鼠会随机从某个洞中冒出,停留一会儿后缩回去。
  • 玩家点击地鼠,得分加一。
  • 游戏有时间限制(如30秒),时间到后显示最终得分。

创建项目与场景

使用 Cocos Console 创建新项目,命名为 WhackAMole,在 WhackAMoleScene.cppinit() 方法中,设置背景色。

创建地鼠洞和地鼠

  1. res 目录下准备地鼠洞(hole.png)和地鼠(mole.png)的图片。
  2. init() 中创建一个 Node 作为游戏容器,并设置其位置。
  3. 使用循环创建9个 Sprite 作为地鼠洞,并排列成3x3网格,添加到游戏容器中。
  4. 为每个地鼠洞创建一个 Sprite 作为地鼠,初始时设置为不可见 (setVisible(false)),并放置在对应洞的上方。

实现地鼠随机出现逻辑

  1. 创建一个 std::vector<Sprite*> 来存储所有地鼠的指针。

  2. 创建一个 schedule 定时器,每隔一段时间(如1秒)触发一次。

    // 在 init() 函数末尾
    this->schedule(schedule_selector(WhackAMole::updateMole), 1.0f);
    // 在 WhackAMoleScene.h 中声明
    // void updateMole(float dt);
    // 在 WhackAMoleScene.cpp 中实现
    void WhackAMole::updateMole(float dt)
    {
        // 1. 随机选择一个地鼠
        int randomIndex = rand() % moles.size();
        Sprite* mole = moles.at(randomIndex);
        // 2. 如果地鼠当前不可见,就让它出现
        if (!mole->isVisible())
        {
            mole->setVisible(true);
            // 3. 创建一个动作,让地鼠在1.5秒后消失
            auto hideAction = Sequence::create(
                DelayTime::create(1.5f),
                Hide::create(),
                nullptr
            );
            mole->runAction(hideAction);
        }
    }

添加点击事件

  1. 为每个地鼠添加一个触摸事件监听器。

  2. onTouchBegan 回调中,判断点击的是否是可见的地鼠。

  3. 如果是,让它立即消失,并加分。

    // 在创建每个地鼠时添加监听
    auto moleListener = EventListenerTouchOneByOne::create();
    moleListener->onTouchBegan = CC_CALLBACK_2(WhackAMole::onMoleTouched, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(moleListener, mole);
    moles.push_back(mole); // 将地鼠加入容器
    // 回调函数实现
    bool WhackAMole::onMoleTouched(Touch* touch, Event* event)
    {
        auto target = static_cast<Sprite*>(event->getCurrentTarget());
        auto touchLocation = touch->getLocation();
        if (target->getBoundingBox().containsPoint(touchLocation) && target->isVisible())
        {
            // 打中地鼠
            target->stopAllActions(); // 停止之前的消失动作
            target->setVisible(false); // 立即隐藏
            score++; // 加分
            scoreLabel->setString("Score: " + std::to_string(score));
            // 播放打中音效
            SimpleAudioEngine::getInstance()->playEffect("hit.wav");
            return true;
        }
        return false;
    }

计分系统

  1. init() 中创建一个 Label 用于显示分数。
  2. 创建一个 int score 变量。
  3. 每次打中地鼠时,更新 score 并刷新 Label 的显示。

游戏开始与结束逻辑

  1. 开始: 在 init() 中启动定时器,并重置分数。
  2. 结束: 创建一个 schedule,倒计时30秒,时间到后,unschedule 掉所有定时器,并显示一个游戏结束的 LayerScene

第五部分:发布与打包

打包到 Windows

在 Visual Studio 中,选择 Release 配置和 x64,然后按 Ctrl + Shift + B 生成解决方案,生成的 .exe 文件位于 proj.windows/bin/Release/x64/ 目录下。

打包到 Android

这个过程比较复杂,需要额外配置:

  1. 安装 Android SDK 和 NDK。
  2. 配置 cocos2d/tools/cocos2d-console/config/android-ndk.xml 文件,指向你的 NDK 路径。
  3. 在命令行中使用 Cocos Console 构建项目:
    cocos build -p android --ndk-root /path/to/your/ndk
  4. 构建完成后,项目会生成在 build/android 目录下,可以使用 Android Studio 打开并进一步打包成 APK。

打包到 iOS

这个过程必须在 Mac 电脑上进行,并且需要安装 Xcode。

  1. 在 Mac 上使用 Cocos Console 构建项目:
    cocos build -p ios
  2. 构建完成后,项目会生成在 build/ios 目录下,使用 Xcode 打开并打包成 IPA 文件。

第六部分:学习资源与社区

官方文档

社区与论坛

  • Cocos 官方论坛
  • Cocos 中文社区论坛
  • Stack Overflow (搜索 cocos2d-x

视频教程

  • Bilibili、YouTube 上有大量由社区成员录制的 Cocos2d-x 教程,搜索 "Cocos2d-x 教程" 即可找到。

推荐书籍

  • 《Cocos2d-x 游戏开发之旅》
  • 《Cocos2d-x 实战:C++卷》

希望这份详细的教程能对你有所帮助!Cocos2d-x 是一个非常强大的工具,多动手实践是掌握它的最好方式,祝你开发顺利!

分享:
扫描分享到社交APP
上一篇
下一篇