Qt实现Flappy Bird游戏

2020-01-06 20:09:37刘景俊


GraphicsButtonItem::GraphicsButtonItem(const QPixmap &pixmap, QGraphicsScene *scene) : pix(pixmap)
{
 scene->addItem(this);
 setCursor(QCursor(Qt::PointingHandCursor));
}

void GraphicsButtonItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
 if (event->button() == Qt::LeftButton)
 {
  emit clicked();
 }
 __super::mousePressEvent(event);
}

QSizeF GraphicsButtonItem::size() const
{
 return pix.size();
}

QRectF GraphicsButtonItem::boundingRect() const
{
 return QRectF(QPointF(0, 0), pix.size());
}

void GraphicsButtonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
 painter->drawPixmap(0, 0, pix);
}

管道组件绘制


#define PIPE_WIDTH 60

GraphicsPipeitem::GraphicsPipeitem(QGraphicsScene *scene)
{
 m_scene = scene;
 m_scene->addItem(this);

 createPipeHeight();
 startMove();
}
void GraphicsPipeitem::createPipeHeight()
{
 m_upPipeHeight = qrand() % 100 + 80;
 m_downPipeHeight = m_scene->height() - m_upPipeHeight - 178;
}

QRectF GraphicsPipeitem::boundingRect() const
{
 return QRectF(m_scene->width(), 0, PIPE_WIDTH, m_scene->height());
}

QPainterPath GraphicsPipeitem::shape() const
{
 QPainterPath path;
 path.addRect(QRectF(m_scene->width(), 0, PIPE_WIDTH, m_upPipeHeight));
 path.addRect(QRectF(m_scene->width(), m_upPipeHeight + 140, PIPE_WIDTH, m_downPipeHeight));
 return path;
}


void GraphicsPipeitem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
 painter->save();
 painter->drawImage(QRectF(m_scene->width(), 0, PIPE_WIDTH, m_upPipeHeight), QImage(":/FlappyBird/Resources/texture/tubeup.png").scaled(PIPE_WIDTH, m_upPipeHeight));
 painter->drawImage(QRectF(m_scene->width(), m_upPipeHeight + 140, PIPE_WIDTH, m_downPipeHeight), QImage(":/FlappyBird/Resources/texture/tubedown.png").scaled(PIPE_WIDTH, m_downPipeHeight));
 painter->restore();
}

void GraphicsPipeitem::startMove()
{
 QPropertyAnimation* moveAnimation = new QPropertyAnimation(this, "pos");
 moveAnimation->setLoopCount(-1);
 moveAnimation->setDuration(3000);
 moveAnimation->setStartValue(QPoint(0, pos().y()));
 moveAnimation->setEndValue(QPoint(-1 * m_scene->width() - PIPE_WIDTH, pos().y()));
 moveAnimation->start();
 connect(moveAnimation, &QPropertyAnimation::currentLoopChanged, [this](int loopCount){
  createPipeHeight();
 });
}

地面绘制


#define ROAD_ITEM_HEIGHT 38

GraphicsRoadItem::GraphicsRoadItem(QGraphicsScene *scene) :m_scene(scene)
{
 scene->addItem(this);
 startMove();
}

QRectF GraphicsRoadItem::boundingRect() const
{
 return QRectF(0, m_scene->height() - ROAD_ITEM_HEIGHT, m_scene->width() * 2, ROAD_ITEM_HEIGHT);
}

void GraphicsRoadItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
 painter->drawImage(QRectF(0, m_scene->height() - ROAD_ITEM_HEIGHT, m_scene->width(), ROAD_ITEM_HEIGHT), QImage(":/FlappyBird/Resources/texture/road.png"));
 painter->drawImage(QRectF(m_scene->width(), m_scene->height() - ROAD_ITEM_HEIGHT, m_scene->width(), ROAD_ITEM_HEIGHT), QImage(":/FlappyBird/Resources/texture/road.png"));
}

void GraphicsRoadItem::startMove()
{
 QPropertyAnimation* moveAnimation = new QPropertyAnimation(this, "pos");
 moveAnimation->setLoopCount(-1);
 moveAnimation->setDuration(6000);
 moveAnimation->setStartValue(QPoint(0, pos().y()));
 moveAnimation->setEndValue(QPoint(0 - m_scene->width(), pos().y()));
 moveAnimation->setEasingCurve(QEasingCurve::Linear);
 moveAnimation->start();
}