认识 Cocos2dx 3.x

34 篇文章 0 订阅

cpp11:

  1. 支持了auto标识符, 这样可以大大简化了声明变量的类型
  2. auto标识符: 泛类定义
  3. nullptr 代替 NULL, NULL只代表内存地址位为0, 这样做有时会出问题, cpp11后尽量用nullptr
  4. static_cast< Class >obj相当于c语言的(Class)obj, dynamic_cast更智能, 无法转换会返回nullptr
  5. 设置指针型布尔 std::shared_ptr<bool> enable(new bool(true));
    1. 获取和赋值 (*enable) = false;
  6. 7.

创建工程

  1. 下载最新的cocos2dx 3.x版本, 解压缩
  2. 打开terminal, cd 找到3.x解压缩的路径位置/tools/cocos2d-console/bin
  3. 执行 ./cocos new ProjectName -l cpp -p PackageName -d ~/Desktop
  4. 自行替换上面的ProjectName和PackageName内容, 以及对应语言, 我使用c++语言, 保存到桌面上
  5. std::nothrow 在内存不足时,new (std::nothrow)并不抛出异常,而是将指针置NULL

[相对cocos2dx2.x来看待]

基础

  1. 设置z层级 setLocalZOrder(0);
  2. 获得z层级 getGlobalZOrder();
  3. 层级参考链接
    1. globalZOrder 是用于 渲染器 中用来给“绘制命令”排序的
    2. localZOrder 是用于父节点的子节点数组中给 节点 对象排序的
  4. 设置颜色 setColor(Color3B::RED);
  5. 清空颜色 setColor(Color3B::WHITE);
  6. 获取锚点对应坐标 Vec2::ANCHOR_BOTTOM_LEFT
  7. 菜单按钮绑定 CC_CALLBACK_1(MyClass::func, this)
  8. 获取屏幕大小 Director::getInstance()->getWinSize()
  9. 获取屏幕可视区域 Director::getInstance()->getOpenGLView()->getVisibleRect()
  10. 获得触碰点的世界坐标系
    1. convertToWorldSpace(convertToNodeSpace(pTouch->getLocation()))
    2. convertToWorldSpace(convertTouchToNodeSpace(pTouch))
    3. 触控点还取决于glview->setDesignResolutionSize和director->setContentScaleFactor

ActionManager:

  1. VisibleRect 屏幕可以获得屏幕的指定位置点, 可以获得屏幕的大小
  2. 同时可并行执行多条 action
  3. CC_CALLBACK_0 调用函数指针, 执行参数为0的函数
  4. CC_CALLBACK_1 执行参数为1的函数
  5. removeChild 可以remove 自身
  6. Director::getInstance()->getActionManager()->addAction(action, target, true); 另外一种添加动作的方式, 第三个参数为不自动执行
  7. Director::getInstance()->getActionManager()->resumeTarget(target); 回复执行对象动作
  8. Director::getInstance()->getActionManager()->pauseTarget(target); 设置后对象即使添加新的动作也无法执行
  9. schedule(CC_SCHEDULE_SELECTOR(MyClass::funct), 3); 每三秒执行一次
    8.unschedule(CC_SCHEDULE_SELECTOR(MyClass::funct)); 停止循环执行函数
  10. 在执行动作的过程中调用函数, 并终止动作, 不会导致crash
  11. action的tag可以重复, 可通过sprite->stopAllActionsByTag(kTag); 删除多个动作, 而且可以保留其他动作继续执行

Action

  1. actionBy->reverse() 可以创建相对运动的逆运动
  2. target->setPosition3D(Vec3(40, 40, 0)); 伪3d, z负责缩放, moveBy moveTo 同样支持
  3. SkewTo可以创造3d翻转
  4. target->ignoreAnchorPointForPosition(false); 不忽略锚点
  5. JumpBy::create(time, targetPosition, high, jumpTimes);
  6. PointArray->addControlPoint(Vec2(0, 0)); 点数组存储点
  7. DrawNode->drawCardinalSpline(pointArray,0,100,Color4F(1.0, 0.0, 1.0, 1.0));
  8. CardinalSplineBy::create(3, array, 1); 按照点以及点的张力运动
  9. CatmullRomBy::create(3, array); 非封闭点运动
  10. CallFunc::create(std::bind(&TargetClass::funct,this, param) ) 绑定函数, 这样可以传递参数, 也支持数值类型
    CallFuncN::create( CC_CALLBACK_1(ActionCallFuncN::callback, this))
    CallFunc::create( std::bind(&ActionCallFunction::callback1, this) )
    CallFunc::create( std::bind(&ActionCallFunction::callback2, this, _tamara) )
    CallFunc::create( std::bind(&ActionCallFunction::callback3, this, _kathia, 42) )
  11. CallFuncND 不再需要, 已经被std::bind()替代
  12. sequence 序列 可以支持reverse翻转
  13. OrbitCamera 轨道动作
  14. this->runAction(Follow::create(target, Rect(0, 0, s.width * 2 - 100, s.height))); 舞台镜头跟踪对象
  15. TargetedAction::create(target, jump2) 混合其他对象动作到当前动作中, 支持reverse
  16. this->schedule([&](float dt) { log(“dealing”);},5 ,false ,0, “key”); 延迟函数(函数内容, 周期间距, 重复次数, 延迟, key)
  17. scheduleOnce([&](float dt) { log(“dealing”);},2 ,”key”);
  18. auto actionFloat = ActionFloat::create(2.f, 0, 3, [this](float value) { target->setScale(value); }); 无需自定义变量, 设置临时数值变化
  19. action->clone() 再也不需要去写autorelease, 已经被包含在clone内部, 非常方便
  20. Scheduler 的 timeScale 可以正倒放动作

ProgressBar

  1. 已支持SpriteFrame方式进度条
 auto s = Director::getInstance()->getWinSize();
    auto to = Sequence::createWithTwoActions(ProgressTo::create(6, 100), ProgressTo::create(0, 0));
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("zwoptex/grossini.plist");
    auto left = ProgressTimer::create(Sprite::createWithSpriteFrameName("grossini_dance_01.png"));
    //ProgressTimer::Type::RADIAL/BAR
    left->setType(ProgressTimer::Type::BAR);
    //radial模式设置为逆时针旋转
    //left->setReverseProgress(true);
    left->setMidpoint(Vec2(0.5f, 0.5f));
    left->setBarChangeRate(Vec2(1, 0));
    addChild(left);
    left->setPosition(100, s.height/2);
    left->runAction(RepeatForever::create(to->clone()));

sound & music

  1. 我能了解到的是v2.x版本的苦恼, 原因是2.x版本的sfx在loop的时候100%无法回收停止音效, 应该在v3.x版本里面有所修正, 待证实

camera

  1. 创建camera: auto camera = Camera::create();
    camera->setCameraFlag(CameraFlag::USER1);
    addChild(camera);
  2. 默认当前场景会有一个defaultCamera
  3. camera对象虽然也是被添加在node环节中, 但是他的层级关系只跟设置的CameraFlag有关系, 数值越大越在前端显示
  4. 在设置一个node节点整体为一个camera的内容时, 如果想把子节点都设置为此camera的内容, 则最好在所有addchild完成后再设置setCameraMask((unsigned short)CameraFlag::USER1)
  5. 参考链接

cocos2d 信息

  1. 读取plist信息 Configuration::getInstance()->loadConfigFile("configs/config-test-ok.plist")
  2. 获取信息 Configuration::getInstance()->getInfo()
  3. cocos2dx版本 Configuration::getInstance()->getValue("cocos2d.x.version") //cocos2d-x-3.7
  4. openGL版本 Configuration::getInstance()->getValue("gl.version") //OpenGL ES 2.0 IMGSGX543-113.3.1
  5. 获取无效值后会得到默认值 Configuration::getInstance()->getValue("invalid.key", Value("defaultStrValue"))
  6. 获取国家 Application::getInstance()->getCurrentLanguage() //LanguageType::CHINESE
  7. 获取国家码 Application::getInstance()->getCurrentLanguageCode() //zh

Touch 触摸绑定

  1. EventListenerTouch 触摸事件侦听
  2. EventListenerKeyboard 键盘事件侦听
  3. EventListenerAcceleration 加速器事件侦听
  4. EventListenMouse 鼠标事件侦听
  5. EventListenerCustom 自定义事件侦听
  6. 回调函数
    1. lambda方式cpp11
      1. [](int x, int y) { return x + y; } // 隐式返回类型
      2. [](int& x) { ++x; } // 没有return语句 -> lambda 函数的返回类型是'void'
      3. []() { ++global_x; } // 没有参数,仅访问某个全局变量
      4. []{ ++global_x; } // 与上一个相同,省略了()
      5. [] //未定义变量.试图在Lambda内使用任何外部变量都是错误的.
      6. [x, &y] //x 按值捕获, y 按引用捕获.
      7. [&] //用到的任何外部变量都隐式按引用捕获
      8. [=] //用到的任何外部变量都隐式按值捕获
      9. [&, x] //x显式地按值捕获. 其它变量按引用捕获
      10. [=, &z] //z按引用捕获. 其它变量按值捕获
      11. 以上参考链接
      12. listener->onTouchBegan = [=](Touch* touch, Event* event){
        return true;
        };
        listener->onTouchEnded = [=](Touch* touch, Event* event){
        };
    2. CC_CALLBACK_N宏回调方式
      1. 10.
  7. 事件侦听器派发
    1. _eventDispatcher是Node的一个属性,使用它来管理当前节点(Scene, Layer和Sprite)不同事件的分配
    2. 使用clone()方法是因为每一个事件监听器只能被添加一次
    3. 如果是固定优先值的监听器添加到一个节点(addEventListenerWithFixedPriority),那当这个节点被移除时必须同时手动移除这个监听器,但是添加场景图优先监听器到节点(addEventListenerWithSceneGraphPriority)就不用这么麻烦,监听器和节点是绑定好的,一旦节点的析构函数被调用,监听器也会同时被移除
    4. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
      _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
      _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);
    5. FixedPriority和SceneGraphPriority
      1. FixedPriority 整形值。低权值的事件监听器将优于高权值的事件监听器
      2. SceneGraphPriority Node的指针。Node的z顺序高的(绘制于顶部的)节点将优于z顺序低的节点。这将保证了诸如触碰事件的自顶向下传播
  8. 键盘

    1. `auto listener = EventListenerKeyboard::create();
      listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this);
      listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this);

    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

    // Implementation of the keyboard event callback function prototype
    void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event)
    {
    log(“Key with keycode %d pressed”, keyCode);
    }

    void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
    {
    log(“Key with keycode %d released”, keyCode);
    } `

  9. 加速计事件

    1. `auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(AccelerometerTest::onAcceleration, this));
      _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

    // Implementation of the accelerometer callback function prototype
    void AccelerometerTest::onAcceleration(Acceleration* acc, Event* event)
    {
    // Processing logic here
    }`

  10. 鼠标事件(v3新增)

    1. `_mouseListener = EventListenerMouse::create();
      _mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this);
      _mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this);
      _mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this);
      _mouseListener->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll, this);

    _eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);`

  11. 自定义事件
    1. _listener = EventListenerCustom::create("game_custom_event1", [=](EventCustom* event){
      std::string str("Custom event 1 received, ");
      char* buf = static_cast<char*>(event->getUserData());
      str += buf;
      str += " times";
      statusLabel->setString(str.c_str());
      });
      _eventDispatcher->addEventListenerWithFixedPriority(_listener, 1);
    2. 事件触发
      1. static int count = 0;
        ++count;
        char* buf = new char[10];
        sprintf(buf, "%d", count);
        EventCustom event("game_custom_event1");
        event.setUserData(buf);
        _eventDispatcher->dispatchEvent(&event);
        CC_SAFE_DELETE_ARRAY(buf);
    3. 事件移除
      1. 移除单独侦听器 _eventDispatcher->removeEventListener(listener);
      2. 移除所有侦听起, 如果在同一语句下新增了新的事件, 那么全部删除语句并不会影响到下一步操作 _eventDispatcher->removeAllEventListeners();
  12. 创建单一事件侦听器
    1. EventListenerTouchOneByOne::create()
  13. 其他
    1. 触碰点转换为位置点
    2. Vec2 locationInNode = this->convertToNodeSpace(touch->getLocation());
    3. 检测是否点击区域
    4. Size s = target->getContentSize();
      Rect rect = Rect(0, 0, s.width, s.height);
      if (rect.containsPoint(locationInNode))
    5. 拖动物体跟随移动
    6. auto target = static_cast<Sprite*>(event->getCurrentTarget());
      target->setPosition(target->getPosition() + touch->getDelta());
  14. 事件优先级
    1. 如果设置了优先级, 那么这个触碰就和addchild层级没关系了, 不设置是默认随层级走的, 层级越高, 越靠近camera越容易被触碰, 而如果设置了优先级, 不管你child层级如何, 都按照指定优先级来, 优先级priority是按照从小到大数字来排列先后点击的
    2. 使用优先级调用的是addEventListenerWithFixedPriority方法, 所以必须手动回收
    3. //使用优先级
      _eventDispatcher->addEventListenerWithFixedPriority(listener, _fixedPriority);
      //不使用优先级
      _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
  15. 移除和添加事件
    1. 移除 _eventDispatcher->removeEventListener(listener1);
    2. 移除指定类型 _eventDispatcher->removeEventListenersForType(EventListener::Type::TOUCH_ONE_BY_ONE);
    3. 添加 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
  16. 在添加事件后, 对象retain并移除, 再次出现时是可以继续执行触碰操作的. 给的例子来看, 在隐藏后显示, 未松开手指拖动, 还是会直接触碰touchmove事件, 这点需要注意
  17. direct事件
    1. 更新 Director::EVENT_AFTER_UPDATE
    2. 访问 Director::EVENT_AFTER_VISIT
    3. 绘制 Director::EVENT_AFTER_DRAW
    4. 投影 Director::EVENT_PROJECTION_CHANGED
    5. 通过 Director::getInstance()->getEventDispatcher() 的 addCustomEventListener 方式来添加事件
    6. 绑定函数 std::bind(&DirectorEventTest::onEvent1, this, std::placeholders::_1)
    7. 绑定匿名函数 [&](EventCustom *event) {}
  18. 多点触摸
    1. EventListenerTouchAllAtOnce
    2. 获得第一个点击的点 touches[0]
  19. 暂停和恢复事件
    1. 暂停
    2. _eventDispatcher->pauseEventListenersForTarget(this, true); //参数2为是否递归
    3. 恢复
    4. _eventDispatcher->resumeEventListenersForTarget(this, true); //参数2为是否递归
  20. 一次性事件 removeListenerOnTouchEnded(true); //触摸结束不再接收触摸

引擎扩展

  1. 动态下载 参照 AssetsManagerExTest 事例
  2. 滑动条 参照 CCControlSliderTest 事例
  3. 取色器 参照 ControlColourPickerTest 事例
  4. 开关 参照 ControlSwitchTest 事例
  5. 色彩文字按钮 参照 ControlButtonTest 事例
  6. 音量旋钮 参照 ControlPotentiometerTest 事例
  7. 加减按钮 参照 CCControlStepperTest 事例
  8. ccbi界面 参照 CocosBuilderTest 事例
  9. 滚动界面 参照 TableViewTest 事例
  10. 图片加密 参照 Texure Atlas Encryption 事例

材质特效

  1. 创建滤镜
    1. auto properties = Properties::createNonRefCounted("Materials/2d_effects.material#sample");
      Material *mat1 = Material::createWithProperties(properties);
  2. 模糊特效
    1. spriteBlur->setNormalizedPosition(Vec2(0.2f, 0.5f));
      spriteBlur->setGLProgramState(mat1->getTechniqueByName("blur")->getPassByIndex(0)->getGLProgramState());
  3. 外发光
    1. spriteOutline->setNormalizedPosition(Vec2(0.4f, 0.5f));
      spriteOutline->setGLProgramState(mat1->getTechniqueByName("outline")->getPassByIndex(0)->getGLProgramState());
  4. 噪点
    1. spriteNoise->setNormalizedPosition(Vec2(0.6f, 0.5f));
      spriteNoise->setGLProgramState(mat1->getTechniqueByName("noise")->getPassByIndex(0)->getGLProgramState());
  5. 边缘检测
    7.spriteEdgeDetect->setNormalizedPosition(Vec2(0.8f, 0.5f));
    spriteEdgeDetect->setGLProgramState(mat1->getTechniqueByName("edge_detect")->getPassByIndex(0)->getGLProgramState());
  6. 效果拖尾
    1. 参考 Node: MotionStreak 支持色彩和贴图拖尾
  7. 物理引擎 参考 Node: Physics / 3D
    1. 屋里引擎 关节 参考 Joints
    2. action和物理引擎的互相影响 Actions
    3. 只处理单面碰撞 One Way Platform
    4. 切割 Slice

数据存储

参考
cocos2d-x中几种存储数据的方式

向量等

参考:
总结数学类Vec2/Size/Rect

参考链接:

总结Cocos2d-x 3.x版本的一些变化

Value、Vector和Map的认识

ps: v4都出了泪奔了~~~

ValueMap的一般使用

cocos2dx v3的一些特色功能:

  • Auto-batching
    在3.0版本实现了引擎的逻辑代码与渲染代码的分离,实现了Auto Batch与Auto Culling功能。不再推荐使用SpriteBatchNode提高精灵的绘制效率。
    Auto-culling的支持,Sprite在绘制时会进行检查,超出屏幕的不会发给渲染。
    Auto-batching拥有更好的性能提升。

  • Auto-batching的渲染流程

    • drawScene开始绘制场景
    • 遍历场景的子节点,调用visit函数,递归遍历子节点的子节点,以及子节点的子节点的子节点,以及…
    • 对每一个子节点调用draw函数
    • 初始化QuadCommand对象,这就是渲染命令,会丢到渲染队列里
    • 丢完QuadCommand就完事了,接着就交给渲染逻辑处理了。
    • 是时候轮到渲染逻辑干活干活,遍历渲染命令队列,这时候会有一个变量,用来保存渲染命令里的材质ID,遍历过程中就拿当前渲染命令的材质ID和上一个的材质ID对比,如果发现是一样的,那就不进行渲染,保存一下所需的信息,继续下一个遍历。好,如果这时候发现当前材质ID和上一个材质ID不一样,那就开始渲染,这就算是一个渲染批次了。
    • 因此,如果我们创建了10个材质相同的对象,但是中间夹杂了一个不同材质的对象,假设它们的渲染命令在队列里的顺序是这样的:2个A,3个A,1个B,1个A,2个A,2个A。那么前面5个相同材质的对象A会进行一次渲染,中间的一个不同材质对象B进行一次渲染,后面的5个相同材质的对象A又进行一次渲染。一共会进行三次批渲染。

http://www.cocos.com/doc/tutorial/show?id=784

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值