• Cocos2d—X游戏开发之CCScrollView(滑动视图)(十二)


    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










  • 相关阅读:
    动态规划3-最长公共子序列问题
    动态规划2-最大子段和
    动态规划1- 矩阵取数
    javac编译提示错误需要为 class、interface 或 enum
    [core python programming]chapter 7 programming MS office
    ubuntu apache nginx 启动 关闭
    ubuntu 安装 hustoj
    TCP报文段的首部格式
    守护进程
    会话session
  • 原文地址:https://www.cnblogs.com/james1207/p/3268706.html
Copyright © 2020-2023  润新知