接上一篇,CCMenu当作ScrollView的Item可能满足不了我现在的需求。
Item中先有个background框,分选中状态...还有个background,还有个CCArmature....
自定义一个类StaticItem继承自CCSprite和CCTouchDelegate
StaticItem.h
// // StaticItem.h // ScrollViewTest // // Created by HanHongmin on 14-1-2. // // #ifndef __ScrollViewTest__StaticItem__ #define __ScrollViewTest__StaticItem__ #include "cocos2d.h" #include "cocos-ext.h" using namespace cocos2d; using namespace cocos2d::extension; class StaticItem : public CCSprite,public CCTouchDelegate{ public: static StaticItem* create(const char *pszFileName); void onEnter(); void onExit(); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); // optional virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); bool isPointIn(const CCPoint &worldPoint); void draw(); }; #endif /* defined(__ScrollViewTest__StaticItem__) */
StaticItem.cpp
// // StaticItem.cpp // ScrollViewTest // // Created by HanHongmin on 14-1-2. // // #include "StaticItem.h" StaticItem* StaticItem::create(const char *pszFileName) { StaticItem *pobSprite = new StaticItem(); if (pobSprite && pobSprite->initWithFile(pszFileName)) { pobSprite->autorelease(); return pobSprite; } CC_SAFE_DELETE(pobSprite); return NULL; } void StaticItem::onEnter(){ CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,10,false); } void StaticItem::onExit(){ CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } bool StaticItem::isPointIn(const CCPoint &worldPoint){ CCPoint o = this->getParent()->convertToWorldSpace(this->boundingBox().origin); CCRect rect = CCRectMake(o.x, o.y, this->boundingBox().size.width, this->boundingBox().size.height); return rect.containsPoint(worldPoint); } bool StaticItem::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ if (this->isPointIn(pTouch->getLocation())) {//在范围内 CCLog("StaticItem::ccTouchBegan ***** in %d",this->getTag()); return true; }else{ CCLog("StaticItem::ccTouchBegan ##### out %d",this->getTag()); return false; } } // optional void StaticItem::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){ CCLog("StaticItem::ccTouchMoved"); } void StaticItem::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){ CCPoint p1 = pTouch->getLocation(); CCPoint p2 = pTouch->getStartLocation(); if(p1.x==p2.x&&p1.y==p2.y){ CCLog("StaticItem::ccTouchEnded 点击%d",this->getTag()); }else{ CCLog("StaticItem::ccTouchEnded 拖动%d",this->getTag()); } } void StaticItem::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent){ CCLog("StaticItem::ccTouchCancelled"); } void StaticItem::draw(){ CCSprite::draw(); CCRect box = this->boundingBox(); CCPoint p = this->getParent()->convertToWorldSpace(box.origin); CCRect rect = CCRectMake(p.x, p.y, box.size.width, box.size.height); ccDrawColor4B(255, 0, 0, 255); ccDrawRect(convertToNodeSpace(rect.origin), convertToNodeSpace(ccp(rect.getMaxX(), rect.getMaxY()))); }
以上红色部分是我遇到问题的部分,不getParent的话,你会发现draw描框永远在那里不跟着动。坐标是错的。
isPointIn方法中也是同样的道理,如果不的话,你会发现点到的永远是那一个item。
接着上代码
HelloWorldScene.h
1 #ifndef __HELLOWORLD_SCENE_H__ 2 #define __HELLOWORLD_SCENE_H__ 3 4 #include "cocos2d.h" 5 #include "cocos-ext.h" 6 #include "VisibleRect.h" 7 #include "MyScrollView.h" 8 #include "StaticItem.h" 9 using namespace cocos2d; 10 using namespace cocos2d::extension; 11 12 class HelloWorld : public CCLayer,public CCScrollViewDelegate 13 { 14 public: 15 virtual bool init(); 16 static cocos2d::CCScene* scene(); 17 void buttonClick(); 18 19 virtual void scrollViewDidScroll(CCScrollView* view); 20 virtual void scrollViewDidZoom(CCScrollView* view); 21 22 CREATE_FUNC(HelloWorld); 23 protected: 24 MyScrollView *_scrollView; 25 }; 26 27 #endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp
1 #include "HelloWorldScene.h" 2 3 USING_NS_CC; 4 5 CCScene* HelloWorld::scene() 6 { 7 CCScene *scene = CCScene::create(); 8 HelloWorld *layer = HelloWorld::create(); 9 scene->addChild(layer); 10 return scene; 11 } 12 13 // on "init" you need to initialize your instance 14 bool HelloWorld::init() 15 { 16 if ( !CCLayer::init() ) 17 { 18 return false; 19 } 20 CCSprite *bg = CCSprite::create("Default-568h@2x.png"); 21 bg->setPosition(VisibleRect::center()); 22 this->addChild(bg); 23 24 CCMenuItemImage *button = CCMenuItemImage::create("Icon-144.png", "Icon-144.png", this, menu_selector(HelloWorld::buttonClick)); 25 CCMenu *menu = CCMenu::create(button,NULL); 26 menu->setPosition(CCPointZero); 27 button->setPosition(ccp(VisibleRect::leftTop().x+72,VisibleRect::leftTop().y-72)); 28 this->addChild(menu); 29 30 CCLayer *container = CCLayer::create(); 31 container->setAnchorPoint(CCPointZero); 32 container->setPosition(CCPointZero); 33 34 StaticItem *item1 = StaticItem::create("HelloWorld0.png"); 35 item1->setTag(1); 36 item1->setPosition(ccp(VisibleRect::center().x,VisibleRect::center().y-300)); 37 CCSprite *sp1 = CCSprite::create("Icon-144.png"); 38 item1->addChild(sp1); 39 sp1->setPosition(ccp(240,160)); 40 container->addChild(item1); 41 42 StaticItem *item12 = StaticItem::create("HelloWorld0.png"); 43 item12->setTag(12); 44 item12->setPosition(ccp(VisibleRect::center().x,VisibleRect::center().y+300)); 45 CCSprite *sp12 = CCSprite::create("Icon-144.png"); 46 item12->addChild(sp12); 47 sp12->setPosition(ccp(240,160)); 48 container->addChild(item12); 49 50 StaticItem *item2 = StaticItem::create("HelloWorld1.png"); 51 item2->setTag(2); 52 item2->setPosition(ccp(VisibleRect::center().x + VisibleRect::right().x,VisibleRect::center().y )); 53 CCSprite *sp2 = CCSprite::create("Icon-144.png"); 54 item2->addChild(sp2); 55 sp2->setPosition(ccp(240,160)); 56 container->addChild(item2); 57 58 StaticItem *item3 = StaticItem::create("HelloWorld2.png"); 59 item3->setTag(3); 60 item3->setPosition(ccp(VisibleRect::center().x + VisibleRect::right().x * 2,VisibleRect::center().y )); 61 CCSprite *sp3 = CCSprite::create("Icon-144.png"); 62 item3->addChild(sp3); 63 sp3->setPosition(ccp(240,160)); 64 container->addChild(item3); 65 66 container->setContentSize(CCSizeMake(640*3, 1136));//重要,默认是屏幕大小,可以去看源码 67 CCLog("container contentsize:%f,%f",container->getContentSize().width,container->getContentSize().height); 68 69 70 _scrollView = MyScrollView::create(CCSizeMake(640, 1136)); 71 //_scrollView->setContentSize(); 72 _scrollView->setDelegate(this); 73 _scrollView->setTouchPriority(1); 74 _scrollView->setContainer(container); 75 _scrollView->setDirection(kCCScrollViewDirectionHorizontal); 76 77 this->addChild(_scrollView); 78 79 CCRect r1 = item1->boundingBox(); 80 CCRect r2 = item2->boundingBox(); 81 CCRect r3 = item3->boundingBox(); 82 CCLog("item3 boundingBox origin:%f,%f",r3.origin.x,r3.origin.y); 83 CCLog("item2 boundingBox origin:%f,%f",r2.origin.x,r2.origin.y); 84 CCLog("item1 boundingBox origin:%f,%f",r1.origin.x,r1.origin.y); 85 return true; 86 } 87 88 void HelloWorld::buttonClick(){ 89 CCLog("##########################buttonClick#"); 90 } 91 92 void HelloWorld::scrollViewDidScroll(CCScrollView* view){ 93 CCLog("scrollViewDidScroll"); 94 } 95 void HelloWorld::scrollViewDidZoom(CCScrollView* view){ 96 CCLog("scrollViewDidZoom"); 97 }
试之,在Item上点击,拖动,都是对的:)
----------------------------
补充:在真机上测试,对于判断是点击还是拖动,不是很理想,大多数情况都被判断成了拖动。
我们给他一个误差值,修改方法如下
void StaticItem::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){ CCPoint p1 = pTouch->getLocation(); CCPoint p2 = pTouch->getStartLocation(); if(abs(p1.x-p2.x)<=10&&abs(p1.y-p2.y)<=10){ CCLog("StaticItem::ccTouchEnded 点击%d",this->getTag()); }else{ CCLog("StaticItem::ccTouchEnded 拖动%d",this->getTag()); } }