1. 程序简介:
俄罗斯方块是一款大家都熟系的小游戏,这里给大家一步一步的详细介绍如何用QT开发这个游戏,并通过这款游戏的开发练习,进一步熟系"qvector.h","qpoint.h", "qmap.h","qpainter.h", QTime, KeyEvent,QMediaPlaylist,QMediaPlayer 等的用法。
2. 程序说明:
2.1 程序界面:分游戏区,提示区,控制区
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
2.2 程序实现功能:
1) 绘制游戏区域;
2) 按开始按钮开始游戏;
3) 按方向键实现方块的左移,右移,翻转;
4) 按空格键实现方块移动到最底部;
5) 当一行排满之后,自动消行。消行后,自动记分。
6) 每满1000分后,自动升到下一级,每升一级,方块向下移动的速度加快;
7) 记录游戏时间;
8) 按暂停按钮暂停游戏;
9) 按结束按钮结束游戏;
10)单击音乐按扭打开/关闭背景音乐;
3. 程序设计
3. 1 创建项目
3.1.1 新建一个以QMainWindow 为基类的Qt Widgets Application,取名 Teris;
3.1.2. 构建项目
1)单击项目模式,在弹出的窗口中选择构建套件,后按Configure Project 按扭。
构建完成后,程序处于可编译状态。
3.2 UI设计
3.2.1 移除窗口中的菜单栏,状态栏;
3.2.2 按下面示意图来设计窗体。
注意:
a. 主窗体大小设置为1000*800;
b. widgetGameArea 窗体大小设为600*800;
c. 先设计排版好控件后,再按Gridlayout;
d. 3 个Pushbutton 和CheckBox 的Focus Policy 设置为NoFocus;
3.2.3 在mainwindow.cpp 中填加如下语句:
setFixedSize(1000,800); //设置窗体为固定大小
setWindowTitle(tr("俄罗斯方块"));//设置窗体标题
3.2.4 运行效果如下
3.3 创建方块类:
3.3.1 新建一个C++ Class 文件,取名为Item, 并勾选#include Widget, #include QObject , Add Q_OBJECT.
3.3.2 在item.h中添加头文件 ,定义方块类形枚举变量,在GameArea 类体中添加 public 变量,成员函数;
#ifndef ITEM_H
#define ITEM_H
#include <QObject>
#include <QWidget>
#include "qvector.h"
#include "qpoint.h"
#include "qpainter.h"
enum ITEM_TYPE{
ITEM_1 = 0, //长条
ITEM_2, //山字形
ITEM_3, //手枪形1
ITEM_4, //手枪形2
ITEM_5, //田
ITEM_6, //Z字形1
ITEM_MAX,
};
class Item
{
public:
Item(){}
Item(ITEM_TYPE t,int nShape = 0); //类型和形状构造
~Item(void){};
void InitNew(int nSeed = 0); //根据随机因子nSeed, 初始化方块类形的种类及形状
void InitItem(ITEM_TYPE t,int nShape = 0); //根据方块类形的种类及形状,初始化方块类形的坐标
void ChangeShape(int nAdd = 1); //改变文块类形形状, 默认按顺续改变形状
void AddPoints(QVector<QPoint>& points); //添加方块格子坐标
void Move(int x,int y); //横向移动x格,竖向移动y格
void MoveTo(int x,int y); //移动到位置(x,y)格
void MoveDown(int nRow,int y); //第nRow行以上的部分下移y行,用在消格之后
void Draw(QPainter& painter,int nStartX,int nStartY,int nW,int nH); //根据方块格子的起始位置座标,长,宽,画出方块格子
void DeleteRow(int y); //删除第y行
public:
QVector<QPoint> mPoints; //方块类型4个方块格子的坐标
QPoint mPos; //方块类型原点
ITEM_TYPE mType; //方块类型,有6种类型
int mShape; //方块形状,每个类型方块有1~4个形状态,
};
#endif // ITEM_H
3.3.3 在item.cpp 中实现成员函数。
#include "item.h"
#include <QTime>
Item::Item(ITEM_TYPE t,int nShape) //类型和形状构造
{
mPos=QPoint(0,0); // 初始化方块类型的原点坐标
InitItem(t,nShape); // 根据方块类形的种类及形状,初始化方块类形的坐标
}
void Item::InitNew(int nSeed)
{
if(nSeed == 0)
{
//如果没有随机因子,就使用当前时间作随机因子
qsrand(QTime::currentTime().msec()); //qsrand, 使用Seed 生成随机数。后面的Qrand 使用相同的随机数序列
}
else
{
//传入随机因子
qsrand(nSeed);
}
ITEM_TYPE t = (ITEM_TYPE)(qrand()%ITEM_MAX); // 产生随机的方块类型
int s = qrand()%4; // 产生随机的形状
//qDebug()<<"t="<<t<<"s="<<s;
InitItem(t,s); //构造方块类型的坐标
}
void Item::InitItem(ITEM_TYPE t,int nShape) //根据方块类形的种类及形状,初始化方块类形的坐标
{
mPoints.clear(); //坐标初始化
mType = t; //初始化Item类体变量mType
mShape = nShape; //初始化Item类体变量mShape
switch (t)
{
case ITEM_1: //如果是长条形
{
if (nShape%2 == 0) //如果形状是0或2
{
for (int i = 0; i < 4; i++)
{
mPoints.append(mPos + QPoint( i,2));//QPoint 加法重载 ,(0,2),(1,2),(2,2),(3,2)
}
}
else if (nShape%2 == 1) //如果形状是1或3
{
for (int i = 0; i < 4; i++)
{
mPoints.append(mPos + QPoint( 2,i));//(2,0),(2,1),(2,2),(2,3)