您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x实现滑屏

2013-10-26 12:25 211 查看
像植物大战僵尸,保卫萝卜这些游戏,刚开始时就有一个滑屏选关卡的功能,这个效果非常好,越来越多的手机游戏使用这种方法进行关卡选择,想到以后,我也会经常用到这个功能,于是,就将这个功能封装起来,大家一起来看看代码吧

#ifndef _SLIDING_LAYER_H_
#define _SLIDING_LAYER_H_

//////////////////////////////////////////////////////////////////////////
class CSlidingLayer : public CCLayer
{
public:
CSlidingLayer();
~CSlidingLayer();

public:
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);    // 手指触碰时
virtual void ccTouchMoved(CCTouch *pTouches, CCEvent *pEvent);  // 手指移动时
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);    // 手指放开时

public:
void AddSprite(CCSprite* pSprite);           // 添加用于滑屏显示的精灵
bool IsMoveLayer()  { return m_bMoveLayer; } // 用于判断是否手指滑动了

private:
CCPoint m_ptTouchDown;      // 首次按下的触摸点

typedef vector<CCSprite*> VEC_SPRITE;
VEC_SPRITE m_vecSprite;     // 精灵集合
int m_nCurSprite;           // 当前显示的精灵

bool m_bMoveLayer;          // 移动层
};
#endif


#include "stdafx.h"
#include "SlidingLayer.h"

const int NEXT_SPRITE_SHOW = 50;    // 触摸点与滑动停止时点距离,如果超过这个值,我们认为是滑屏,没有超过则认为误操作,不做滑屏处理
//////////////////////////////////////////////////////////////////////////
CSlidingLayer::CSlidingLayer()
{
m_ptTouchDown.setPoint(-1, -1);
m_nCurSprite = 0;
m_bMoveLayer = false;
}

//////////////////////////////////////////////////////////////////////////
CSlidingLayer::~CSlidingLayer()
{

}

//////////////////////////////////////////////////////////////////////////
bool CSlidingLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
m_ptTouchDown = pTouch->getLocation();    // 获取触摸点
m_bMoveLayer = false;
return true;
}

//////////////////////////////////////////////////////////////////////////
void CSlidingLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
m_bMoveLayer = true;
if (m_vecSprite.size() <= 0)
{
return ;
}

int nCurSpriteTemp = m_nCurSprite;
int nWillShowSpriteIndex = m_nCurSprite;    // 将要显示的精灵的索引,就是你左右滑动时,要显示的精灵
CCPoint ptTouch = pTouch->getLocation();
if (ptTouch.x > m_ptTouchDown.x)        // 向右滑动
{
nWillShowSpriteIndex--;
}
else if (ptTouch.x < m_ptTouchDown.x)   // 向左滑动
{
nWillShowSpriteIndex++;
}
nWillShowSpriteIndex = __max(0, nWillShowSpriteIndex);
nWillShowSpriteIndex = __min(nWillShowSpriteIndex, (int)m_vecSprite.size() - 1);
nCurSpriteTemp = __max(0, nCurSpriteTemp);
nCurSpriteTemp = __min(nCurSpriteTemp, (int)m_vecSprite.size() - 1);

// 当前页移动显示
int nDalta = ptTouch.x - m_ptTouchDown.x;            // 手指当前滑动到的触摸点与刚开始触摸的点的X差值
CCSprite* pSprite = m_vecSprite[nCurSpriteTemp];
CCAssert(pSprite != NULL, "");
CCSize size = CCDirector::sharedDirector()->getWinSize();
pSprite->setPosition(ccp(size.width / 2 + nDalta, size.height / 2));    // 移动当前页

if (nWillShowSpriteIndex != nCurSpriteTemp)    // 移动将要显示的页
{
CCSprite* pSpriteWillShow = m_vecSprite[nWillShowSpriteIndex];
MUSTOK(pSpriteWillShow);
if (nWillShowSpriteIndex < nCurSpriteTemp)
{
pSpriteWillShow->setPosition(ccp(-size.width / 2 + nDalta, size.height / 2));    // 向右移动时,将要显示的页在屏幕左边,锚点在半屏之外
}
else
{
pSpriteWillShow->setPosition(ccp(size.width * 3 / 2 + nDalta, size.height / 2)); // 向左移动时,将要显示的页在屏幕右边,锚点在3/2屏之外
}
}
}

//////////////////////////////////////////////////////////////////////////
void CSlidingLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
if (m_vecSprite.size() == 0)
{
return ;
}

CCPoint ptEnd = pTouch->getLocation();
if (ptEnd.x > m_ptTouchDown.x)          // 向右滑
{
if (ptEnd.x - m_ptTouchDown.x >= NEXT_SPRITE_SHOW)
{
m_nCurSprite--;    // 当前页变为前一页
}
}
else if (ptEnd.x < m_ptTouchDown.x)     // 向左滑
{
if (m_ptTouchDown.x - ptEnd.x >= NEXT_SPRITE_SHOW)
{
m_nCurSprite++;    // 当前页变为下一页
}
}
m_nCurSprite = __min(m_nCurSprite, (int)m_vecSprite.size() - 1);
m_nCurSprite = __max(0, m_nCurSprite);

if (m_vecSprite.size() != 0)
{
CCSprite* pSprite = m_vecSprite[m_nCurSprite];
CCAssert(pSprite != NULL, "");
CCSize size = CCDirector::sharedDirector()->getWinSize();
pSprite->setPosition(ccp(size.width / 2, size.height / 2));    // 将当前页显示在屏幕中间

// 为了使左右两个精灵不对当前页构成显示影响,将左右精灵都移动到很远很远的地方去
if (m_nCurSprite >= 1)
{
pSprite = m_vecSprite[m_nCurSprite - 1];
pSprite->setPosition(ccp(-10000, 0));
}
if (m_nCurSprite + 1 <= (int)m_vecSprite.size() - 1)
{
pSprite = m_vecSprite[m_nCurSprite + 1];
pSprite->setPosition(ccp(-10000, 0));
}
}
}

//////////////////////////////////////////////////////////////////////////
void CSlidingLayer::AddSprite(CCSprite* pSprite)
{
CCAssert(pSprite != NULL, "");
m_vecSprite.push_back(pSprite);
}


步骤很简单

1、当手指触摸时,记录触摸点

2、当手指滑动时,判断是左滑动还是右滑动,移动当前页,如果左滑动,还要移动下一页,如果右滑动,则还要移动的是上一页

3、当放开手指时,判断滑动距离,如果是滑动操作,则根据左滑和右滑分别显示不同的当前页。并且把当前页左右两边的精灵移动到远方,不让其妨碍当前页的显示

使用起来也很简单,只要将你的类派生于CSlidingLayer,然后在三个手指函数的最后加上CSlidingLayer::xxxxxx就可以了,跟MFC的做法是一样的。

比如,以下三个函数

//////////////////////////////////////////////////////////////////////////
bool CRossingMgr::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CSlidingLayer::ccTouchBegan(pTouch, pEvent);
return true;
}

//////////////////////////////////////////////////////////////////////////
void CRossingMgr::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
CSlidingLayer::ccTouchMoved(pTouch, pEvent);
}

//////////////////////////////////////////////////////////////////////////
void CRossingMgr::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
CSlidingLayer::ccTouchEnded(pTouch, pEvent);
}


效果图如下:



是不是so easy,妈妈再也不用担心我的滑屏了~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: