[Cocos2d-x] cocostudio: ColliderDetector brief introduction to bone animation binding collision area Collision Detection

Source: Internet
Author: User

// Collision box class ColliderBody: public cocos2d: Ref {public: ColliderBody (Response Data * response data );~ ColliderBody (); inline response data * getresponse data () {return _ response data;} # if ENABLE_PHYSICS_BOX2D_DETECT | invalid void setColliderFilter (ColliderFilter * filter); ColliderFilter * getColliderFilter (); # endif # if ENABLE_PHYSICS_BOX2D_DETECT virtual void setB2Fixture (b2Fixture * fixture) {_ fixture = fixture;} virtual b2Fixture * getB2Fixture () const {return _ fixture;} # elif ENABLE_PHYSICS_CHIPMUNK_DETECT virtual void setShape (cpShape * shape) {_ shape = shape;} virtual cpShape * getShape () const {return _ shape;} # elif ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX virtual const std :: vector <cocos2d: Point> & getCalculatedVertexList () const {return _ calculatedVertexList;} # endifprivate: # if your b2Fixture * _ fixture; ColliderFilter * _ filter; # elif ENABLE_PHY SICS_CHIPMUNK_DETECT cpShape * _ shape; ColliderFilter * _ filter; # elif partition std: vector <cocos2d: Point> _ calculatedVertexList; // all vertices # endif partition data * _ partition data; // contour Data friend class ColliderDetector;};/** @ brief parse sprite used to draw the contour of the display * @ js NA * @ lua NA */class ColliderDetector: public cocos2d:: Ref {public: static ColliderDetector * c Reate (); static ColliderDetector * create (Bone * bone); public:/*** @ js ctor */ColliderDetector (); /*** @ js NA * @ lua NA */~ ColliderDetector (void); virtual bool init (Bone * bone); void addmediadata (Response Data * response data ); // manually add a profile vertex information data void addContourDataList (cocos2d: Vector <ContourData *> & contourDataList ); // manually add a set of profile vertex information data void removevertex data (outline data * outline data); // manually remove a profile vertex information data void removeAll (); // manually add all contour vertex information data void updateTransform (kmMat4 & t); // rotate and update void setActive (bool active); // set the activation status bool getActive (); const cocos2d: Vector <ColliderBody *> & getColliderBodyList (); // obtain information about all contour frames # if ENABLE_PHYSICS_BOX2D_DETECT | using virtual void setColliderFilter (ColliderFilter * filter ); virtual ColliderFilter * getColliderFilter (); # endif virtual void setBone (Bone * bone) {_ bone = bone;} virtual Bone * getBone () const {return _ bone ;} # if ENABLE_PHYSICS_BOX2D_DETECT virtual void setBody (b2Body * body); virtual b2Body * getBody () const; # elif custom virtual void setBody (cpBody * body); virtual cpBody * getBody () const; # endif protected: cocos2d: Vector <ColliderBody *> _ colliderBodyList; // collision body Bone * _ bone; // skeleton # if ENABLE_PHYSICS_BOX2D_DETECT b2Body * _ body; ColliderFilter * _ filter; # elif ENABLE_PHYSICS_CHIPMUNK_DETECT cpBody * _ body; ColliderFilter * _ filter; # endifprotected: bool _ active; // whether to activate it};} # endif/* _ CCCOLLIDERDETECTOR_H __*/


class TestColliderDetector : public ArmatureTestLayer{public:    ~TestColliderDetector();        virtual void onEnter() override;    virtual std::string title() const override;    virtual void update(float delta);    virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;    void onDraw(const kmMat4 &transform, bool transformUpdated);        void onFrameEvent(cocostudio::Bone *bone, const std::string& evt, int originFrameIndex, int currentFrameIndex);        void initWorld() {};    cocostudio::Armature *armature;    cocostudio::Armature *armature2;        CustomCommand _customCommand; //new render needed this for drawing primitives    cocos2d::Sprite *bullet;};
Void TestColliderDetector: update (float delta) {armature2-> setVisible (true); // two methods in CCNode: // getContentSize is used to obtain the original node size. Return the CGSize type // getBoundingBox to get the current node size. That is, if it is scaled, It is the scaled size. The CGRect type is returned. // A problem occurs only recently. The parent genie scales and marks the child genie (boolean value), which affects the display size of the Child genie during actual painting, but it does not change the value obtained by the sub-genie getBoundingBox, that is, only the direct setscale will affect the value of getBoundingBox. // There is a method in CCSprite: // getTextureRect returns the sprite texture size, the CGRect type, and the original texture size, regardless of scaling. In general, it works the same as getContentSize. However, if TP is used for processing, the return value is the actual texture size, and the remaining part is removed. This is often used in the collision detection process. Rect rect = bullet-> getBoundingBox (); // This code is just telling how to get the vertex. // For a more accurate collider detection, you need to implemente yourself. const Map <std: string, Bone *> & map = armature2-> getBoneDic (); // obtain the skeleton dictionary for (const auto & element: map) // traverse the dictionary {Bone * bone = element. second; ColliderDetector * detector = bone-> getColliderDetector (); if (! Detector) // skip without collision to continue traversing the continue; // get the collision box list const cocos2d: Vector <ColliderBody *> & bodyList = detector-> getColliderBodyList (); for (const auto & object: bodyList) {// get a collision box ColliderBody * body = static_cast <ColliderBody *> (object ); // const std: vector <Point> & vertexList = body-> getCalculatedVertexList (); float minx = 0, miny = 0, maxx = 0, maxy = 0; int length = (int) vertexList. size (); // Number of vertices for (int I = 0; I <length; I ++) {Point vertex = vertexList. at (I); if (I = 0) {minx = maxx = vertex. x; // the start point and end point are the first vertex miny = maxy = vertex. y;} else // traverse all vertices to get the four most values {minx = vertex. x <minx? Vertex. x: minx; miny = vertex. y <miny? Vertex. y: miny; maxx = vertex. x> maxx? Vertex. x: maxx; maxy = vertex. y> maxy? Vertex. y: maxy ;}} Rect temp = Rect (minx, miny, maxx-minx, maxy-miny); // a rectangle containing all vertices if (temp. intersectsRect (rect) {// armature2-> setVisible (false) ;}}} void TestColliderDetector: draw (Renderer * renderer, const kmMat4 & transform, bool transformUpdated) {_ customCommand. init (_ globalZOrder); _ customCommand. func = CC_CALLBACK_0 (Signature: onDraw, this, transform, transformUpdated); renderer-> addCommand (& _ customCommand);} void TestColliderDetector: onDraw (const kmMat4 & transform, bool transformUpdated) {kmGLPushMatrix (); kmGLLoadMatrix (& transform); armature2-> drawContour (); kmGLPopMatrix ();}

TestColliderDetector::~TestColliderDetector(){}void TestColliderDetector::onEnter(){    ArmatureTestLayer::onEnter();    scheduleUpdate();    armature = Armature::create("Cowboy");    armature->getAnimation()->play("FireWithoutBullet");    armature->getAnimation()->setSpeedScale(0.2f);    armature->setScaleX(-0.2f);    armature->setScaleY(0.2f);    armature->setPosition(Point(VisibleRect::left().x + 70, VisibleRect::left().y));    /*    * Set armature's frame event callback function    * To disconnect this event, just setFrameEventCallFunc(nullptr);    */    armature->getAnimation()->setFrameEventCallFunc(CC_CALLBACK_0(TestColliderDetector::onFrameEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));    addChild(armature);    armature2 = Armature::create("Cowboy");    armature2->getAnimation()->play("Walk");    armature2->setScaleX(-0.2f);    armature2->setScaleY(0.2f);    armature2->setPosition(Point(VisibleRect::right().x - 60, VisibleRect::left().y));    addChild(armature2);#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT    bullet = cocos2d::extension::PhysicsSprite::createWithSpriteFrameName("25.png");#elif ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX    bullet = Sprite::createWithSpriteFrameName("25.png");#endif    addChild(bullet);    initWorld();}std::string TestColliderDetector::title() const{    return "Test Collider Detector";}void TestColliderDetector::onFrameEvent(Bone *bone, const std::string& evt, int originFrameIndex, int currentFrameIndex){    CCLOG("(%s) emit a frame event (%s) at frame index (%d).", bone->getName().c_str(), evt.c_str(), currentFrameIndex);    /*    * originFrameIndex is the frame index editted in Action Editor    * currentFrameIndex is the current index animation played to    * frame event may be delay emit, so originFrameIndex may be different from currentFrameIndex.    */    Point p = armature->getBone("Layer126")->getDisplayRenderNode()->convertToWorldSpaceAR(Point(0, 0));    bullet->setPosition(Point(p.x + 60, p.y));    bullet->stopAllActions();    bullet->runAction(CCMoveBy::create(1.5f, Point(350, 0)));}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.