CocoStudio sample讲解 SampleCollision骨骼动画与简单碰撞

文章转载自:http://www.cocoachina.com/bbs/read.php?tid=189665

CocoStuido sample----SampleCollision源代码地址  
https://github.com/chukong/CocoStudioSamples  
大家可以预先下载这个源代码, 等下要用到里面的图片资源哦  
今天我们再来学习下骨骼动画在CocoStudio中的制作. 骨骼动画由各个关节有机的结合起来, 并附着以皮肤. 当关节运动时, 相关的关节会一起运动, 以达到更加真实的动画效果.  

代码实现  

我们要在cocos2d-x工程中实现两个牛仔, 一个走路, 一个打枪, 子弹和牛仔碰撞后, 牛仔消失一下.  
代码中包含了普通, box2d, chipmunk三种碰撞判断, box2d, chipmunk这两种判断方式太过复杂, 我们这次就不再展开了, 只带大家看下普通的碰撞判断.  
我们创建一个TestColliderDetector类, 包含TestColliderDetector.h 和 TestColliderDetector.cpp.  
先来看下TestColliderDetector.h  

#include "cocos2d.h"
#include "cocos-ext.h"
 
class TestColliderDetector : public cocos2d:: CCLayer
{
public :
                ~TestColliderDetector();
  
                 virtual void onEnter();
                 virtual void update( float delta); //检测对象位置,判断是否有碰撞
                 virtual void draw(); //绘制右边牛仔的碰撞区域
  
                 //帧事件响应函数
                 void onFrameEvent(cocos2d::extension:: CCBone *bone, const char *evt, int originFrameIndex, intcurrentFrameIndex);
 
                 //左边牛仔对象
                cocos2d::extension:: CCArmature *armature;
                 //右边牛仔对象
                cocos2d::extension:: CCArmature *armature2;
                 //子弹对象
                cocos2d:: CCSprite * bullet;
};

TestColliderDetector.cpp   

#include "TestColliderDetector.h"
 
using namespace cocos2d;
using namespace cocos2d::extension;
 
TestColliderDetector ::~TestColliderDetector()
{
                 //CCArmatureDataManager::purge();
}
void TestColliderDetector ::onEnter()
{
                 CCLayer ::onEnter();
                scheduleUpdate(); //每帧都会调用update函数, 用于碰撞判断
  
                 //加载动画数据
                 CCArmatureDataManager ::sharedArmatureDataManager()->addArmatureFileInfo( "Cowboy0.png","Cowboy0.plist" , "Cowboy.ExportJson");
 
                 //左边牛仔对象
                armature = CCArmature ::create("Cowboy" );
                armature->getAnimation()->play( "FireWithoutBullet" );//播放FireWithoutBullet动画
                armature->getAnimation()->setSpeedScale(0.2f); //以0.2倍的速度播放, 牛仔动作会比较慢
                armature->setScaleX(-0.2f); //缩放牛仔, 并且让牛仔脸向右
                armature->setScaleY(0.2f);
                armature->setPosition( ccp (CCDirector ::sharedDirector()->getVisibleSize().width * 0.2, CCDirector ::sharedDirector()->getVisibleSize().height * 0.5));
  
                 //给左边牛仔对象绑定对象
                armature->getAnimation()->setFrameEventCallFunc( this , frameEvent_selector (TestColliderDetector ::onFrameEvent));
  
                addChild(armature);
  
                 //右边牛仔对象
                armature2 = cocos2d::extension:: CCArmature ::create("Cowboy" );
                armature2->getAnimation()->play( "Walk" );//播放Walk动画
                armature2->setScaleX(-0.2f); //缩放牛仔, 并且让牛仔脸向右
                armature2->setScaleY(0.2f);
                armature2->setPosition( ccp (CCDirector ::sharedDirector()->getVisibleSize().width * 0.8, CCDirector ::sharedDirector()->getVisibleSize().height * 0.5));
                addChild(armature2);
 
                 //创建子弹对象
                bullet = CCSprite ::createWithSpriteFrameName("25.png" );
                addChild(bullet);
}
 
//我们刚才在编辑器中设置的帧事件会调用这个函数
void TestColliderDetector ::onFrameEvent( CCBone * bone , const char * evt, int originFrameIndex, intcurrentFrameIndex )
{
    //获取武器所在节点的坐标
                 CCPoint p = armature->getBone("gun" )->getDisplayRenderNode()->convertToWorldSpaceAR( ccp (0, 0));
  
                 //设置子弹的坐标
                bullet->setPosition( ccp (p.x + 60, p.y));
                bullet->stopAllActions();
                 //子弹向右运动
                bullet->runAction( CCMoveBy ::create(2.5f, ccp (CCDirector ::sharedDirector()->getVisibleSize().width, 0)));
}
 
void TestColliderDetector ::update( float delta)
{
                 //先设置右边牛仔对象可见
                armature2->setVisible( true );
 
                 //获取子弹的boundingBox区域, 用于碰撞检测
    CCRect rect = bullet->boundingBox();
 
    //逐一判断左边牛仔子节点中碰撞区域, 是否与子弹有相交之处
    CCDictElement *element = NULL ;
    CCDictionary *dict = armature2->getBoneDic();
    CCDICT_FOREACH(dict, element)
    {
        CCBone *bone = static_cast < CCBone*>(element->getObject());
        CCArray *bodyList = bone->getColliderBodyList();
 
        CCObject *object = NULL ;
        CCARRAY_FOREACH (bodyList, object)
        {
            ColliderBody *body = static_cast < ColliderBody*>(object);
            CCArray *vertexList = body->getCalculatedVertexList();
 
            float minx, miny, maxx, maxy = 0;
            int length = vertexList->count();
            for (int i = 0; i<length; i++)
            {
                CCContourVertex2 *vertex = static_cast < CCContourVertex2*>(vertexList->objectAtIndex(i));
                if (i == 0)
                {
                  minx = maxx = vertex->x;
                  miny = maxy = vertex->y;
                }
                else
                {
                    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;
                }
            }
            CCRect temp = CCRectMake (minx, miny, maxx - minx, maxy - miny);
 
            if (temp.intersectsRect(rect))
            {
                                                                 //与子弹相交隐藏右边牛仔
                armature2->setVisible( false );
            }
        }
    }
}
 
//绘制右边牛仔的碰撞区
void TestColliderDetector ::draw()
{
                armature2->drawContour();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值