cocos2dx 触摸测试四 Armature

我忘了我这篇测试的主要目的是干啥了...。

就算往项目上靠靠吧,我项目里面要用到CCArmature这个,给这个实现单指拖拽,双指缩放功能。

新建类MyArmature,和MySprite类似,如下:

MyArmature.h

 1 //

 2 //  MyArmature.h

 3 //  TouchesTest

 4 //

 5 //  Created by HanHongmin on 13-12-29.

 6 //

 7 //

 8 

 9 #ifndef __TouchesTest__MyArmature__

10 #define __TouchesTest__MyArmature__

11 

12 #include "cocos2d.h"

13 #include "cocos-ext.h"

14 using namespace cocos2d;

15 using namespace cocos2d::extension;

16 class MyArmature:public CCArmature,public CCTouchDelegate{

17 public:

18     static MyArmature* create(const char* name,int nPriority);

19     

20     virtual void onEnter();

21     virtual void onExit();

22     void draw();//for Test

23     

24     // optional

25     virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);

26     virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);

27     virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);

28     virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);

29     void setPriority(int nPriority);

30     int getPriority();

31 protected:

32     int _nPriority;

33 };

34 

35 #endif /* defined(__TouchesTest__MyArmature__) */
View Code

MyArmature.cpp

  1 //

  2 //  MyArmature.cpp

  3 //  TouchesTest

  4 //

  5 //  Created by HanHongmin on 13-12-29.

  6 //

  7 //

  8 

  9 #include "MyArmature.h"

 10 

 11 MyArmature* MyArmature::create(const char *name,int nPriority){

 12     MyArmature *armature = new MyArmature();

 13     if (armature && armature->init(name))

 14     {

 15         armature->setPriority(nPriority);

 16         armature->autorelease();

 17         return armature;

 18     }

 19     CC_SAFE_DELETE(armature);

 20     return NULL;

 21 }

 22 void MyArmature::setPriority(int nPriority){

 23     _nPriority = nPriority;

 24 }

 25 int MyArmature::getPriority(){

 26     return _nPriority;

 27 }

 28 

 29 void MyArmature::onEnter(){

 30     CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, _nPriority);//多点触控

 31     CCArmature::onEnter();

 32 }

 33 void MyArmature::onExit(){

 34     CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);

 35     CCArmature::onExit();

 36 }

 37 

 38 void MyArmature::draw(){

 39     CCArmature::draw();

 40     CCRect rect = this->boundingBox();

 41     

 42     ccDrawColor4B(255, 0, 0, 255);

 43     ccDrawRect(convertToNodeSpace(rect.origin), convertToNodeSpace(ccp(rect.getMaxX(), rect.getMaxY())));

 44 }

 45 

 46 

 47 // optional

 48 void MyArmature::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){

 49     //CCLog("ccTouchesBegan touches point count:%i",pTouches->count());

 50     CCLog("origin:%f,%f",this->boundingBox().origin.x,this->boundingBox().origin.y);

 51 }

 52 void MyArmature::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){

 53     //CCLog("ccTouchesMoved touches point count:%i",pTouches->count());

 54     CCDictionary* touchesDic = CCDictionary::create();

 55     CCSetIterator iter = pTouches->begin();

 56     CCRect rect = this->boundingBox();

 57     CCLog("rect:%f,%f",rect.size.width,rect.size.height);

 58     for (; iter != pTouches->end(); iter++){

 59         CCTouch* pTouch = (CCTouch*)(*iter);

 60         if(rect.containsPoint(pTouch->getLocation())){

 61             touchesDic->setObject(pTouch, CCString::createWithFormat("%d",pTouch->getID())->getCString());

 62         }

 63     }

 64     CCArray* keys = touchesDic->allKeys();

 65     //两个手指

 66     if (touchesDic->count() >= 2){

 67         //CCLog("****ccTouchesMoved*");

 68         CCArray* keys = touchesDic->allKeys();

 69         CCTouch *touch1 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString());

 70         CCTouch *touch2 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(1))->getCString());

 71         

 72         CCPoint p1End = touch1->getLocation();

 73         CCPoint p2End = touch2->getLocation();

 74         CCPoint p1Start = touch1->getPreviousLocation();

 75         CCPoint p2Start = touch2->getPreviousLocation();

 76         

 77         float startDistance = ccpDistance(p1Start,p2Start);

 78         float endDistance = ccpDistance(p1End,p2End);

 79         

 80         //CCLog("startDistance:%f,endDistance:%f",startDistance,endDistance);

 81         float scale = this->getScale()*(endDistance/startDistance);

 82         CCLog("scale %f",scale);

 83         if(scale<1.0f){

 84             scale = 1.0f;

 85         }else if(scale>3.0f){

 86             scale = 3.0f;

 87         }

 88         this->setScale(scale);

 89         

 90         pTouches->removeObject(touch1);

 91         pTouches->removeObject(touch2);

 92     }else if(touchesDic->count() ==1){//单点

 93         CCTouch *pTouch = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString());

 94         CCPoint start = pTouch->getPreviousLocation();

 95         CCPoint end = pTouch->getLocation();

 96         //计算位移,直接使用point充当position的话,会有偏差,比如点住图片的一角进行拖动,setPosition的时候是依据AnchorPoint进行设置的

 97         CCPoint sub = ccpSub(end, start);

 98         CCPoint newPosition = ccpAdd(this->getPosition(),sub);

 99         this->setPosition(newPosition);

100         

101         pTouches->removeObject(pTouch);

102     }

103 }

104 void MyArmature::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){

105     //CCLog("****ccTouchesEnded*");

106 }

107 void MyArmature::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent){

108     //CCLog("****ccTouchesCancelled*");

109 }
View Code

draw方法是测试用的,因为在测试时发现boundingBox的位置不准,所以把它描绘出来看看。后面再说这个吧。

HelloWorld的init方法

bool HelloWorld::init()

{

    if ( !CCLayer::init() )

    {

        return false;

    }

    CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("run.png", "run.plist", "run.xml");//加载动画资源

    MyArmature* armature = MyArmature::create("run",1);

    armature->setPosition(VisibleRect::center());

    armature->setScale(2.0f);

    this->addChild(armature,0);

    

    /**

    MySprite* pSprite2 = MySprite::create("Icon-114.png",2);//优先级数值越小越优先响应

    pSprite2->setPosition(VisibleRect::center());

    pSprite2->setScale(2.0f);

    this->addChild(pSprite2, 1);

     */

    

    MySprite* pSprite = MySprite::create("HelloWorld.png",0);

    pSprite->setPosition(VisibleRect::center());

    this->addChild(pSprite, 1);

    

    return true;

}

CCArmature是 cocos2dx 扩展包里的东西,别忘了下面两行

#include "cocos-ext.h"

using namespace cocos2d::extension;

然后就应该可以看看效果了。

是不是发现boundingBox不是想得那么回事?因为Armature中有子Armature的关系吧,我猜的。

在论坛发帖问了,还没得到回复,自己尝试hack了一下源码,没想到啊,还好使了。。。

修改CCArmature::boundingBox如下:

CCRect CCArmature::boundingBox()

{

    float minx, miny, maxx, maxy = 0;



    bool first = true;



    CCRect boundingBox = CCRectMake(0, 0, 0, 0);



    CCObject *object = NULL;

    CCARRAY_FOREACH(m_pChildren, object)

    {

        if (CCBone *bone = dynamic_cast<CCBone *>(object))

        {

            CCArmature* child = bone->getChildArmature();

            //CCRect r = bone->getDisplayManager()->getBoundingBox();//hack by HanHongmin 2013-12-29 CCRect r; if(child!=NULL){ r = child->boundingBox(); }else{ r = bone->getDisplayManager()->getBoundingBox(); } //hack finish



            if(first)

            {

                minx = r.getMinX();

                miny = r.getMinY();

                maxx = r.getMaxX();

                maxy = r.getMaxY();



                first = false;

            }

            else

            {

                minx = r.getMinX() < boundingBox.getMinX() ? r.getMinX() : boundingBox.getMinX();

                miny = r.getMinY() < boundingBox.getMinY() ? r.getMinY() : boundingBox.getMinY();

                maxx = r.getMaxX() > boundingBox.getMaxX() ? r.getMaxX() : boundingBox.getMaxX();

                maxy = r.getMaxY() > boundingBox.getMaxY() ? r.getMaxY() : boundingBox.getMaxY();

            }



            boundingBox.setRect(minx, miny, maxx - minx, maxy - miny);

        }

    }



    return CCRectApplyAffineTransform(boundingBox, nodeToParentTransform());

}

运行之,看看吧。

改的对不对我不知道哈,反正跟我要的效果差不多了。

等着看论坛帖子下文吧:

http://www.cocos2d-x.org/forums/6/topics/41700

http://www.cocoachina.com/bbs/read.php?tid=176727

 

 

恩,现在两个自定义类了,可能大家早就发现了,能够提取出来公共代码。

虽然复制粘贴不麻烦,但是我想,大多数程序员都应该有代码洁癖吧。。。

各位自行搞一搞吧,我尝试了一下不会弄T_T,谁弄好了告诉我一声。

 

 

还有一点,如果涉及到x轴Y轴单向翻转的话,缩放哪里要注意,X,Y要分开。

setScale方法会把scaleX和scaleY都设置了,相当于调用了setScaleX和setScaleY。

 

 

 

 

 

你可能感兴趣的:(cocos2dx)