博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2dx 触摸测试四 Armature
阅读量:6078 次
发布时间:2019-06-20

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

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

就算往项目上靠靠吧,我项目里面要用到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 Test23     24     // optional25     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
(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());}

运行之,看看吧。

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

等着看论坛帖子下文吧:

 

 

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

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

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

 

 

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

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

 

 

 

 

 

转载于:https://www.cnblogs.com/hanhongmin/p/3496717.html

你可能感兴趣的文章
1、IOS开发--iPad之仿制QQ空间(登录界面搭建+登录逻辑实现)
查看>>
UIImagePickerController从拍照、图库、相册获取图片
查看>>
LeetCode-95. Unique Binary Search Trees II
查看>>
mysql存储过程procedure
查看>>
Mybatis学习——一对一关联表查询
查看>>
Linux kernel模块管理相关详解
查看>>
电量与电压 ,内阻与电压的关系;
查看>>
激活窗体
查看>>
iOS开发--使用RSA加密
查看>>
Linux模式设计系列( 内核与应用关联思考)
查看>>
【C#】1.3 WPF应用程序学习要点
查看>>
java 短信验证码===随机数
查看>>
Windows Server 2008 计划任务配置(任务计划程序)每分钟执行BAT
查看>>
【VNC】Linux环境VNC服务安装、配置与使用
查看>>
动态创建地图文档MXD并发布地图服务
查看>>
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
查看>>
单例模式讲解
查看>>
Linux权限管理(笔记)
查看>>
(笔记)电路设计(二)之串联匹配电阻的应用
查看>>
Linux下的grep搜索命令详解(二)
查看>>