graphics view 框架结构主要包含三个类,场景类(qgraphicsscene),视图类(qgraphicsview)和图元类(qgraphicsitem)
#include "dialog.h"
#include
#include "ui_dialog.h"
// 游戏的初始速度
static const qreal INITSPEED = 500;
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
//设置场景
QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0,0, 750, 580);
ui->graphicsView->setScene(scene);
//scene->setBackgroundBrush(QPixmap(":/images/background.png"));
topLine = scene->addLine(100,20, 400, 20);
bottomLine = scene->addLine(100,520, 400, 520);
leftLine = scene->addLine(100, 20, 100, 520);
rightLine = scene->addLine(400,20,400,520);
// 当前方块组和提示方块组
boxGroup = new BoxGroup;
connect(boxGroup, SIGNAL(needNewBox()), this, SLOT(clearFullRows()));
connect(boxGroup, SIGNAL(gameFinished()), this, SLOT(gameOver()));
scene->addItem(boxGroup);
nextBoxGroup = new BoxGroup;
scene->addItem(nextBoxGroup);
startGame();
}
// 开始游戏
void Dialog::startGame()
{
initGame();
}
// 初始化游戏
void Dialog::initGame()
{
boxGroup->createBox(QPointF(300, 70));
boxGroup->setFocus();
boxGroup->startTimer(INITSPEED);
gameSpeed = INITSPEED;
nextBoxGroup->createBox(QPointF(640, 70));
}
// 清空满行
void Dialog::clearFullRows()
{
// 获取比一行方格较大的矩形中包含的所有小方块
for (int y = 429; y > 50; y -= 20) {
QList<QGraphicsItem *> list = ui->graphicsView->scene()->items(199, y, 202, 22, Qt::ContainsItemShape, Qt::AscendingOrder);
// 如果该行已满
if (list.count() == 10) {
foreach (QGraphicsItem *item, list) {
mybox *box = (mybox*) item;
box->deleteLater();
}
// 保存满行的位置
rows << y;
}
}
// 如果有满行,下移满行上面的各行再出现新的方块组
// 如果没有满行,则直接出现新的方块组
if(rows.count() > 0) {
moveBox();
} else {
boxGroup->createBox(QPointF(300, 70), nextBoxGroup->getCurrentShape());
// 清空并销毁提示方块组中的所有小方块
nextBoxGroup->clearBoxGroup(true);
nextBoxGroup->createBox(QPointF(500, 70));
}
}
// 下移满行上面的所有小方块
void Dialog::moveBox()
{
// 从位置最靠上的满行开始
for (int i = rows.count(); i > 0; --i) {
int row = rows.at(i - 1);
foreach (QGraphicsItem *item,ui->graphicsView->scene()->items(199, 49, 202, row - 47, Qt::ContainsItemShape, Qt::AscendingOrder)) {
item->moveBy(0, 20);
}
}
// 更新分数
updateScore(rows.count());
// 将满行列表清空为0
rows.clear();
// 等所有行下移以后再出现新的方块组
boxGroup->createBox(QPointF(300, 70), nextBoxGroup->getCurrentShape());
nextBoxGroup->clearBoxGroup(true);
nextBoxGroup->createBox(QPointF(500, 70));
}
void Dialog::updateScore(const int fullRowNum)
{
// 更新分数
}
void Dialog::gameOver()
{
// 游戏结束
}
Dialog::~Dialog()
{
delete ui;
}