QT学习路四

来源:互联网 发布:php吧 编辑:程序博客网 时间:2024/05/23 16:39

贪吃蛇游戏(一)

Qt 提供了自己的绘制系统,还提供了 Graphics View Framework。

Graphics View Framework 有三个主要部分:

  • QGraphicsScene:能够管理元素的非 GUI 容器;
  • QGraphicsItem:能够被添加到场景的元素;
  • QGraphicsView:能够观察场景的可视化组件视图。

对于游戏而言,我们需要一个QGraphicsScene,作为游戏发生的舞台;一个QGraphicsView,作为观察游戏舞台的组件;以及若干元素,用于表示游戏对象,比如蛇、食物以及障碍物等。


主窗口应该是一个QGraphicsView

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QGraphicsScene;
class QGraphicsView;

class GameController;

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void adjustViewSize();

private:
    void initScene();
    void initSceneBackground();

    QGraphicsScene *scene;
    QGraphicsView *view;

    GameController *game;
};

#endif // MAINWINDOW_H


在头文件中声明了MainWindow。构造函数除了初始化成员变量,还设置了窗口的大小,并且需要对场景进行初始化:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    scene(new QGraphicsScene(this)),
    view(new QGraphicsView(scene, this)),
    game(new GameController(*scene, this))
{
    setCentralWidget(view);
    resize(600, 600);

    initScene();
    initSceneBackground();

    QTimer::singleShot(0, this, SLOT(adjustViewSize()));
}


接下来看看initScene()initSceneBackground()的代码:

void MainWindow::initScene()
{
    scene->setSceneRect(-100, -100, 200, 200);
}

void MainWindow::initSceneBackground()
{
    QPixmap bg(TILE_SIZE, TILE_SIZE);
    QPainter p(&bg);
    p.setBrush(QBrush(Qt::gray));
    p.drawRect(0, 0, TILE_SIZE, TILE_SIZE);

    view->setBackgroundBrush(QBrush(bg));
}


现在我们的程序看起来是这样的:



下面是 food.h 和 food.cpp 的内容:

////////// food.h //////////
#ifndef FOOD_H
#define FOOD_H

#include <QGraphicsItem>

class Food : public QGraphicsItem
{
public:
    Food(qreal x, qreal y);

    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);

    QPainterPath shape() const;
};

#endif // FOOD_H

////////// food.cpp //////////
#include <QPainter>

#include "constants.h"
#include "food.h"

static const qreal FOOD_RADIUS = 3;

Food::Food(qreal x, qreal y)
{
    setPos(x, y);
    setData(GD_Type, GO_Food);
}

QRectF Food::boundingRect() const
{
    return QRectF(-TILE_SIZE,    -TILE_SIZE,
                   TILE_SIZE * 2, TILE_SIZE * 2 );
}

void Food::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->save();

    painter->setRenderHint(QPainter::Antialiasing);
    painter->fillPath(shape(), Qt::red);

    painter->restore();
}

QPainterPath Food::shape() const
{
    QPainterPath p;
    p.addEllipse(QPointF(TILE_SIZE / 2, TILE_SIZE / 2), FOOD_RADIUS, FOOD_RADIUS);
    return p;
}


GameController创建并开始游戏循环:

GameController::GameController(QGraphicsScene *scene, QObject *parent) :
    QObject(parent),
    scene(scene),
    snake(new Snake(this))
{
    timer.start(1000/33);

    Food *a1 = new Food(0, -50);
    scene->addItem(a1);

    scene->addItem(snake);

    scene->installEventFilter(this);

    resume();
}


当然,我们也可以加入pause()resume()函数:

void GameController::pause()
{
    disconnect(&timer, SIGNAL(timeout()),
               scene,  SLOT(advance()));
}

void GameController::resume()
{
    connect(&timer, SIGNAL(timeout()),
            scene,  SLOT(advance()));
}


当我们把这一切都准备好之后,我们把GameController添加到MainWindow中:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      game(new GameController(scene, this))
{
    ...
}


这样,我们就把第一个食物添加到了游戏场景:





原创粉丝点击