COCOS2DX,cocostudio::ColliderDetector 简单介绍 骨骼动画绑定碰撞区域进行碰撞检测

前端之家收集整理的这篇文章主要介绍了COCOS2DX,cocostudio::ColliderDetector 简单介绍 骨骼动画绑定碰撞区域进行碰撞检测前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
  1. /
  1. #ifndef __CCCOLLIDERDETECTOR_H__

    #define __CCCOLLIDERDETECTOR_H__

  2. #include "cocostudio/CCArmatureDefine.h"

    #include "cocostudio/CCDatas.h"

  3. #ifndef PT_RATIO

    #define PT_RATIO 32

    #endif

  4. #if ENABLE_PHYSICS_CHIPMUNK_DETECT

    #include "chipmunk.h"

    #elif ENABLE_PHYSICS_Box2D_DETECT

    #include "Box2D/Box2D.h"

    #endif

  5. namespace cocostudio {

  6. class Bone;

  7. /**

    * @js NA

    * @lua NA

    */

    class ColliderFilter

    {

    public:

    virtual ~ColliderFilter() { }

    #if ENABLE_PHYSICS_Box2D_DETECT

    public:

    ColliderFilter(uint16 categoryBits = 0x0001,uint16 maskBits = 0xFFFF,int16 groupIndex = 0);

    void updateShape(b2Fixture *fixture);

  8. virtual void setCategoryBits(uint16 categoryBits) { _categoryBits = categoryBits; }

    virtual uint16 getCategoryBits() const { return _categoryBits; }

  9. virtual void setMaskBits(uint16 maskBits) { _maskBits = maskBits; }

    virtual uint16 getMaskBits() const { return _maskBits; }

  10. virtual void setGroupIndex(int16 groupIndex) { _groupIndex = groupIndex; }

    virtual int16 getGroupIndex() const { return _groupIndex; }

    protected:

    uint16 _categoryBits;

    uint16 _maskBits;

    int16 _groupIndex;

    #elif ENABLE_PHYSICS_CHIPMUNK_DETECT

    public:

    ColliderFilter(cpCollisionType collisionType = 0,cpGroup group = 0);

    void updateShape(cpShape *shape);

  11. virtual void setCollisionType(cpCollisionType collisionType) { _collisionType = collisionType; }

    virtual cpCollisionType getCollisionType() const { return _collisionType; }

  12. virtual void setGroup(cpGroup group) { _group = group; }

    virtual cpGroup getGroup() const { return _group; }

    protected:

    cpCollisionType _collisionType;

    cpGroup _group;

    #endif

    };

  1. //碰撞框
  2. class ColliderBody : public cocos2d::Ref
  3. {
  4. public:
  5. ColliderBody(ContourData *contourData);
  6. ~ColliderBody();
  7.  
  8. inline ContourData *getContourData() { return _contourData; }
  9.  
  10. #if ENABLE_PHYSICS_Box2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT
  11. void setColliderFilter(ColliderFilter *filter);
  12. ColliderFilter *getColliderFilter();
  13. #endif
  14.  
  15. #if ENABLE_PHYSICS_Box2D_DETECT
  16. virtual void setB2Fixture(b2Fixture *fixture) { _fixture = fixture; }
  17. virtual b2Fixture *getB2Fixture() const { return _fixture; }
  18. #elif ENABLE_PHYSICS_CHIPMUNK_DETECT
  19. virtual void setShape(cpShape *shape) { _shape = shape; }
  20. virtual cpShape *getShape() const { return _shape; }
  21. #elif ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
  22. virtual const std::vector<cocos2d::Point> &getCalculatedVertexList() const { return _calculatedVertexList; }
  23. #endif
  24.  
  25. private:
  26.  
  27. #if ENABLE_PHYSICS_Box2D_DETECT
  28. b2Fixture *_fixture;
  29. ColliderFilter *_filter;
  30. #elif ENABLE_PHYSICS_CHIPMUNK_DETECT
  31. cpShape *_shape;
  32. ColliderFilter *_filter;
  33. #elif ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
  34. vector<cocos2d::Point> _calculatedVertexList;//所有顶点
  35. #endif
  36.  
  37. ContourData *_contourData;//轮廓数据
  38.  
  39. friend class ColliderDetector;
  40. };
  41.  
  42. /*
  43. * @brief ContourSprite used to draw the contour of the display
  44. * @js NA
  45. * @lua NA
  46. */
  47. class ColliderDetector : public cocos2d::Ref
  48. {
  49. public:
  50. static ColliderDetector *create();
  51. static ColliderDetector *create(Bone *bone);
  52. public:
  53. /**
  54. * @js ctor
  55. */
  56. ColliderDetector();
  57. /**
  58. * @js NA
  59. * @lua NA
  60. */
  61. ~ColliderDetector(void);
  62.  
  63. virtual bool init();
  64. virtual bool init(Bone *bone);
  65.  
  66. void addContourData(ContourData *contourData);//手动添加 一个 轮廓顶点信息数据
  67. void addContourDataList(cocos2d::Vector<ContourData*> &contourDataList);//手动添加 一组 轮廓顶点信息数据
  68.  
  69. void removeContourData(ContourData *contourData);//手动移除 一个 轮廓顶点信息数据
  70. void removeAll();//手动添加 所有 轮廓顶点信息数据
  71.  
  72. void updateTransform(kmMat4 &t);//旋转更新
  73.  
  74. void setActive(bool active);//设置激活状态
  75. bool getActive();
  76.  
  77. const cocos2d::Vector<ColliderBody*>& getColliderBodyList();//得到所有轮廓框信息
  78.  
  79. #if ENABLE_PHYSICS_Box2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT
  80. virtual void setColliderFilter(ColliderFilter *filter);
  81. virtual ColliderFilter *getColliderFilter();
  82. #endif
  83.  
  84. virtual void setBone(Bone *bone) { _bone = bone; }
  85. virtual Bone *getBone() const { return _bone; }
  86.  
  87. #if ENABLE_PHYSICS_Box2D_DETECT
  88. virtual void setBody(b2Body *body);
  89. virtual b2Body *getBody() const;
  90. #elif ENABLE_PHYSICS_CHIPMUNK_DETECT
  91. virtual void setBody(cpBody *body);
  92. virtual cpBody *getBody() const;
  93. #endif
  94. protected:
  95. cocos2d::Vector<ColliderBody*> _colliderBodyList;//碰撞body
  96.  
  97. Bone *_bone;//骨骼
  98.  
  99. #if ENABLE_PHYSICS_Box2D_DETECT
  100. b2Body *_body;
  101. ColliderFilter *_filter;
  102. #elif ENABLE_PHYSICS_CHIPMUNK_DETECT
  103. cpBody *_body;
  104. ColliderFilter *_filter;
  105. #endif
  106.  
  107. protected:
  108. bool _active;//是否激活
  109. };
  110.  
  111. }
  112.  
  113. #endif /*__CCCOLLIDERDETECTOR_H__*/
  1. class TestColliderDetector : public ArmatureTestLayer
  2. {
  3. public:
  4. ~TestColliderDetector();
  5. virtual void onEnter() override;
  6. virtual std::string title() const override;
  7. virtual void update(float delta);
  8. virtual void draw(Renderer *renderer,const kmMat4 &transform,bool transformUpdated) override;
  9. void onDraw(const kmMat4 &transform,bool transformUpdated);
  10. void onFrameEvent(cocostudio::Bone *bone,const std::string& evt,int originFrameIndex,int currentFrameIndex);
  11. void initWorld() {};
  12. cocostudio::Armature *armature;
  13. cocostudio::Armature *armature2;
  14. CustomCommand _customCommand; //new render needed this for drawing primitives
  15. cocos2d::Sprite *bullet;
  16. };
  1. void TestColliderDetector::update(float delta)
  2. {
  3. armature2->setVisible(true);
  4. //
  5. // CCNode中两个个方法方法
  6. // getContentSize用来获得节点原始大小。返回CGSize类型
  7. // getBoundingBox获得节点当前大小,即如果经过缩放那么就是缩放后的大小。返回CGRect类型。
  8. // 有个问题最近才遇到,父精灵进行缩放处理,会对子精灵进行标记(boolean值),在实际绘制过程中会影响子精灵显示大小,但并不改变子精灵的getBoundingBox所获得的值,也就是只有直接setscale才会影响getBoundingBox数值。
  9. // CCSprite中有个方法
  10. // getTextureRect返回精灵纹理大小,返回CGRect类型,并且是原始纹理大小,无关缩放。在一般情况下和getContentSize作用一样,但如果用TP处理过,还回值是实际纹理大小,留白部分会去除。这个在碰撞检测过程中经常用到。
  11. Rect rect = bullet->getBoundingBox();
  12.  
  13. // This code is just telling how to get the vertex.
  14. // For a more accurate collider detection,you need to implemente yourself.
  15. const Map<std::string,Bone*>& map = armature2->getBoneDic();//得到骨骼字典
  16. for(const auto& element : map)//遍历字典
  17. {
  18. Bone *bone = element.second;
  19. ColliderDetector *detector = bone->getColliderDetector();
  20.  
  21. if (!detector)//如否没有碰撞 跳过 继续遍历
  22. continue;
  23. //得到碰撞框列表
  24. const cocos2d::Vector<ColliderBody*>& bodyList = detector->getColliderBodyList();
  25.  
  26. for (const auto& object : bodyList)
  27. {
  28. //得到一个碰撞框
  29. ColliderBody *body = static_cast<ColliderBody*>(object);
  30. //一个碰撞框包含的所有顶点
  31. const vector<Point> &vertexList = body->getCalculatedVertexList();
  32.  
  33. float minx = 0,miny = 0;
  34. int length = (int)vertexList.size();//顶点个数
  35. for (int i = 0; i<length; i++)
  36. {
  37. Point vertex = vertexList.at(i);
  38. if (i == 0)
  39. {
  40. minx = maxx = vertex.x;//起点和终点 是 第一个点
  41. miny = maxy = vertex.y;
  42. }
  43. else//遍历所有点 得到4个最值
  44. {
  45. minx = vertex.x < minx ? vertex.x : minx;
  46. miny = vertex.y < miny ? vertex.y : miny;
  47. maxx = vertex.x > maxx ? vertex.x : maxx;
  48. maxy = vertex.y > maxy ? vertex.y : maxy;
  49. }
  1. }
  2.       Rect temp = Rect(minx,miny,maxx - minx,maxy - miny);//组成一个包含所有顶点的矩形
  3.       if (temp.intersectsRect(rect))
  4.       {
  5.         //子弹矩形在碰撞区域内 碰撞框不可见
  6.         armature2->setVisible(false);
  7.       }
  8.     }
  9.   }
  10. }
  11. void TestColliderDetector::draw(Renderer *renderer,bool transformUpdated)
  12. {
  13.   _customCommand.init(_globalZOrder);
  14.   _customCommand.func = CC_CALLBACK_0(TestColliderDetector::onDraw,this,transform,transformUpdated);
  15.   renderer->addCommand(&_customCommand);
  16. }
  17. void TestColliderDetector::onDraw(const kmMat4 &transform,bool transformUpdated)
  18. {
  19.   kmGLPushMatrix();
  20.   kmGLLoadMatrix(&transform);
  21.   
  22.   armature2->drawContour();
  23.   
  24.   kmGLPopMatrix();
  25. }
    TestColliderDetector::~TestColliderDetector()
  26. {
  27. }
  28. void TestColliderDetector::onEnter()
  29. {
  30.   ArmatureTestLayer::onEnter();
  31.   scheduleUpdate();
  32.   armature = Armature::create("Cowboy");
  33.   armature->getAnimation()->play("FireWithoutBullet");
  34.   armature->getAnimation()->setSpeedScale(0.2f);
  35.   armature->setScaleX(-2f);
  36.   armature->setScaleY(2f);
  37.   armature->setPosition(Point(VisibleRect::left().x + 70,VisibleRect::left().y));
  38.   /*
  39.  * Set armature's frame event callback function
  40.  * To disconnect this event,just setFrameEventCallFunc(nullptr);
  41.  */
  42.   armature->getAnimation()->setFrameEventCallFunc(CC_CALLBACK_0(TestColliderDetector::onFrameEvent,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4));
  43.   addChild(armature);
  44.   armature2 = Armature::create("Cowboy");
  45.   armature2->getAnimation()->play("Walk");
  46.   armature2->setScaleX(-2f);
  47.   armature2->setScaleY(2f);
  48.   armature2->setPosition(Point(VisibleRect::right().x - 60,VisibleRect::left().y));
  49.   addChild(armature2);
  50. #if ENABLE_PHYSICS_Box2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT
  51.   bullet = cocos2d::extension::PhysicsSprite::createWithSpriteFrameName("25.png");
  52. #elif ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
  53.   bullet = Sprite::createWithSpriteFrameName(#endif
  54.   addChild(bullet);
  55.   initWorld();
  56. }
  57. std::string TestColliderDetector::title() const
  58. {
  59.   return "Test Collider Detector";
  60. }
  61. void TestColliderDetector::onFrameEvent(Bone *bone,const std::string& evt,int currentFrameIndex)
  62. {
  63.   CCLOG("(%s) emit a frame event (%s) at frame index (%d).",bone->getName().c_str(),evt.c_str(),currentFrameIndex);
  64.   /*
  65.  * originFrameIndex is the frame index editted in Action Editor
  66.  * currentFrameIndex is the current index animation played to
  67.  * frame event may be delay emit,so originFrameIndex may be different from currentFrameIndex.
  68.  */
  69.   Point p = armature->getBone("Layer126")->getDisplayRenderNode()->convertToWorldSpaceAR(Point(0));
  70.   bullet->setPosition(Point(p.x + y));
  71.   bullet->stopAllActions();
  72.   bullet->runAction(CCMoveBy::create(1.5f,Point(350,153)">0)));
  73. }
    参考原地址:http://www.tuicool.com/articles/bUz6BrM

猜你在找的Cocos2d-x相关文章