http://blog.csdn.net/star530/article/details/25658725
前天有個網友問我一些關於scrollView的用法,由於在QQ上實在講不清,所以就利用晚上的時間寫這篇博客出來了。
本篇要實現的功能是用scrollView 拖動對象時,對象移動到某個固定範圍會有放大、縮小的效果。下面開始。
在進入正題前我先簡短的介紹下scrollView應該怎麼用吧(想必大家也都會用~~):
1、記得在頭文件裡包含 「../extensions/cocos-ext.h",順便聲明下作用域:USING_NS_CC_EXT;
2、在類的繼承裡 加上ScrollViewDelegate,如下:
- class HelloWorld : public cocos2d::Layer,public ScrollViewDelegate
- void scrollViewDidScroll(ScrollView* view);
- void scrollViewDidZoom(ScrollView* view);
- void scrollViewMoveOver(ScrollView* view);
先看頭文件:
- #ifndef __HELLOWORLD_SCENE_H__
- #define __HELLOWORLD_SCENE_H__
- #include "cocos2d.h"
- #include "../extensions/cocos-ext.h"
- USING_NS_CC;
- USING_NS_CC_EXT;
- class HelloWorld : public cocos2d::Layer,public ScrollViewDelegate
- {
- public:
- static cocos2d::Scene* createScene();//獲取歡迎畫面的Scene
- virtual bool init();
- void menuCloseCallback(Ref* pSender);
- CREATE_FUNC(HelloWorld);
- //scroll 委託
- void scrollViewDidScroll(ScrollView* view);
- void scrollViewDidZoom(ScrollView* view);
- void scrollViewMoveOver(ScrollView* view);
- private:
- Vector<Sprite*> sp_vec;//聲明一個容器
- };
- #endif // __HELLOWORLD_SCENE_H__
下面看定義
- bool HelloWorld::init()
- {
- //首先創建scrollView
- auto scroll_layer = Layer::create();//創建scrollView中的容器層
- scroll_layer->setPosition(Point::ZERO);
- scroll_layer->setAnchorPoint(Point::ZERO);
- scroll_layer->setContentSize(Size(600,300));//設置容器層大小為(600,300)
- auto scrollView = ScrollView::create(Size(400,300),scroll_layer);//創建scrollView,顯示窗口大小為(400,300)
- scrollView->setDelegate(this);//設置委託
- scrollView->setDirection(ScrollView::Direction::HORIZONTAL);//設置滾動方向為水平
- scrollView->setPosition(Point(300,200));
- this->addChild(scrollView,2);
- //創建三個對象
- auto boy = Sprite::create("boy.png");//沒錯,主角又是我們熟悉的那仨。多麼溫馨。
- boy->setPosition(Point(150,100));
- scroll_layer->addChild(boy,2);
- auto girl = Sprite::create("girl_1.png");
- girl->setPosition(Point(300,100));
- scroll_layer->addChild(girl,2);
- auto girl3 = Sprite::create("girl_3.png");
- girl3->setPosition(Point(450,100));
- scroll_layer->addChild(girl3,2);
- sp_vec.pushBack(boy);//將三個對象放入容器中
- sp_vec.pushBack(girl);
- sp_vec.pushBack(girl3);
- return true;
- }
接下來看下scrollView的委託函數,這裡只要看scrollViewDidScroll 就好了。實現效果是對象在某個坐標範圍內移動時會有縮放效果。
- void HelloWorld::scrollViewDidScroll(ScrollView* view)
- {
- //在scrollView拖動時響應該函數
- auto offsetPosX = (view->getContentOffset()).x;//獲得偏移X坐標(向右移動,偏移量為正數,向左則為負數)
- // CCLOG("offset pos is %f , %f",offsetPos.x,offsetPos.y);
- //for 循環遍歷容器中的每個精靈
- for( auto e : sp_vec )
- {
- auto pointX = e->getPositionX();//獲得當前對象的X坐標(不管怎麼滾動,這個坐標都是不變的)
- float endPosX = pointX + offsetPosX;//將精靈的 X坐標 + 偏移X坐標
- //當endPosX在 150~250 範圍,則對象的大小從左向右遞增
- if( endPosX > 150 && endPosX < 250 )
- {
- float x = endPosX / 150;//放大倍數為 endPosX / 150;
- e->setScale(x);
- CCLOG("x = %f",x);
- }
- //當endPosX在 250~350 範圍,則對象的大小從左向右遞減
- else if( endPosX > 250 && endPosX < 350 )
- {
- //下面這個公式不好解釋,我就這麼說吧:
- //假設 endPosX = 200,那麼放大倍數應該是 200 / 150 = 1.33左右,那麼當endPosX = 300時,出於對稱的原理,我們以250為對稱中心,那麼
- //300 的放大倍數也應該是 1.33。這就是下面的公式由來
- float a = endPosX - 250;
- float b = 250 - a;
- float x = b / 150;
- e->setScale(x);
- }
- else
- {
- //不是在上面的範圍,則設置為正常大小
- e->setScale(1.0f);
- }
- }
- }
- void HelloWorld::scrollViewDidZoom(ScrollView* view)
- {
- //do something
- }
- void HelloWorld::scrollViewMoveOver(ScrollView* view)
- {
- //do something
- }
恩,註釋寫的很清楚啦,但我還是要稍微補充一些東東:我們應該知道,對象放到滾動層上(如scroll_layer->addChild(boy)),那麼不管對象在scrollView上如何移動,它獲得的坐標都是不會變的(如boy->getPosition()是不變的數值),這種情況下,如果我們想實現對象在某個坐標範圍內會有縮放效果,那麼只是去獲取對象的坐標肯定是行不通的,所以肯定要找一個時刻在變化的」參照物」來利用下,該找什麼呢?沒錯,就是scrollView的偏移坐標(scrollView->getContentOffset())!只要scrollView移動一下,那麼它的 偏移量也隨之改變。我這裡就是利用對象的坐標與scrollView的偏移坐標之間不可告人的秘密,從而實現當前的目的。
下面看下運行效果。
沒有留言:
張貼留言