cocos2d-x 菜鸟进阶篇(三) ScrollView(上)

scrollView 的调用问题困扰我很久,昨天才有时间继续研究这个,可惜最后还是没能完全解决它存在的问题。。。


看头文件:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

#include "../../extensions/cocos-ext.h"

//using namespace CocosDenshion;

using namespace cocos2d;

USING_NS_CC;
USING_NS_CC_EXT;

class HelloWorld : public CCLayer, public 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();
    
    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);

	virtual void scrollViewDidScroll(cocos2d::extension::CCScrollView* view) {};
    virtual void scrollViewDidZoom(cocos2d::extension::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(CCObject *pSender);
    void menu2Callback(CCObject *pSender);
    
private:  
    CCScrollView *scrollView;
};

#endif  // __HELLOWORLD_SCENE_H__

看.cpp

#include "HelloWorldScene.h"

// 校正滑动动画速度
#define ADJUST_ANIM_VELOCITY 800;

CCScene* HelloWorld::scene()
{
    CCScene * scene = NULL;
    do 
    {
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        HelloWorld *layer = HelloWorld::create();
        CC_BREAK_IF(! layer);

        scene->addChild(layer);
    } while (0);

    return scene;
}

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        	CC_BREAK_IF(! CCLayer::init());
		CCSize size = CCDirector::sharedDirector()->getWinSize();

		//add scrollView and layer
		scrollView = CCScrollView::create();  
		CCLayer *layer = CCLayer::create();  

		//set layer AnchorPoint and Position zero
		layer->setAnchorPoint(CCPointZero);  
		layer->setPosition(CCPointZero); 
     
		//add two spriteMenu
		CCSprite *sprite1 = CCSprite::create("HelloWorld.png");  
		CCSprite *sprite2 = CCSprite::create("HelloWorld.png");  
        
		// Menu  
		CCMenuItemSprite *menuItem1 = CCMenuItemSprite::create(sprite1, sprite1, this, menu_selector(HelloWorld::menu1Callback));  
		menuItem1->setPosition(ccpAdd(CCPointZero, ccp(size.width / 2, size.height / 3)));  
		menuItem1->setScale(0.4f);  
		CCMenuItemSprite *menuItem2 = CCMenuItemSprite::create(sprite2, sprite2, this, menu_selector(HelloWorld::menu1Callback));  
		//menuItem2->setPosition(ccpAdd(ccp(480, 0), ccp(size.width / 2, size.height / 2)));  
		menuItem2->setPosition(ccpAdd(CCPointZero, ccp(size.width / 2, 2*size.height / 3)));  
		menuItem2->setScale(0.4f);  
		CCMenu *menu = CCMenu::create(menuItem1, menuItem2, NULL);  
      
		menu->setPosition(CCPointZero);  
		//addChild in layer
		layer->addChild(menu);
	 
		scrollView->setPosition(CCPointZero);
		//这一步是1.0版本没有的,重要!
		scrollView->setContentOffset(CCPointZero);
		//layer->setContentSize(CCSizeMake(960, 320)); 
		//最重要的就是下面这两步,setViewSize是设置显示的大小;ContenSize是设置总大小,包括显示跟隐藏幕后的
		scrollView->setViewSize(CCSizeMake(320, 480));//大小要设置得比图片的小。
		scrollView->setContentSize(CCSizeMake(640, 640));  
		scrollView->setContainer(layer);

		//设置滚动方向,
		scrollView->setDirection(kCCScrollViewDirectionBoth);
		scrollView->setDelegate(this);

		this->addChild(scrollView);

        bRet = true;
    } while (0);

    return bRet;
}

void HelloWorld::onEnter()
{
    CCLayer::onEnter();
    // 这里的第三个参数一定要设置成false,
    // true 即HelloWorld层吞噬掉触摸事件
    // false 即HelloWorld层与CCScrollView对象先后处理触摸事件
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, false);
}

void HelloWorld::onExit()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
    CCLayer::onExit();
}

bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
    return true;
}

void HelloWorld::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
    CCLOG("move");
}

void HelloWorld::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
    adjustScrollView();
}

void HelloWorld::ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
    adjustScrollView();
}

void HelloWorld::adjustScrollView()
{
    // 关闭CCScrollView中的自调整
    scrollView->unscheduleAllSelectors();
    
    int x = scrollView->getContentOffset().x;
    int offset = (int) x % 480;
    // 调整位置
    CCPoint adjustPos;
    // 调整动画时间
    float adjustAnimDelay;
    
    if (offset < -240) {
        // 计算下一页位置,时间
        adjustPos = ccpSub(scrollView->getContentOffset(), ccp(480 + offset, 0));
        adjustAnimDelay = (float) (480 + offset) / ADJUST_ANIM_VELOCITY;
    }
    else {
        // 计算当前页位置,时间
        adjustPos = ccpSub(scrollView->getContentOffset(), ccp(offset, 0));
        // 这里要取绝对值,否则在第一页往左翻动的时,保证adjustAnimDelay为正数
        adjustAnimDelay = (float) abs(offset) / ADJUST_ANIM_VELOCITY;
    }
    
    // 调整位置
    scrollView->setContentOffsetInDuration(adjustPos, adjustAnimDelay);
}

void HelloWorld::menu1Callback(CCObject *pSender)
{
    CCLOG("menu1Callback");
}

void HelloWorld::menu2Callback(CCObject *pSender)
{
    CCLOG("menu2Callback");
}

本篇代码大多都是参考 oneRain 的博客后进一步修改的。

http://blog.csdn.net/onerain88/article/details/7775569,大家可以去看看。

posted @ 2013-02-07 14:35  star特530  阅读(353)  评论(0编辑  收藏  举报