天天看點

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;
    }
  }
}      

繼續閱讀