天天看点

cocos3.X 惯性滑动

1 主要思路

实现手指拖动地图后,手指离开地图后,地图距离会向着手指的方向移动一段距离:

1.在滑动中把每个点放入到容器中

2.滑动结束根据最后一个点与倒数第二点的设定x,y方向上的位移

3.根据摩擦系数,依次减小位移,直至小到一定程度

2 详细设计

2.1 给地图精灵绑定触摸监听

auto listener1 = EventListenerTouchOneByOne::create();//创建一个触摸监听
  listener1->setSwallowTouches(true); //设置是否想下传递触摸
  //通过 lambda 表达式 直接实现触摸事件的回掉方法
  listener1->onTouchBegan = [=](Touch* touch, Event* event){
    return onTouchBegan(touch, event);
  };
  listener1->onTouchMoved = [=](Touch* touch, Event* event){
    onTouchMoved(touch, event);
  };
  listener1->onTouchEnded = [=](Touch* touch, Event* event){
    onTouchEnded(touch, event);
  };
  _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, m_spr);      

2.2触摸开始

bool  HelloWorld::onTouchBegan(Touch* touch, Event*  event)
{
  auto target = static_cast<Sprite*>(event->getCurrentTarget());
  m_vecPot.clear();
  Point locationInNode = target->convertToNodeSpace(touch->getLocation());
  Size s = target->getContentSize();
  Rect rect = Rect(0, 0, s.width, s.height);

  if (rect.containsPoint(locationInNode))
  {
    log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
    target->setOpacity(180);
    return true;
  }
  return false;
}      

当按在精灵上时,返回true,表示能继续响应后面的move操作。

2.3触摸移动

void  HelloWorld::onTouchMoved(Touch* touch, Event*  event)
{
  m_bDrag = true;
  auto target = static_cast<Sprite*>(event->getCurrentTarget());
  target->setPosition(target->getPosition() + touch->getDelta());
  Point locationInNode = target->convertToWorldSpace(touch->getLocation());
  m_vecPot.push_back(locationInNode);
}      

2.4触摸结束

void  HelloWorld::onTouchEnded(Touch* touch, Event*  event)
{
  auto target = static_cast<Sprite*>(event->getCurrentTarget());
  target->setOpacity(255);
  if (m_bDrag == true)
  {
    m_bDrag = false;
    int iVecSize = m_vecPot.size();
    float fXspeed = m_vecPot[iVecSize - 1].x - m_vecPot[iVecSize - 2].x;
    float fYspeed = m_vecPot[iVecSize - 1].y - m_vecPot[iVecSize - 2].y;
    while (abs(fXspeed) > 0.1 || abs(fYspeed) > 0.1)
    {
      Point potNew = ccpAdd(target->getPosition(), Point(fXspeed, fYspeed));
      auto moveBy = MoveBy::create(0.1f, ccp(fXspeed, fYspeed));
      target->runAction(moveBy);
      fXspeed *= GfFriction;
      fYspeed *= GfFriction;
    }
  }
}      

继续阅读