cocos2d-x 自己写的一个scrollview 有待完善
直接上代码,根据cocos2d-x 扩展库中的代码改编的。
////MScrollView.h//TestScrollView////CreatedbyZaaaon13-4-25.////#ifndef_MScrollView_h#define_MScrollView_h#include"cocos2d.h"usingnamespacecocos2d;//触摸误差constintTOUCH_DELTA=5;//设置图片修正时的移动速度constfloatMOVE_SPEED=1000;classMScrollView:publiccocos2d::CCLayerColor{public:MScrollView();~MScrollView();virtualboolinit();//复写绘图函数,每帧调用,添加了区域剔除voidvisit();//CREATE_FUNC(MScrollView);//自定义--------//从多个精灵创建staticMScrollView*CreateWithSprite(floatgap,CCSprite*p_w_picpathSprite,...);//修改剔除区域voidsetClipSize(floatwidth,floatheight);//修改响应区域voidsetTouchRect(CCRecttouchRect){m_touchRect=touchRect;};//根据间距初始化子层精灵boolinitGapForChild(floatgap);//修正动画的函数voidRAnimation(CCPointpt);//拖动精灵,跟随手指移动改变位置voiddraySprite(floatdelta);//滚动到某一页的函数voidgotoPageAnimation(floatpage);//页面滚动动画,moveto动画voidScrollAnimation(CCPointoffset,floattime);//updata,用于如果拖动就停止moveto动作voidMoveToAnimation(floatdt);//添加一个回调函数,用于停止动画voidStopMoveToAnimation();//重写触屏相关函数----virtualvoidregisterWithTouchDispatcher();virtualboolccTouchBegan(CCTouch*touch,CCEvent*event);virtualvoidccTouchMoved(CCTouch*touch,CCEvent*event);virtualvoidccTouchEnded(CCTouch*touch,CCEvent*event);virtualvoidccTouchCancelled(CCTouch*pTouch,CCEvent*pEvent);private://是否按下后移动boolm_dragging;//按下的点CCPointm_touchDownPoint;//抬起点CCPointm_touchUpPoint;//当前的触电CCPointm_touchCurPoint;//子层容器,用于滚动显示CCLayer*m_Container;//保存所有精灵CCArray*m_spriteArray;//总页数intm_page;//当前页数intm_curpage;//偏移动画的时间floatm_time;//显示区域//CCRectm_view;//显示区域,区域外的将被剪切CCSizem_clipSize;//接收事件的区域CCRectm_touchRect;//点击后的回调函数SEL_CallFuncm_fun;};#endif
////MScrollView.cpp//TestScrollView////CreatedbyZaaaon13-4-25.////#include"MScrollView.h"MScrollView::MScrollView(){}MScrollView::~MScrollView(){//清空数组m_spriteArray->release();}MScrollView*MScrollView::CreateWithSprite(floatgap,CCSprite*p_w_picpathSprite,...){MScrollView*pRet=newMScrollView();if(pRet&&pRet->init()){//创建array,用于保存所有spritepRet->m_spriteArray=CCArray::create();CC_SAFE_RETAIN(pRet->m_spriteArray);//-----------------------------------------------//将省略的sprite添加进m_spriteArray和mscrollview中//----------------------------------------------//定义一个params变量,实际是一个指针,用于定位可变行参变量va_listparams;//执行本宏后,params指向第一个可变信参,p_w_picpathSprite为最后一个确定行参va_start(params,p_w_picpathSprite);//定义一个ccsprite接收参数CCSprite*pNow=p_w_picpathSprite;while(true){if(pNow){//添加进数组和层-----pRet->m_spriteArray->addObject(pNow);pRet->m_Container->addChild(pNow);//去下一个值pNow=va_arg(params,CCSprite*);}else{break;}}//清空va_end(params);//排列ccpritepRet->initGapForChild(gap);////////////添加完成////////pRet->autorelease();returnpRet;}\else{deletepRet;pRet=NULL;returnNULL;}}boolMScrollView::init(){////////////////////////////////1.superinitfirst//if(!CCLayerColor::init())if(!CCLayerColor::CCLayerColor::initWithColor(ccc4(0xff,0x00,0x00,0x80),100,100)){returnfalse;}//开启触屏响应this->setTouchEnabled(true);//添加显示容器m_Container=CCLayer::create();m_Container->setAnchorPoint(ccp(0.0f,0.0f));m_Container->setPosition(ccp(0.0f,0.0f));this->addChild(m_Container);//修改响应区域,默认是全屏CCSizescreen=CCDirector::sharedDirector()->getWinSize();setTouchRect(CCRectMake(0,0,screen.width,screen.height));//修改显示区域,默认为全屏this->setContentSize(screen);//修改剪切区域,默认为全屏setClipSize(screen.width,screen.height);//默认回调函数为空m_fun=NULL;returntrue;}voidMScrollView::visit(){if(!m_bIsVisible){return;}kmGLPushMatrix();if(m_pGrid&&m_pGrid->isActive()){m_pGrid->beforeDraw();this->transformAncestors();}this->transform();//默认情况下,剪裁是禁用的glEnable(GL_SCISSOR_TEST);//启用剪裁测试floats=this->getScale();//当前layer缩放的倍数s*=CCDirector::sharedDirector()->getContentScaleFactor();//获取缩放倍率CCPointscreenPos=this->convertToWorldSpace(this->getParent()->getPosition());//默认不设置Scissor的大小是整个视图的大小glScissor((GLint)screenPos.x,(GLint)screenPos.y,(GLsizei)(m_clipSize.width*s),(GLsizei)(m_clipSize.height*s));//子节点处理if(m_pChildren){ccArray*arrayData=m_pChildren->data;unsignedinti=0;for(;i<arrayData->num;i++){CCNode*child=(CCNode*)arrayData->arr[i];if(child->getZOrder()<0){child->visit();}else{break;}}this->draw();for(;i<arrayData->num;i++){CCNode*child=(CCNode*)arrayData->arr[i];child->visit();}}else{this->draw();}glDisable(GL_SCISSOR_TEST);//禁用剪裁测试if(m_pGrid&&m_pGrid->isActive()){m_pGrid->afterDraw(this);}kmGLPopMatrix();//}voidMScrollView::setClipSize(floatwidth,floatheight){m_clipSize=CCSizeMake(width,height);}//TODO:载显示容器中排列精灵boolMScrollView::initGapForChild(floatgap){//用于判读是否有元素if(m_spriteArray==NULL)returnfalse;///////////修改各个元素的位置//初始化当前页m_curpage=0;//初始化总页数m_page=m_spriteArray->count();CCSprite*sp=(CCSprite*)m_spriteArray->objectAtIndex(0);floatspwidth=sp->boundingBox().size.width/2.0f;floatspheight=sp->boundingBox().size.height/2.0f;//获取一个中心点CCPointpt=ccp(this->boundingBox().size.width/2.0f-spwidth,this->boundingBox().size.height/2.0f-spheight);floattY=pt.y;sp->setAnchorPoint(ccp(0,0));sp->setPosition(pt);for(inti=1;i<m_page;i++){spwidth=sp->boundingBox().size.width;pt=ccp(sp->getPositionX()+spwidth+gap,tY);sp=(CCSprite*)m_spriteArray->objectAtIndex(i);sp->setAnchorPoint(ccp(0,0));sp->setPosition(pt);}}//TODO:滚动修正voidMScrollView::RAnimation(CCPointpt){int_page=m_curpage;//判断移动的方向floatf=pt.x;if(f>0){//向左移动CCLog("zuo");_page++;}else{//向→移动CCLog("you");_page--;}if(!(_page>m_page-1||_page<0)){m_curpage=_page;}CCLog("_pageis:%d",_page);CCLog("pageis:%d",m_page);CCLog("curpageis:%d",m_curpage);gotoPageAnimation(m_curpage);}//TODO:拖动精灵,跟随手指移动改变位置voidMScrollView::draySprite(floatdelta){this->m_Container->setPosition(ccpAdd(this->m_Container->getPosition(),ccp(delta,0)));}//TODO:滚动到某一页的动画voidMScrollView::gotoPageAnimation(floatpage){if(m_page==0)return;//获得当前页的精灵CCSprite*sp=(CCSprite*)this->m_spriteArray->objectAtIndex(page);//多移动一小段距离让sprite载正中间float_width=sp->boundingBox().size.width*0.5f;_width=m_clipSize.width*0.5f-_width;//获取要到达的点CCPointgotoPoint=ccp(-sp->getPositionX()+_width,this->m_Container->getPositionY());//计算移动到点的时间float_length=ccpDistance(gotoPoint,m_Container->getPosition());float_time=_length/MOVE_SPEED;//滚动到指定点ScrollAnimation(gotoPoint,_time);}//页面滚动动画,moveto动画voidMScrollView::ScrollAnimation(CCPointoffset,floattime){//如果是拖动就停止这个动作if(m_dragging){this->unschedule(schedule_selector(MScrollView::MoveToAnimation));return;}/////////////////创建移动动画//////////////CCFiniteTimeAction*scroll,*expire;scroll=CCMoveTo::create(time,offset);//添加一个回调函数expire=CCCallFuncN::create(this,callfuncN_selector(MScrollView::StopMoveToAnimation));//运行moveto动画m_Container->runAction(CCSequence::create(scroll,expire,NULL));//开启拖动判读this->schedule(schedule_selector(MScrollView::MoveToAnimation));}//updata,用于如果拖动就停止moveto动作voidMScrollView::MoveToAnimation(floatdt){if(m_dragging){this->m_Container->unscheduleAllSelectors();return;}}////添加一个回调函数,用于停止动画voidMScrollView::StopMoveToAnimation(){//this->unschedule(schedule_selector(MoveToAnimation));this->m_Container->unscheduleAllSelectors();}//消息注册voidMScrollView::registerWithTouchDispatcher(){CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);}boolMScrollView::ccTouchBegan(cocos2d::CCTouch*touch,cocos2d::CCEvent*event){if(!this->isVisible()){returnfalse;}//记录按下的点m_touchDownPoint=CCDirector::sharedDirector()->convertToGL(touch->locationInView());if(!m_touchRect.containsPoint(m_touchDownPoint)){returnfalse;}m_dragging=true;CCLog("CCtouchBegan");//returntrue;}voidMScrollView::ccTouchMoved(CCTouch*touch,CCEvent*event){CCLog("ccTouchMoved");if(!this->isVisible()){return;}m_touchCurPoint=CCDirector::sharedDirector()->convertToGL(touch->locationInView());if(!m_touchRect.containsPoint(m_touchCurPoint)){m_dragging=false;return;}//如果不是按下后移动if(m_dragging){CCPointmoveDelta=ccpSub(m_touchCurPoint,m_touchDownPoint);draySprite(moveDelta.x);m_dragging=false;}else{draySprite(touch->getDelta().x);}//CCLog("ccTouchMoved,xis%f::yis%f",x,y);}voidMScrollView::ccTouchEnded(CCTouch*touch,CCEvent*event){if(!this->isVisible()){return;}m_touchUpPoint=CCDirector::sharedDirector()->convertToGL(touch->locationInView());if(!m_touchRect.containsPoint(m_touchUpPoint)){m_dragging=false;return;}//判定是点击还是滑动,如果是点击执行点击函数,如果是滑动执行调整动画floatoff=ccpDistance(m_touchDownPoint,m_touchUpPoint);if(off<TOUCH_DELTA){//触发点击事件m_fun;CCLog("touchclick");}else{//滑动纠正//触发滑动动画RAnimation(ccpSub(m_touchDownPoint,m_touchUpPoint));}}voidMScrollView::ccTouchCancelled(CCTouch*pTouch,CCEvent*pEvent){}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。