我正在 Qt 中制作基于 2D 网格的游戏。
当点击网格中的一个方格时,玩家将按照使用 A* 算法计算的路径移动到该方格。但是,我希望能够对此进行动画处理。因此,玩家不必立即到达目标,而是必须从一个方格(节点)到另一个方格,直到它以用户可以设置的速度到达目标。
问题:实现这一目标的最简单方法是什么?
就个人而言,我会设计类似于以下内容:
class Player : public QObject {
...
QPoint pos;
QList<QPoint> path;
QPropertyAnimation posAnimation;
};
定义pos
为Q_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 文档中阅读有关元属性的更多信息:属性系统。
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).