BezierEqualPointsAction.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //
  2. // BezierEqualPointsAction.cpp
  3. // redream_runtime
  4. //
  5. // Created by 潮伟钦 on 2022/7/18.
  6. //
  7. #include "BezierEqualPointsAction.hpp"
  8. #define DEBUG_PATH false
  9. BezierEqualPointsAction* BezierEqualPointsAction::create(float duration, std::vector<Vec2> equalPoints) {
  10. BezierEqualPointsAction *ret = new (std::nothrow) BezierEqualPointsAction();
  11. if (ret && ret->initWithDuration(duration, equalPoints))
  12. {
  13. ret->autorelease();
  14. return ret;
  15. }
  16. delete ret;
  17. return nullptr;
  18. }
  19. bool BezierEqualPointsAction::initWithDuration(float duration, std::vector<Vec2> equalPoints) {
  20. ActionInterval::initWithDuration(duration);
  21. _equalPoints = equalPoints;
  22. #if DEBUG_PATH
  23. DrawNode* dn = DrawNode::create();
  24. for (Vec2 p : equalPoints) {
  25. dn->drawDot(p, 1, Color4F::RED);
  26. }
  27. dn->retain();
  28. Director::getInstance()->getScheduler()->schedule([=](float dt){
  29. Director::getInstance()->getRunningScene()->addChild(dn);
  30. dn->release();
  31. }, Director::getInstance(), 1, 0, 1, false, "!231231231");
  32. #endif
  33. _length = 0;
  34. Vec2 last = _equalPoints[0];
  35. _count = (int)_equalPoints.size();
  36. for (int i = 1; i < _count; ++i) {
  37. Vec2 now = _equalPoints[i];
  38. float curLength = last.distance(now);
  39. _length = _length + curLength;
  40. last = now;
  41. }
  42. return true;
  43. }
  44. void BezierEqualPointsAction::update(float time) {
  45. float idx_f = (_count-1) * time;
  46. int idx_i = (int)idx_f;
  47. idx_i = min(idx_i, (int)(_equalPoints.size() - 1));
  48. idx_i = max(0, idx_i);
  49. Vec2 pos = _equalPoints.at(idx_i);
  50. float p = idx_f - idx_i;
  51. if (p > 0.0f) { // 有余数
  52. if (idx_i+1 < _equalPoints.size()) {
  53. Vec2 nextPos = _equalPoints.at(idx_i+1);
  54. pos = (nextPos-pos)*p + pos;
  55. }
  56. }
  57. _target->setPosition(pos);
  58. #if DEBUG_PATH
  59. auto dn = static_cast<DrawNode*>(Director::getInstance()->getRunningScene()->getChildByTag(213));
  60. if (dn == nullptr) {
  61. dn = DrawNode::create();
  62. dn->setTag(213);
  63. Director::getInstance()->getRunningScene()->addChild(dn);
  64. }
  65. dn->drawDot(pos, 3, Color4F::BLUE);
  66. #endif
  67. }