关羽CCLayer的滑动和剪切功能,已经在cocos2dx中实现,CCScrowView是按照IOS的控件自实现的功能,鄙人由于在用的时候,cocos2d-x版本比较早,没有类似的功能,所以大致自己写了个,凑合用,效果好不错,废话不多说上代码:
欢迎大家加入我的cocos2d-x交流群:166693678
#ifndef MYSCROWLAYER_H
#define MYSCROWLAYER_H
#include <iostream>
#include <vector>
#include "cocos2d.h"
#include "MyScissorLayer.h"
#include "MyScrowLayer.h"
using namespace std;
using namespace cocos2d;
class GameLayer;
class MyScrowLayer : public MyScissorLayer
{
public:
MyScrowLayer();
virtual ~MyScrowLayer();
virtual bool init();
virtual void visit();
CREATE_FUNC(MyScrowLayer);
public:
virtual void registerWithTouchDispatcher();
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
void endSlid(float t);
void updatePosTouchEnd(float t);
void initMenu();
void slidDir(int dir,float lg);
void touchMenu(CCObject *pSender);
private:
CCNode *m_uiNode;
bool m_nodeMoved;
CCPoint m_curPos;
CCPoint m_lastPos;
CCMenu *m_menu;
long m_curTime;
float m_lastPosY;
float m_curEndSpeed;
vector<CCMenuItemSprite*> m_spriteItems;
};
#endif
#include "MyScrowLayer.h"
#include <iostream>
#include <vector>
using namespace std;
MyScrowLayer::MyScrowLayer():m_uiNode(NULL)
,m_nodeMoved(false)
,m_menu(NULL)
,m_curTime(0)
,m_lastPosY(0)
,m_curEndSpeed(0)
{
}
MyScrowLayer::~MyScrowLayer()
{
}
bool MyScrowLayer::init()
{
CCSize size = CCDirector::sharedDirector()->getWinSize();
m_uiNode = CCNode::create();
this->addChild(m_uiNode,1);
m_uiNode->setPosition(CCPointZero);
CCLayerColor *ly = CCLayerColor::create(ccc4(200,100,100,100),640,960);
this->addChild(ly,-1);
ly->setAnchorPoint(CCPointZero);
ly->setPosition(ccp(0,0));
setTouchEnabled(true);
CCMenu *m_menu = CCMenu::create();
m_uiNode->addChild(m_menu);
m_menu->setPosition(CCPointZero);
for (int i=0;i!=10;++i)
{
CCSprite *spNml = CCSprite::create("gomap0.png");
CCSprite *spSel = CCSprite::create("gomap1.png");
CCMenuItemSprite *itemSp = CCMenuItemSprite::create(spNml,spSel,this,menu_selector(MyScrowLayer::touchMenu));
m_menu->addChild(itemSp);
itemSp->setPosition(ccp(320,50+100*i));
m_spriteItems.push_back(itemSp);
}
return true;
}
void MyScrowLayer::visit()
{
MyScissorLayer::visit();
}
void MyScrowLayer::registerWithTouchDispatcher()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -129, false);
}
bool MyScrowLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint touchePos = pTouch->getLocation();
if (!m_rect.containsPoint(touchePos))
{
return false;
}
m_nodeMoved = false;
CCPoint pos = pTouch->getLocation();
m_curPos = pos;
m_lastPos = pos;
m_curTime = time(NULL);
m_lastPosY = m_uiNode->getPositionY();
unschedule(schedule_selector(MyScrowLayer::updatePosTouchEnd));
unschedule(schedule_selector(MyScrowLayer::endSlid));
return true;
}
void MyScrowLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
CCSize size = CCSize(640,960);
m_curPos = pTouch->getLocation();
if ((m_curPos - m_lastPos).getLength() < 12)
{
return ;
}
else
{
m_nodeMoved = true;
float xMove = m_curPos.y - m_lastPos.y;
slidDir(0,xMove);
//float posY = m_uiNode->getPositionY() ;
//if (posY < -3 * size.height) //-160 )
//{
// m_uiNode->setPositionY( -3 * size.height);// -160 );
// return;
//}
//else if (posY > m_rect.origin.y)
//{
// m_uiNode->setPositionY(m_rect.origin.y);
// return;
//}
//m_uiNode->setPositionY(posY);
m_lastPos = m_curPos;
}
}
void MyScrowLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
if (!m_nodeMoved)
{
return;
}
long curTime = time(NULL);
float curPosY= m_uiNode->getPositionY();
if (curTime == m_curTime)
{
if (curPosY - m_lastPosY > 0)
{
m_curEndSpeed = 700;
}
else if (curPosY - m_lastPosY < 0)
{
m_curEndSpeed = -700;
}
else
{
return;
}
}
else
{
m_curEndSpeed = (curPosY - m_lastPosY)/(curTime - m_curTime);
m_curEndSpeed *= 1.30f;
}
if (fabs(m_curEndSpeed) > 80)
{
schedule(schedule_selector(MyScrowLayer::updatePosTouchEnd));
scheduleOnce(schedule_selector(MyScrowLayer::endSlid),0.5f);
}
}
void MyScrowLayer::updatePosTouchEnd(float t)
{
m_curEndSpeed = m_curEndSpeed ;
float xMove = m_curEndSpeed * t;
slidDir(0,xMove);
}
void MyScrowLayer::endSlid(float t)
{
unschedule(schedule_selector(MyScrowLayer::updatePosTouchEnd));
}
void MyScrowLayer::initMenu()
{
}
void MyScrowLayer::slidDir(int dir,float lg)
{
CCSize size = CCDirector::sharedDirector()->getWinSize();
float posY = m_uiNode->getPositionY() +lg;
if (posY < -3 * size.height) //-160 )
{
m_uiNode->setPositionY( -3 * size.height);// -160 );
return;
}
else if (posY > m_rect.origin.y)
{
m_uiNode->setPositionY(m_rect.origin.y);
return;
}
m_uiNode->setPositionY(posY);
}
void MyScrowLayer::touchMenu(CCObject *pSender)
{
if (m_nodeMoved)
{
return;
}
}
#ifndef MYSCISSORLAYER_H
#define MYSCISSORLAYER_H
#include "cocos2d.h"
using namespace cocos2d;
class MyScissorLayer : public CCLayer
{
public:
MyScissorLayer();
~MyScissorLayer();
virtual bool init();
virtual void visit();
CREATE_FUNC(MyScissorLayer);
void setScissorRect(const CCRect& rect);
protected:
bool m_touchOnLayer;
CCNode *m_scrowRootNode;
CCRect m_rect;
};
#endif
#include "MyScissorLayer.h"
MyScissorLayer::MyScissorLayer(): m_touchOnLayer(false)
{
this->setTouchEnabled(true);
}
MyScissorLayer::~MyScissorLayer()
{
}
bool MyScissorLayer::init()
{
return true;
}
void MyScissorLayer::visit()
{
glEnable(GL_SCISSOR_TEST);
CCLayer::visit();
CCPoint pos = m_rect.origin + this->getPosition(); //**世界坐标的左下角**//
CCSize size = m_rect.size; //**剪切区域的大小**//
CCEGLView::sharedOpenGLView()->setScissorInPoints(pos.x, pos.y, size.width, size.height);
glDisable(GL_SCISSOR_TEST);
}
void MyScissorLayer::setScissorRect(const CCRect& rect)
{
CCLayerColor *ly = CCLayerColor::create(ccc4(10,10,10,100),rect.size.width,rect.size.height);
this->addChild(ly,10);
ly->setPosition(rect.origin);
m_rect = rect;
}
使用的时候,自定义剪切区域
MyScrowLayer *ly = MyScrowLayer::create();
CCScene *pScene = CCScene::create();
pScene->addChild(ly);
ly->setScissorRect(CCRectMake(100,100,440,760));