【cocos2d-x】cocostudio::ColliderDetector 简单介绍 骨骼动画绑定碰撞区域进行碰撞检测
发布日期:2021-06-28 22:16:29 浏览次数:2 分类:技术文章

本文共 7617 字,大约阅读时间需要 25 分钟。

//碰撞框class ColliderBody : public cocos2d::Ref{public:    ColliderBody(ContourData *contourData);    ~ColliderBody();    inline ContourData *getContourData() { return _contourData; }#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT     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
&getCalculatedVertexList() const { return _calculatedVertexList; }#endifprivate:#if ENABLE_PHYSICS_BOX2D_DETECT b2Fixture *_fixture; ColliderFilter *_filter;#elif ENABLE_PHYSICS_CHIPMUNK_DETECT cpShape *_shape; ColliderFilter *_filter;#elif ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX std::vector
_calculatedVertexList;//所有顶点#endif ContourData *_contourData;//轮廓数据 friend class ColliderDetector;};/* * @brief ContourSprite used to draw the contour of the display * @js NA * @lua NA */class ColliderDetector : public cocos2d::Ref{public: static ColliderDetector *create(); static ColliderDetector *create(Bone *bone);public: /** * @js ctor */ ColliderDetector(); /** * @js NA * @lua NA */ ~ColliderDetector(void); virtual bool init(); virtual bool init(Bone *bone); void addContourData(ContourData *contourData);//手动添加 一个 轮廓顶点信息数据 void addContourDataList(cocos2d::Vector
&contourDataList);//手动添加 一组 轮廓顶点信息数据 void removeContourData(ContourData *contourData);//手动移除 一个 轮廓顶点信息数据 void removeAll();//手动添加 所有 轮廓顶点信息数据 void updateTransform(kmMat4 &t);//旋转更新 void setActive(bool active);//设置激活状态 bool getActive(); const cocos2d::Vector
& getColliderBodyList();//得到所有轮廓框信息#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT 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 ENABLE_PHYSICS_CHIPMUNK_DETECT virtual void setBody(cpBody *body); virtual cpBody *getBody() const;#endif protected: cocos2d::Vector
_colliderBodyList;//碰撞body Bone *_bone;//骨骼#if ENABLE_PHYSICS_BOX2D_DETECT b2Body *_body; ColliderFilter *_filter;#elif ENABLE_PHYSICS_CHIPMUNK_DETECT cpBody *_body; ColliderFilter *_filter;#endifprotected: bool _active;//是否激活};}#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);//// CCNode中两个个方法方法:// getContentSize用来获得节点原始大小。返回CGSize类型// getBoundingBox获得节点当前大小,即如果经过缩放那么就是缩放后的大小。返回CGRect类型。// 有个问题最近才遇到,父精灵进行缩放处理,会对子精灵进行标记(boolean值),在实际绘制过程中会影响子精灵显示大小,但并不改变子精灵的getBoundingBox所获得的值,也就是只有直接setscale才会影响getBoundingBox数值。// CCSprite中有个方法:// getTextureRect返回精灵纹理大小,返回CGRect类型,并且是原始纹理大小,无关缩放。在一般情况下和getContentSize作用一样,但如果用TP处理过,还回值是实际纹理大小,留白部分会去除。这个在碰撞检测过程中经常用到。 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
& map = armature2->getBoneDic();//得到骨骼字典 for(const auto& element : map)//遍历字典 { Bone *bone = element.second; ColliderDetector *detector = bone->getColliderDetector(); if (!detector)//如否没有碰撞 跳过 继续遍历 continue; //得到碰撞框列表 const cocos2d::Vector
& bodyList = detector->getColliderBodyList(); for (const auto& object : bodyList) { //得到一个碰撞框 ColliderBody *body = static_cast
(object); //一个碰撞框包含的所有顶点 const std::vector
&vertexList = body->getCalculatedVertexList(); float minx = 0, miny = 0, maxx = 0, maxy = 0; int length = (int)vertexList.size();//顶点个数 for (int i = 0; i
< 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);//组成一个包含所有顶点的矩形 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(TestColliderDetector::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)));}

转载地址:https://blog.csdn.net/yhhwatl/article/details/23924897 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【cocos2d-x】cocostudio::CCDate.h简单理解
下一篇:【IOS】In-App Purchases入门

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年03月31日 04时00分02秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

程序员如何解决中年危机?全网最具深度的三次握手、四次挥手讲解,附面试题答案 2019-04-29
程序员如何解决中年危机?难道Android真的凉了?再不刷题就晚了! 2019-04-29
程序员开发指南!全世界都在问Android开发凉了吗?大厂面试题汇总 2019-04-29
程序员深度学习!字节跳动Android面试全套真题解析在互联网火了,已拿offer 2019-04-29
程序员深度学习!读完我这份《Android开发核心源码精编解析》面试至少多要3K!面试真题解析 2019-04-29
程序员进阶知识点!系统盘点Android开发者必须掌握的知识点,Android面试题及解析 2019-04-29
看完我工资从12K变成了20K!Android开发者出路在哪?建议收藏 2019-04-29
看完直接怼产品经理!Android彻底组件化方案实践方法!送大厂面经一份! 2019-04-29
看完直接怼项目经理!只需一篇文章吃透Android多线程技术,成功定级腾讯T3-2 2019-04-29
看完老板就给加薪了!2021年Android春招面试经历,大厂面试题汇总 2019-04-29
看完豁然开朗!一位Android大牛的BAT面试心得与经验总结,含泪整理面经 2019-04-29
真是经典中的经典!身为一个安卓程序员Context都没弄明白?已拿offer 2019-04-29
真牛!全网最具深度的三次握手、四次挥手讲解,附面试题答案 2019-04-29
真香!为什么Android要采用Binder作为IPC机制?全套教学资料 2019-04-29
离开小厂进大厂的第一周,系统盘点Android开发者必须掌握的知识点,2年以上经验必看 2019-04-29
看完直接怼产品经理!从入门到精通系列Android高级工程师路线介绍,面试真题解析 2019-04-29
看完老板哭着让我留下来!Android性能优化最佳实践,含爱奇艺,小米,腾讯,阿里 2019-04-29
看完老板哭着让我留下来!Android高级架构进阶之数据传输与序列化,送大厂面经一份! 2019-04-29
看完老板就给加薪了!字节跳动正式启动2021届秋季校招!深度好文 2019-04-29
真是经典中的经典!Android多进程从头讲到尾,挥泪整理面经 2019-04-29