cocos2d-x实现滑屏

7 篇文章 0 订阅
3 篇文章 0 订阅

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

#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,妈妈再也不用担心我的滑屏了~~~~

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值