吐槽下csdn,我打老。。虎。。机,我的账号会被封。。难怪我之前要做这个动画的时候,找不到一个好点的参考资料!
原理:
1: 靠ScrollView遮挡,是其在有限的区域运动!
2: 在update中更新每个精灵的位置,这些位置用物理的基础知识做运算!(当位置小于某个值时,将其弄到最上面!)
3: 让精灵停在制定位置,则是当加速到一定程度,然后设定指定圈数,然后停下!
int m_cardsReturnResult; float m_cardsDistance; bool m_bUpdate1Flag; //四個精灵的编号 vector<int> m_vec_allCards; //每一列的纵坐标 float m_cardPosY[CardsSum]; //每一列的横坐标 float m_cardPosX[LowsSum]; //三列的所有精灵 CCSprite* m_sCards[LowsSum][CardsSum]; //每一列加速减速匀速的时间 float m_sCardsChangeTimes[LowsSum][AddDelSpeedSum]; //初速度 float m_cardsV0[LowsSum]; //时间 float m_cardsTime[LowsSum]; //是否update bool m_cardsIsUpdate[LowsSum]; //是否在最后位置停下 bool m_cardsIsUpdateEndPos[LowsSum]; //最后的一个数 vector<int> m_cardsEndNum; //卡片到结束要转的圈数 int m_cardsEndRool[LowsSum]; //定时器刷新位置 void update(float dt); void fun_cardsAction(int _lowNum,float dt); bool fun_cardsMove(int _lowNum,float dt,int isFinish = -1); //通过m_cardsReturnResult,得到返回最后结果的容器 vector<int> getEndNum(); int getRandCardDifByOther(int _cardColor); vector<int> getEndAllDifNum(int count = 3);
cpp的核心代码:
1: 靠ScrollView遮挡,是其在有限的区域运动!
Node* node_container = Node::create(); ScrollView* scrollView = ScrollView::create(); if (scrollView && node_container) { scrollView->setContainer(node_container); scrollView->setViewSize(Size(500,250)); scrollView->setContentSize(Size(500,500)); scrollView->setTouchEnabled(false); this->addChild(scrollView); scrollView->setPosition(Vec2(size.width / 2 - 500 / 2,size.height / 2 - 250 / 2)); } m_cardsDistance = 115; m_cardPosY[0] = -120 + m_cardsDistance * 0; m_cardPosY[1] = -120 + m_cardsDistance * 1; m_cardPosY[2] = -120 + m_cardsDistance * 2; m_cardPosY[3] = -120 + m_cardsDistance * 3; m_cardPosX[0] = scrollView->getContentSize().width * 1 / 6; m_cardPosX[1] = scrollView->getContentSize().width * 1 / 2; m_cardPosX[2] = scrollView->getContentSize().width * 5 / 6; const char* szName[] = { "1.png","2.png","3.png","4.png" }; for (int i = 0; i < LowsSum; i++) { for (int j = 0; j < CardsSum; j++) { m_sCards[i][j] = Sprite::create(szName[j]); if (m_sCards[i][j]) { m_sCards[i][j]->setPosition(ccp(m_cardPosX[i],m_cardPosY[j])); node_container->addChild(m_sCards[i][j]); } } }
2: 在update中更新每个精灵的位置,这些位置用物理的基础知识做运算!(当位置小于某个值时,将其弄到最上面!)
精灵加速部分(匀速和减速相同的道理):
float k = 1000.0f; float v0 = m_cardsV0[_lowNum]; m_cardsTime[_lowNum] += dt; m_cardsV0[_lowNum] = v0 + k*dt; float moveSum = (v0 + m_cardsV0[_lowNum])*dt / 2; fun_cardsMove(_lowNum,moveSum);其中fun_cardsMove函数
bool GameLayer::fun_cardsMove(int _lowNum,float _moveSum,int isFinish /*= -1*/) { for (int i = 0; i < CardsSum; i++) { Sprite* sp = m_sCards[_lowNum][i]; if (sp) { float flagPosY = sp->getPositionY() - _moveSum; if (flagPosY < -50) { flagPosY = flagPosY + m_cardsDistance * 4; //转的圈数减一 if (isFinish == 2 && i == m_cardsEndNum[_lowNum]) { m_cardsEndRool[_lowNum] = m_cardsEndRool[_lowNum] - 1; } } sp->setPositionY(flagPosY); } } return false; }3: 让精灵停在制定位置,则是当加速到一定程度,然后设定指定圈数(上面代码中的m_cardsEndRool[_lowNum]),然后停下!
匀减速部分,做了很多非常规处理
int _endPos = m_cardsEndNum[_lowNum]; Sprite* sp2 = m_sCards[_lowNum][_endPos]; if (m_cardsEndRool[_lowNum] == 0) { if (sp2->getPositionY() >= m_cardPosY[2]) { float dis = sp2->getPositionY() - m_cardPosY[2]; if (fabsf(dis) < 1) { m_cardsIsUpdateEndPos[_lowNum] = true; //show result if (m_cardsIsUpdateEndPos[0] && m_cardsIsUpdateEndPos[1] && m_cardsIsUpdateEndPos[2]) { this->unschedule(schedule_selector(GameLayer::update)); } return; } float k = m_cardsV0[_lowNum] * m_cardsV0[_lowNum] / (2 * dis); float v0 = m_cardsV0[_lowNum]; m_cardsTime[_lowNum] += dt; m_cardsV0[_lowNum] = v0 - k * dt; //不正常情况下 if (v0 <= 0) { float moveSum = sp2->getPositionY() - m_cardPosY[2]; fun_cardsMove(_lowNum,moveSum); CCLOG("v0 no normal_1: %d,m_cardsV0: %lf,moveSum: %lf,a: %lf,dis: %lf",_lowNum,m_cardsV0[_lowNum],moveSum,k,dis); return; } //正常情况下 float moveSum = (v0 + m_cardsV0[_lowNum]) * dt / 2; fun_cardsMove(_lowNum,moveSum); } else { //不正常情况下 float dis = m_cardsDistance * 4 - m_cardPosY[2] + sp2->getPositionY();//; float k = m_cardsV0[_lowNum] * m_cardsV0[_lowNum] / (2 * dis); float v0 = m_cardsV0[_lowNum]; m_cardsTime[_lowNum] += dt; m_cardsV0[_lowNum] = v0 - k * dt; float moveSum = (v0 + m_cardsV0[_lowNum]) * dt / 2; fun_cardsMove(_lowNum,moveSum); CCLOG("v0 no normal_2: %d,dis); } return; }一些效果图:
源码地址: