cocos2dx ScrollView 测试二 自定义Item和boundingBox

接上一篇,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());
    }
}
我是cocos2dx初学者,Java5年,一点C++,OC经验都没有,各位见笑了 文章中如有错误或者不全面或者有更好的解决办法,请指出,不胜感激
原文地址:https://www.cnblogs.com/hanhongmin/p/3501789.html