mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-28 00:42:19 -07:00
[Game] Animate arrows with a draw-on effect on creation
This commit is contained in:
parent
12fb19ef06
commit
15027497ee
3 changed files with 56 additions and 1 deletions
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QTimer>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
#include <libcockatrice/card/card_info.h>
|
#include <libcockatrice/card/card_info.h>
|
||||||
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
|
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
|
||||||
|
|
@ -91,10 +92,11 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
if (lineLength < 30) {
|
if (lineLength < 30) {
|
||||||
path = QPainterPath();
|
path = QPainterPath();
|
||||||
|
centerLine = QPainterPath();
|
||||||
} else {
|
} else {
|
||||||
QPointF c(lineLength / 2, qTan(phi * M_PI / 180) * lineLength);
|
QPointF c(lineLength / 2, qTan(phi * M_PI / 180) * lineLength);
|
||||||
|
|
||||||
QPainterPath centerLine;
|
centerLine = QPainterPath();
|
||||||
centerLine.moveTo(0, 0);
|
centerLine.moveTo(0, 0);
|
||||||
centerLine.quadTo(c, QPointF(lineLength, 0));
|
centerLine.quadTo(c, QPointF(lineLength, 0));
|
||||||
|
|
||||||
|
|
@ -125,6 +127,32 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||||
setTransform(QTransform().rotate(-line.angle()));
|
setTransform(QTransform().rotate(-line.angle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArrowItem::startDrawAnimation()
|
||||||
|
{
|
||||||
|
if (!SettingsCache::instance().userInterface().getAnimationsEnabled() || centerLine.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawProgress = 0.0;
|
||||||
|
if (drawTimer == nullptr) {
|
||||||
|
drawTimer = new QTimer(this);
|
||||||
|
connect(drawTimer, &QTimer::timeout, this, [this] {
|
||||||
|
if (!SettingsCache::instance().userInterface().getAnimationsEnabled()) {
|
||||||
|
drawProgress = 1.0;
|
||||||
|
drawTimer->stop();
|
||||||
|
} else {
|
||||||
|
drawProgress += 0.08;
|
||||||
|
if (drawProgress >= 1.0) {
|
||||||
|
drawProgress = 1.0;
|
||||||
|
drawTimer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
drawTimer->start(20);
|
||||||
|
}
|
||||||
|
|
||||||
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||||
{
|
{
|
||||||
QColor paintColor(data->color);
|
QColor paintColor(data->color);
|
||||||
|
|
@ -133,8 +161,29 @@ void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti
|
||||||
} else {
|
} else {
|
||||||
paintColor.setAlpha(150);
|
paintColor.setAlpha(150);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
if (drawProgress < 1.0 && !path.isEmpty()) {
|
||||||
|
QRectF pr = path.boundingRect();
|
||||||
|
qreal revealX = pr.left() + pr.width() * drawProgress;
|
||||||
|
QPainterPath clip;
|
||||||
|
clip.addRect(QRectF(pr.left() - 100, pr.top() - 100, revealX - pr.left() + 200, pr.height() + 200));
|
||||||
|
painter->setClipPath(clip);
|
||||||
|
}
|
||||||
painter->setBrush(paintColor);
|
painter->setBrush(paintColor);
|
||||||
painter->drawPath(path);
|
painter->drawPath(path);
|
||||||
|
|
||||||
|
if (drawProgress < 1.0 && !centerLine.isEmpty()) {
|
||||||
|
const QPointF impulse = centerLine.pointAtPercent(drawProgress);
|
||||||
|
QRadialGradient glow(impulse, 10);
|
||||||
|
glow.setColorAt(0, QColor(255, 255, 255, 230));
|
||||||
|
glow.setColorAt(0.4, paintColor);
|
||||||
|
glow.setColorAt(1, QColor(paintColor.red(), paintColor.green(), paintColor.blue(), 0));
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(glow);
|
||||||
|
painter->drawEllipse(impulse, 8, 8);
|
||||||
|
}
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
class CardItem;
|
class CardItem;
|
||||||
class QGraphicsSceneMouseEvent;
|
class QGraphicsSceneMouseEvent;
|
||||||
class PlayerLogic;
|
class PlayerLogic;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
class ArrowItem : public QObject, public QGraphicsItem
|
class ArrowItem : public QObject, public QGraphicsItem
|
||||||
{
|
{
|
||||||
|
|
@ -21,6 +22,9 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
|
QPainterPath centerLine;
|
||||||
|
qreal drawProgress = 1.0;
|
||||||
|
QTimer *drawTimer = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSharedPointer<const ArrowData> data;
|
QSharedPointer<const ArrowData> data;
|
||||||
|
|
@ -38,6 +42,7 @@ public:
|
||||||
void delArrow();
|
void delArrow();
|
||||||
void updatePath();
|
void updatePath();
|
||||||
void updatePath(const QPointF &endPoint);
|
void updatePath(const QPointF &endPoint);
|
||||||
|
void startDrawAnimation();
|
||||||
|
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||||
[[nodiscard]] QRectF boundingRect() const override
|
[[nodiscard]] QRectF boundingRect() const override
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,7 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *arrow = new ArrowItem(data, startCard, targetItem);
|
auto *arrow = new ArrowItem(data, startCard, targetItem);
|
||||||
|
arrow->startDrawAnimation();
|
||||||
addItem(arrow);
|
addItem(arrow);
|
||||||
arrowRegistry.insert(data, arrow);
|
arrowRegistry.insert(data, arrow);
|
||||||
connect(arrow, &ArrowItem::requestDeletion, this, &GameScene::requestArrowDeletion);
|
connect(arrow, &ArrowItem::requestDeletion, this, &GameScene::requestArrowDeletion);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue