在2D中沿着航点移动对象

时间:2010-12-06 14:25:22

标签: qt path pseudocode

我创建了此功能,以便在list_中保存的路点上移动单位。每个单位都有自己的list_move()最初是以每一步的速度(距离/步长)调用的。然后根据到下一个路点的距离,采取三种可能的行动。

你能否提出任何改进建议?

void Unit::move(qreal maxDistance)
{
 // Construct a line that goes from current position to next waypoint
 QLineF line = QLineF(pos(), list_.firstElement().toPointF());

 // Calculate the part of this line that can be "walked" during this step.
 qreal part = maxDistance / line.length();

 // This step's distance is exactly the distance to next waypoint.
 if (part == 1) {
  moveBy(line.dx(), line.dy());
  path_.removeFirst();
 }
 // This step's distance is bigger than the distance to the next waypoint.
 // So we can continue from next waypoint in this step.
 else if (part > 1)
 {
  moveBy(line.dx() , line.dy());
  path_.removeFirst();
  if (!path_.isEmpty())
  {
   move(maxDistance - line.length());
  }
 }
 // This step's distance is not enough to reach next waypoint.
 // Walk the appropriate part of the length.
 else /* part < 1 */
 {
  moveBy(line.dx() * part, line.dy() * part);
 }
}

2 个答案:

答案 0 :(得分:1)

我会讨厌建议一种弃用的做法,但是没有提到替换方法:(

QGraphicsItemAnimation

为方便起见,它有addStep和线性插值。

似乎Qt开发人员希望您使用QTimeLine本身作为替代。

答案 1 :(得分:1)

我更准确地使用Qt动画框架QPropertyAnimation

// I use QPainterPath to calculate the % of whole route at each waypoint. 
QVector<qreal> lengths;

QPainterPath path;
path.moveTo(list_.first());
lengths.append(0);

foreach (const QPointF &waypoint, list_.mid(1)) {
    path.lineTo(waypoint);
    lengths.append(path.length());
}

// KeyValues is typedef for QVector< QPair<qreal, QVariant> >
KeyValues animationKeyValues; 
for (int i(0); i != lenghts.count(); ++i) {
    animationKeyValues.append(qMakePair(path.percentAtLength(lenghts.at(i)), list_.at(i)));
}

// I assume unit is a pointer to a QObject deriving Unit instance and that
// Unit has QPointF "position" property 
QPropertyAnimation unitAnimation(unit, "position");
unitAnimation.setKeyValues(animationKeyValues);
unitAnimation.setDuration(/* enter desired number here */);
unitAnimation.start();

我没有测试过这个解决方案,但你应该得到一般的想法。