#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_NS_CC; #include "cocos-ext.h" USING_NS_CC_EXT; // 校正滑动动画速度 #define ADJUST_ANIM_VELOCITY 800; class HelloWorld : public cocos2d::CCLayer, public cocos2d::extension::CCScrollViewDelegate { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommand to return the exactly class pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); public: void scrollViewDidScroll(cocos2d::extension::CCScrollView* view); void scrollViewDidZoom(CCScrollView* view); public: virtual void onEnter(); virtual void onExit(); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); private: // 当触摸事件结束时,校正CCScrollView的位置 void adjustScrollView(); private: // 菜单回调 void menu1Callback(CCNode *pSender); void menu2Callback(CCNode *pSender); private: // 显示当前页 CCLabelTTF* pLabel; CCScrollView *scrollView; }; #endif // __HELLOWORLD_SCENE_H__
实现文件
1 #include "HelloWorldScene.h" 2 #include "SimpleAudioEngine.h" 3 4 using namespace cocos2d; 5 using namespace CocosDenshion; 6 USING_NS_CC_EXT; 7 8 CCScene* HelloWorld::scene() 9 { 10 // 'scene' is an autorelease object 11 CCScene *scene = CCScene::create(); 12 13 // 'layer' is an autorelease object 14 HelloWorld *layer = HelloWorld::create(); 15 16 // add layer as a child to scene 17 scene->addChild(layer); 18 19 // return the scene 20 return scene; 21 } 22 CCLayer *layer; 23 CCSprite *sprite2; 24 // on "init" you need to initialize your instance 25 bool HelloWorld::init() 26 { 27 ////////////////////////////// 28 // 1. super init first 29 if ( !CCLayer::init() ) 30 { 31 return false; 32 } 33 34 ///////////////////////////// 35 // 2. add a menu item with "X" image, which is clicked to quit the program 36 // you may modify it. 37 38 // add a "close" icon to exit the progress. it's an autorelease object 39 40 41 // ask director the window size 42 CCSize size = CCDirector::sharedDirector()->getWinSize(); 43 44 layer = CCLayerColor::create(ccc4(123, 23, 235,255)); 45 layer->setAnchorPoint(CCPointZero); 46 layer->setPosition(CCPointZero); 47 48 49 // CCScrollView 50 scrollView = CCScrollView::create(CCSizeMake(480, 320), layer); 51 52 // scrollView->setBounceable(false); 53 54 55 CCSprite *sprite1 = CCSprite::create("HelloWorld.png"); 56 sprite2 = CCSprite::create("HelloWorld.png"); 57 CCSprite *sprite3 = CCSprite::create("HelloWorld.png"); 58 59 // Menu 60 //CCMenuItemSprite *menuItem1 = CCMenuItemSprite::create(sprite1, sprite1, this, menu_selector(HelloWorld::menu1Callback)); 61 // CCMenuItemSprite *menuItem1 = CCMenuItemSprite::create(sprite1, sprite1, this, NULL); 62 // menuItem1->setPosition(ccpAdd(CCPointZero, ccp(size.width / 2, size.height / 2))); 63 // 64 // CCMenuItemSprite *menuItem2 = CCMenuItemSprite::create(sprite2, sprite2, this, NULL); 65 // menuItem2->setPosition(ccpAdd(ccp(480, 0), ccp(size.width / 2, size.height / 2))); 66 // 67 // CCMenu *menu = CCMenu::create(menuItem1, menuItem2, NULL); 68 // 69 // menu->setPosition(CCPointZero); 70 // layer->addChild(menu); 71 72 sprite1->setPosition(ccpAdd(CCPointZero, ccp(size.width / 2, size.height / 2))); 73 sprite2->setPosition(ccpAdd(ccp(480, 0), ccp(size.width / 2, size.height / 2))); 74 sprite3->setPosition(ccpAdd(ccp(960, 0), ccp(size.width / 2, size.height / 2))); 75 76 layer->addChild(sprite1); 77 layer->addChild(sprite2); 78 layer->addChild(sprite3); 79 80 81 82 83 layer->setContentSize(CCSizeMake(960, 320)); 84 85 sprite1->setScale(0.5); 86 sprite2->setScale(0.5); 87 88 scrollView->setPosition(CCPointZero); 89 scrollView->setContentOffset(CCPointZero); 90 91 scrollView->setContentSize(CCSizeMake(480*3, 320)); 92 scrollView->setContainer(layer); 93 94 95 scrollView->setDirection(kCCScrollViewDirectionHorizontal); 96 scrollView->setDelegate(this); 97 98 this->addChild(scrollView); 99 100 101 102 return true; 103 } 104 105 void HelloWorld::menuCloseCallback(CCObject* pSender) 106 { 107 CCDirector::sharedDirector()->end(); 108 109 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 110 exit(0); 111 #endif 112 } 113 114 void HelloWorld::scrollViewDidScroll(cocos2d::extension::CCScrollView *view) 115 { 116 } 117 118 void HelloWorld::scrollViewDidZoom(cocos2d::extension::CCScrollView *view) 119 { 120 } 121 122 void HelloWorld::onEnter() 123 { 124 CCLayer::onEnter(); 125 // 这里的第三个参数一定要设置成false, 126 // true 即HelloWorld层吞噬掉触摸事件 127 // false 即HelloWorld层与CCScrollView对象先后处理触摸事件 128 // CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, false); 129 } 130 131 void HelloWorld::onExit() 132 { 133 CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); 134 CCLayer::onExit(); 135 } 136 137 bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) 138 { 139 auto postion= pTouch->getLocation(); 140 auto p2= layer->convertToNodeSpace(postion); 141 // printf("p1.x=%f,p1.y=%f ",postion.x,postion.y); 142 // printf("p2.x=%f,p2.y=%f ",p2.x,p2.y); 143 144 auto rect =sprite2->boundingBox(); 145 if(rect.containsPoint(p2)){ 146 int ffff=0; 147 ffff++; 148 // printf("摸到了 "); 149 } 150 151 int ffffr=0; 152 ffffr++; 153 154 155 return true; 156 } 157 158 void HelloWorld::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) 159 { 160 // CCLOG("move"); 161 } 162 163 void HelloWorld::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) 164 { 165 adjustScrollView(); 166 } 167 168 void HelloWorld::ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) 169 { 170 adjustScrollView(); 171 } 172 173 void HelloWorld::adjustScrollView() 174 { 175 // 关闭CCScrollView中的自调整 176 scrollView->unscheduleAllSelectors(); 177 178 int x = scrollView->getContentOffset().x; 179 int offset = (int) x % 480; 180 181 printf("x=%d,offset=%d ",x,offset); 182 // 调整位置 183 CCPoint adjustPos; 184 // 调整动画时间 185 float adjustAnimDelay; 186 187 if (offset < -240) { 188 // 计算下一页位置,时间 189 adjustPos = ccpSub(scrollView->getContentOffset(), ccp(480 + offset, 0)); 190 adjustAnimDelay = (float) (480 + offset) / ADJUST_ANIM_VELOCITY; 191 printf("-240调整后的坐标=%f ",adjustPos.x); 192 } 193 else { 194 // 计算当前页位置,时间 195 adjustPos = ccpSub(scrollView->getContentOffset(), ccp(offset, 0)); 196 197 198 // 这里要取绝对值,否则在第一页往左翻动的时,保证adjustAnimDelay为正数 199 adjustAnimDelay = (float) abs(offset) / ADJUST_ANIM_VELOCITY; 200 201 202 printf("现在的位移=%f ",scrollView->getContentOffset().x); 203 204 printf(">240调整后的坐标=%f ",adjustPos.x); 205 } 206 207 208 // 调整位置 209 scrollView->setContentOffsetInDuration(adjustPos, adjustAnimDelay); 210 } 211 212 void HelloWorld::menu1Callback(cocos2d::CCNode *pSender) 213 { 214 CCLOG("menu1Callback"); 215 } 216 217 void HelloWorld::menu2Callback(cocos2d::CCNode *pSender) 218 { 219 CCLOG("menu2Callback"); 220 }
这里主要研究的是他的显示,以及当滑动停止的时候,有个加速度还要滑动一段,具体如何实现,是研究的CCScrollView源码,如下
1 void CCScrollView::deaccelerateScrolling(float dt) 2 { 3 if (m_bDragging) 4 { 5 this->unschedule(schedule_selector(CCScrollView::deaccelerateScrolling)); 6 return; 7 } 8 9 float newX, newY; 10 CCPoint maxInset, minInset; 11 12 m_pContainer->setPosition(ccpAdd(m_pContainer->getPosition(), m_tScrollDistance)); 13 14 if (m_bBounceable) 15 { 16 maxInset = m_fMaxInset; 17 minInset = m_fMinInset; 18 } 19 else 20 { 21 maxInset = this->maxContainerOffset(); 22 minInset = this->minContainerOffset(); 23 } 24 printf("maxinset.x=%f,mininset.x=%f ",maxInset.x,minInset.x); 25 //96,-1056 26 27 //check to see if offset lies within the inset bounds 28 newX = MIN(m_pContainer->getPosition().x, maxInset.x); 29 newX = MAX(newX, minInset.x); 30 newY = MIN(m_pContainer->getPosition().y, maxInset.y); 31 newY = MAX(newY, minInset.y); 32 33 newX = m_pContainer->getPosition().x; 34 newY = m_pContainer->getPosition().y; 35 36 m_tScrollDistance = ccpSub(m_tScrollDistance, ccp(newX - m_pContainer->getPosition().x, newY - m_pContainer->getPosition().y)); 37 m_tScrollDistance = ccpMult(m_tScrollDistance, SCROLL_DEACCEL_RATE); 38 this->setContentOffset(ccp(newX,newY)); 39 40 if ((fabsf(m_tScrollDistance.x) <= SCROLL_DEACCEL_DIST && 41 fabsf(m_tScrollDistance.y) <= SCROLL_DEACCEL_DIST) || 42 newY > maxInset.y || newY < minInset.y || 43 newX > maxInset.x || newX < minInset.x || 44 newX == maxInset.x || newX == minInset.x || 45 newY == maxInset.y || newY == minInset.y) 46 { 47 this->unschedule(schedule_selector(CCScrollView::deaccelerateScrolling)); 48 this->relocateContainer(true); 49 } 50 }
每次坐标增加
m_tScrollDistance,但是
m_tScrollDistance会每次变为0.95*m_tScrollDistance,达到减速的效果