1

我正在 Qt 中制作基于 2D 网格的游戏。

当点击网格中的一个方格时,玩家将按照使用 A* 算法计算的路径移动到该方格。但是,我希望能够对此进行动画处理。因此,玩家不必立即到达目标,而是必须从一个方格(节点)到另一个方格,直到它以用户可以设置的速度到达目标。

问题:实现这一目标的最简单方法是什么?

4

2 回答 2

4

就个人而言,我会设计类似于以下内容:

class Player : public QObject {
    ...
    QPoint pos;
    QList<QPoint> path;
    QPropertyAnimation posAnimation;
};

定义posQ_PROPERTY. 这使您可以使用QPropertyAnimation此值定义动画,以动画化两个相邻点之间的移动。动画完成后,take()从路径中移一点并重新配置动画,为您提供沿整个路径的动画。

使用animationFinished()Player 类中的插槽为动画提供下一个点。

要启动这样的动画,请用值(在函数或类似函数中)填充路径move(QList<QPoint> path),设置动画的值并启动它。

这些代码片段应该可以帮助您:

// in constructor:
posAnimation.setPropertyName("pos");
posAnimation.setTargetObject(this);
connect(&posAnimation, SIGNAL(finished()), SLOT(animationFinished()));

// in the slot:
if(!path.empty()) {
    posAnimation.setStartValue(pos());
    posAnimation.setEndValue(path.takeFirst());
    posAnimation.start();
}

要定义pos为属性,您必须定义两个插槽:读取和写入函数,也称为 getter 和 setter:

class Player : public QObject {
    Q_OBJECT
    Q_PROPERTY(QPoint pos READ pos WRITE setPos) // define meta-property "pos"
    ...
public slots:
    QPoint pos() const; // getter
    void setPos(QPoint p); // setter
private:
    QPoint m_pos; // private member
};

QPoint Player::pos() const {
    return m_pos;
}
void Player::setPos(QPoint pos) {
    m_pos = pos;
}

Q_PROPERTY行仅声明了一个meta-property。这与 C++ 无关,但是 Qt 的元对象编译器会解析这一行并在内部属性列表中添加一个条目。然后,您可以说player->property("pos")访问该位置而不是player->pos(). 您可能想知道为什么这很有用。当您只想将属性名称作为字符串传递时,它很有用,例如告诉 QPropertyAnimation 要为哪个属性设置动画。另一种情况是使用 QML 之类的脚本。然后你在你的类中定义属性。您可以在 Qt 文档中阅读有关元属性的更多信息:属性系统

于 2013-01-05T22:56:19.277 回答
1

Take a look at the demo of the tower defense game Squaby made with the V-Play (v-play.net) engine. You can access the full source code here: Squaby. V-Play provides you with game components for path finding and more (API reference).

于 2013-06-07T08:17:19.997 回答