CCScrollView在Cocos2d-X引擎中主要使用在图片尺寸远大于屏幕尺寸的时候使用。
总体来说,使用起来比较简单。
一个是CCScrollView控件本身,一个是CCScrollViewDelegate代理。
#1.现在我们先来看CCScrollView的主要方法:
*/ //滑动方向 typedef enum { kCCScrollViewDirectionNone = -1, kCCScrollViewDirectionHorizontal = 0, kCCScrollViewDirectionVertical, kCCScrollViewDirectionBoth } CCScrollViewDirection; class CCScrollView; class CCScrollViewDelegate { public: virtual ~CCScrollViewDelegate() {} virtual void scrollViewDidScroll(CCScrollView* view) = 0; //滑动调用 virtual void scrollViewDidZoom(CCScrollView* view) = 0; //缩放调用 }; /** * ScrollView support for cocos2d for iphone. * It provides scroll view functionalities to cocos2d projects natively. */ class CCScrollView : public CCLayer { public: CCScrollView(); virtual ~CCScrollView(); bool init(); virtual void registerWithTouchDispatcher(); /** * Returns an autoreleased scroll view object. * * @param size view size * @param container parent object * @return autoreleased scroll view object */ static CCScrollView* create(CCSize size, CCNode* container = NULL); /** * Returns an autoreleased scroll view object. * * @param size view size * @param container parent object * @return autoreleased scroll view object */ static CCScrollView* create(); /** * Returns a scroll view object * * @param size view size * @param container parent object * @return scroll view object */ bool initWithViewSize(CCSize size, CCNode* container = NULL); /** * Sets a new content offset. It ignores max/min offset. It just sets what's given. (just like UIKit's UIScrollView) * * @param offset new offset * @param If YES, the view scrolls to the new offset */ void setContentOffset(CCPoint offset, bool animated = false); CCPoint getContentOffset(); /** * Sets a new content offset. It ignores max/min offset. It just sets what's given. (just like UIKit's UIScrollView) * You can override the animation duration with this method. * 设置新的容器坐标 * @param offset new offset * @param animation duration */ void setContentOffsetInDuration(CCPoint offset, float dt); void setZoomScale(float s); /** * Sets a new scale and does that for a predefined duration. * 设置CCScrollView的缩放 * @param s a new scale vale * @param animated if YES, scaling is animated */ void setZoomScale(float s, bool animated); float getZoomScale(); /** * Sets a new scale for container in a given duration. * * @param s a new scale value * @param animation duration */ void setZoomScaleInDuration(float s, float dt); /** * Returns the current container's minimum offset. You may want this while you animate scrolling by yourself */ CCPoint minContainerOffset(); /** * Returns the current container's maximum offset. You may want this while you animate scrolling by yourself */ CCPoint maxContainerOffset(); /** * Determines if a given node's bounding box is in visible bounds * * @return YES if it is in visible bounds */ bool isNodeVisible(CCNode * node); /** * Provided to make scroll view compatible with SWLayer's pause method */ void pause(CCObject* sender); /** * Provided to make scroll view compatible with SWLayer's resume method */ void resume(CCObject* sender); bool isDragging() {return m_bDragging;} bool isTouchMoved() { return m_bTouchMoved; } bool isBounceable() { return m_bBounceable; } //是否开启弹性滑动,默认true,false滑动失效 void setBounceable(bool bBounceable) { m_bBounceable = bBounceable; } /** * size to clip. CCNode boundingBox uses contentSize directly. * It's semantically different what it actually means to common scroll views. * Hence, this scroll view will use a separate size property. */ CCSize getViewSize() { return m_tViewSize; } void setViewSize(CCSize size); CCNode * getContainer(); void setContainer(CCNode * pContainer); //设置,获取容器的一对方法 /** * direction allowed to scroll. CCScrollViewDirectionBoth by default. */ CCScrollViewDirection getDirection() { return m_eDirection; } virtual void setDirection(CCScrollViewDirection eDirection) { m_eDirection = eDirection; } //设置,获取CCScrollView的对齐方向 CCScrollViewDelegate* getDelegate() { return m_pDelegate; } void setDelegate(CCScrollViewDelegate* pDelegate) { m_pDelegate = pDelegate; } //设置代理对象 /** override functions */ // optional 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); virtual void setContentSize(const CCSize & size); //设置容器大小 virtual const CCSize& getContentSize() const; void updateInset(); /** * Determines whether it clips its children or not. */ bool isClippingToBounds() { return m_bClippingToBounds; } void setClippingToBounds(bool bClippingToBounds) { m_bClippingToBounds = bClippingToBounds; } virtual void visit(); virtual void addChild(CCNode * child, int zOrder, int tag); virtual void addChild(CCNode * child, int zOrder); virtual void addChild(CCNode * child); void setTouchEnabled(bool e); private: /** * Relocates the container at the proper offset, in bounds of max/min offsets. * * @param animated If YES, relocation is animated */ void relocateContainer(bool animated); /** * implements auto-scrolling behavior. change SCROLL_DEACCEL_RATE as needed to choose * deacceleration speed. it must be less than 1.0f. * * @param dt delta */ void deaccelerateScrolling(float dt); /** * This method makes sure auto scrolling causes delegate to invoke its method */ void performedAnimatedScroll(float dt); /** * Expire animated scroll delegate calls */ void stoppedAnimatedScroll(CCNode* node); /** * clip this view so that outside of the visible bounds can be hidden. */ void beforeDraw(); /** * retract what's done in beforeDraw so that there's no side effect to * other nodes. */ void afterDraw(); /** * Zoom handling */ void handleZoom(); protected: CCRect getViewRect(); /** * current zoom scale */ float m_fZoomScale; /** * min zoom scale */ float m_fMinZoomScale; /** * max zoom scale */ float m_fMaxZoomScale; /** * scroll view delegate */ CCScrollViewDelegate* m_pDelegate; CCScrollViewDirection m_eDirection; /** * If YES, the view is being dragged. */ bool m_bDragging; /** * Content offset. Note that left-bottom point is the origin */ CCPoint m_tContentOffset; /** * Container holds scroll view contents, Sets the scrollable container object of the scroll view */ CCNode* m_pContainer; /** * Determiens whether user touch is moved after begin phase. */ bool m_bTouchMoved; /** * max inset point to limit scrolling by touch */ CCPoint m_fMaxInset; /** * min inset point to limit scrolling by touch */ CCPoint m_fMinInset; /** * Determines whether the scroll view is allowed to bounce or not. */ bool m_bBounceable; bool m_bClippingToBounds; /** * scroll speed */ CCPoint m_tScrollDistance; /** * Touch point */ CCPoint m_tTouchPoint; /** * length between two fingers */ float m_fTouchLength; /** * UITouch objects to detect multitouch */ CCArray* m_pTouches; /** * size to clip. CCNode boundingBox uses contentSize directly. * It's semantically different what it actually means to common scroll views. * Hence, this scroll view will use a separate size property. */ CCSize m_tViewSize; /** * max and min scale */ float m_fMinScale, m_fMaxScale; /** * scissor rect for parent, just for restoring GL_SCISSOR_BOX */ CCRect m_tParentScissorRect; bool m_bScissorRestored; };
#2.现在看下示例代码:
.h声明
class HelloWorld : public cocos2d::CCLayer, public CCScrollViewDelegate { private: CCScrollView *scroll ; float xOffSet; float yOffSet; public: virtual bool init(); static cocos2d::CCScene* scene(); void menuCloseCallback(CCObject* pSender); CREATE_FUNC(HelloWorld); virtual void scrollViewDidScroll(CCScrollView* view); virtual void scrollViewDidZoom(CCScrollView* view); };
.cpp实现
bool HelloWorld::init() { // 1. super init first if ( !CCLayer::init() ) { return false; } CCSize winSize = CCDirector::sharedDirector()->getWinSize(); //设置scrollView的大小,为显示的view的尺寸 scroll = CCScrollView::create(CCSizeMake(960, 640)); CCSprite *bg = CCSprite::create("11.png"); //bg->setPosition(ccp(winSize.width/2, winSize.height/2)); //容器的锚点是(0,0) bg->setPosition(ccp(0, 0)); CCMenuItemImage *back = CCMenuItemImage::create("Icon.png", "Icon.png"); back->setPosition(CCPoint(200, 200)); bg->addChild(back); //bg->setAnchorPoint(ccp(0.5, 0.5)); //scroll->setAnchorPoint(ccp(0, 0)); //设置容器 scroll->setContainer(bg); //是开启弹性效果,关闭的话就不用使用这个控件 //scroll->setBounceable(false); bool flag = scroll->isBounceable(); CCLog("flag: %d",flag); //设置滑动方向 //kCCScrollViewDirectionHorizontal——水平滑动 //kCCScrollViewDirectionVertical——垂直滑动 scroll->setDirection(kCCScrollViewDirectionBoth); //设置容器大小 scroll->setContentSize(CCSizeMake(978, 2189)); //触摸有效 this->setTouchEnabled(true); CCSize scrollSize = scroll->getContentSize(); CCLog("scrollSize: %f %f",scrollSize.width,scrollSize.height); //设置代理为自身 scroll->setDelegate(this); this->addChild(scroll); //黑边防御坐标 xOffSet = winSize.width - scrollSize.width; yOffSet = winSize.height - scrollSize.height; return true; } void HelloWorld::scrollViewDidScroll(CCScrollView* view) { static int flag = 0; CCLog("Scroll %d",flag++); CCPoint offSet = this->scroll->getContentOffset(); CCLog("offSet : %f %f",offSet.x,offSet.y); if (offSet.x < this->xOffSet || offSet.y < this->yOffSet) { CCLog("scrollView 已经出现黑边问题了!"); if (offSet.x < this->xOffSet ) { CCLog("scrollView X轴 出现黑边问题了!"); this->scroll->setContentOffset(CCPoint(this->xOffSet, offSet.y)); }else{ CCLog("scrollView Y轴 已经出现黑边问题了!"); this->scroll->setContentOffset(CCPoint(offSet.x, this->yOffSet)); } } if (offSet.x > 0 || offSet.y > 0) { CCLog("scrollView 已经出现黑边问题了!"); if (offSet.x > 0 ) { CCLog("scrollView X轴 出现黑边问题了!"); this->scroll->setContentOffset(CCPoint(0, offSet.y)); }else{ CCLog("scrollView Y轴 已经出现黑边问题了!"); this->scroll->setContentOffset(CCPoint(offSet.x, 0)); } } }
#3.现在,我们来看下效果
原图的尺寸是978*2189