Qt开发源码俄罗斯方块.docx
《Qt开发源码俄罗斯方块.docx》由会员分享,可在线阅读,更多相关《Qt开发源码俄罗斯方块.docx(22页珍藏版)》请在冰豆网上搜索。
![Qt开发源码俄罗斯方块.docx](https://file1.bdocx.com/fileroot1/2023-1/8/adfdd4aa-173d-457b-977e-5d33f7dce8d8/adfdd4aa-173d-457b-977e-5d33f7dce8d81.gif)
Qt开发源码俄罗斯方块
俄罗斯方块游戏
Main.cpp主程序代码:
#include
#include
#include"tetrixwindow.h"
intmain(intargc,char*argv[])
{
//为了能够正常显示中文,设置Tr编码环境为GB2312(详见wiki)
QTextCodec:
:
setCodecForTr(QTextCodec:
:
codecForName("GB2312"));
//app这个对象用于管理应用级别的资源
QApplicationapp(argc,argv);
app.setStyleSheet("TetrixBoard{background-color:
lightGray}");
TetrixWindowwindow;
window.setWindowIcon(QIcon(":
/Chrome.ico"));
window.show();
//当前时间作为随机种子
qsrand(QTime(0,0,0).secsTo(QTime:
:
currentTime()));
returnapp.exec();//程序的事件循环
}
Tetrixboard.h头文件代码:
//主游戏区类
#ifndefTETRIXBOARD_H
#defineTETRIXBOARD_H
#include"tetrixpiece.h"
#include
#include
#include
#include
//前向声明
classQLabel;
classTetrixBoard:
publicQFrame
{
Q_OBJECT
public:
TetrixBoard(QWidget*parent=0);
voidsetNextPieceLabel(QLabel*label);
QSizesizeHint()const;//最适合大小
QSizeminimumSizeHint()const;//最小限制
publicslots:
//公有槽
voidstart();
voidpause();
signals:
//信号:
只需声明,根据参数变化来判断
voidscoreChanged(intscore);
voidlevelChanged(intlevel);
voidlinesRemovedChanged(intnumLines);
protected:
//着色、键盘、计时事件:
其中着色事件随着update()不断触发
voidpaintEvent(QPaintEvent*event);
voidkeyPressEvent(QKeyEvent*event);
voidtimerEvent(QTimerEvent*event);
private:
enum{BoardWidth=10,BoardHeight=22};
//把主游戏区宽分成10等份,高分成22等份,也就是说每行有10小矩形,总共有22行
TetrixShape&shapeAt(intx,inty){returnboard[(y*BoardWidth)+x];}
inttimeoutTime(){return1000/(1+level);}
//contentsRect():
返回当前布局(QLayout)的矩形,可访问其长、宽(详见API)
//conntentsRect().width()/BoardWidth把游戏区矩形的宽分成了BoardWidth份
intsquareWidth(){returncontentsRect().width()/BoardWidth;}
//同上,把高分成了BoardHeight份
intsquareHeight(){returncontentsRect().height()/BoardHeight;}
//此时squareWidth(),squareHeight()分别是分割后的小矩形宽和高
voidclearBoard();//清屏
voiddropDown();//下落事件
voidoneLineDown();//下落一行
voidpieceDropped(intdropHeight);
voidremoveFullLines();//移除填满的行
voidnewPiece();//新方块
voidshowNextPiece();//显示下一个方块
booltryMove(constTetrixPiece&newPiece,intnewX,intnewY);//判断方块是否可以移动
voiddrawSquare(QPainter&painter,intx,inty,TetrixShapeshape);//着色
QBasicTimertimer;
//相当于QLabel*nextPieceLabel(QPointer详见API)
QPointernextPieceLabel;
boolisStarted;
boolisPaused;
boolisWaitingAfterLine;
TetrixPiececurPiece;//当前方块
TetrixPiecenextPiece;//下一个方块
intcurX;
intcurY;
intnumLinesRemoved;
intnumPiecesDropped;
intscore;
intlevel;
TetrixShapeboard[BoardWidth*BoardHeight];
};
#endif//TETRIXBOARD_H
Tetrixboard.cpp程序代码:
#include
#include"tetrixboard.h"
TetrixBoard:
:
TetrixBoard(QWidget*parent)
:
QFrame(parent)
{
//设置游戏区框架风格:
内浮雕
setFrameStyle(QFrame:
:
Panel|QFrame:
:
Sunken);
//增加游戏区键盘鼠标等事件的焦点集中
setFocusPolicy(Qt:
:
StrongFocus);
isStarted=false;//初始化:
未开始状态
isPaused=false;
clearBoard();//初始清屏
nextPiece.setRandomShape();//下一方块获得一个随机形状
}
//tetrixpiece.h:
tetrixpiece.cpp中使用
voidTetrixBoard:
:
setNextPieceLabel(QLabel*label)
{
nextPieceLabel=label;
}
//游戏区合适大小
QSizeTetrixBoard:
:
sizeHint()const
{
returnQSize(BoardWidth*15+frameWidth()*2,
BoardHeight*15+frameWidth()*2);
}
//游戏区最小大小
QSizeTetrixBoard:
:
minimumSizeHint()const
{
returnQSize(BoardWidth*5+frameWidth()*2,
BoardHeight*5+frameWidth()*2);
}
//开始事件:
slots
voidTetrixBoard:
:
start()
{
//如果已暂停,则启动无效
if(isPaused)
return;
isStarted=true;//标记已开始
isWaitingAfterLine=false;
//此参数为判断是否有方块正在下落,false为有方块正在下落中
//初始各参数
numLinesRemoved=0;
numPiecesDropped=0;
score=0;
level=1;
clearBoard();//清屏
//emit信号发射:
触发对应信号槽内的函数(相关connect()在tetrixwindow.cpp中)
emitlinesRemovedChanged(numLinesRemoved);
emitscoreChanged(score);
emitlevelChanged(level);
newPiece();//调用新方块
timer.start(timeoutTime(),this);//游戏开始计时
}
//暂停事件:
slots
voidTetrixBoard:
:
pause()
{
//如果未开始,则暂停无效
if(!
isStarted)
return;
//否则,若未暂停,则赋值为暂停,反之,取消暂停,继续游戏
isPaused=!
isPaused;
if(isPaused){
timer.stop();//游戏计时停止
}else{
timer.start(timeoutTime(),this);//否则继续计时
}
update();//刷新窗口:
动态显示画面
}
//游戏区方块着色
//重定义绘图事件,当调用update()时进行重绘
voidTetrixBoard:
:
paintEvent(QPaintEvent*event)
{
QFrame:
:
paintEvent(event);
QPainterpainter(this);
QRectrect=contentsRect();//QRect定义了平面上的矩形(详见API),是主游戏区
//暂停的时候显示的信息
if(isPaused){
painter.drawText(rect,Qt:
:
AlignCenter,tr("游戏暂停"));
return;
}
//BoardHeight*squareHeight()相当于contentsRect().Height(),是小网格的高
//因为squareHeight(){returncontentsRect().Width()/BoardWidth();}
//见tetrixboard.h中的定义
intboardTop=rect.bottom()-BoardHeight*squareHeight();
for(inti=0;ifor(intj=0;j//TetrixShape&shapeAt(intx,inty){returnboard[(y*BoardWidth)+x];}
TetrixShapeshape=shapeAt(j,BoardHeight-i-1);
if(shape!
=NoShape)
//rect.left()返回游戏区矩形左边的x坐标,squareWidth()为小网格的宽度
drawSquare(painter,rect.left()+j*squareWidth(),
boardTop+i*squareHeight(),shape);
}
}
//绘图
if(curPiece.shape()!
=NoShape){
for(inti=0;i<4;++i){
intx=curX+curPiece.x(i);
inty=curY-curPiece.y(i);
drawSquare(painter,rect.left()+x*squareWidth(),
boardTop+(BoardHeight-y-1)*squareHeight(),
curPiece.shape());
}
}
}
//键盘事件
voidTetrixBoard:
:
keyPressEvent(QKeyEvent*event)
{
if(!
isStarted||isPaused||curPiece.shape()==NoShape){
QFrame:
:
keyPressEvent(event);
return;
}
switch(event->key()){
caseQt:
:
Key_Left:
tryMove(curPiece,curX-1,curY);//左移
break;
caseQt:
:
Key_Right:
tryMove(curPiece,curX+1,curY);//右移
break;
caseQt:
:
Key_Up:
tryMove(curPiece.rotatedLeft(),curX,curY);//方块左转
break;
caseQt:
:
Key_Down:
dropDown();//快速下落
break;
default:
QFrame:
:
keyPressEvent(event);
}
}
//计时时间
voidTetrixBoard:
:
timerEvent(QTimerEvent*event)
{
if(event->timerId()==timer.timerId()){
//如果还有方块已下落完毕
if(isWaitingAfterLine){
isWaitingAfterLine=false;//重标记为有方块正在下落
newPiece();//添加新方块
(timeoutTime(),this);
}else{
oneLineDown();//否则进行下落动作
}
}else{
QFrame:
:
timerEvent(event);
}
}
//清空游戏区所有绘图
voidTetrixBoard:
:
clearBoard()
{
for(inti=0;iboard[i]=NoShape;
}
//直接快速下落操作
voidTetrixBoard:
:
dropDown()
{
intdropHeight=0;
intnewY=curY;
//进行下落过程,并求得方块还能下落的最大高度
while(newY>0){
if(!
tryMove(curPiece,curX,newY-1))
break;
--newY;
++dropHeight;
}
//把下落高度传递给此函数
pieceDropped(dropHeight);
}
//正常下落操作
voidTetrixBoard:
:
oneLineDown()
{
if(!
tryMove(curPiece,curX,curY-1))//如果能移动,则下落一行
pieceDropped(0);//正常下落不几分
}
//进行方块下落后的行为,如绘图,加分等参数:
下落方块的高度
voidTetrixBoard:
:
pieceDropped(intdropHeight)
{
for(inti=0;i<4;++i){
intx=curX+curPiece.x(i);
inty=curY-curPiece.y(i);
shapeAt(x,y)=curPiece.shape();
}
++numPiecesDropped;
//等级划分,加快下落速度
if(numPiecesDropped%25==0){
++level;
timer.start(timeoutTime(),this);//加速,游戏时间加快
emitlevelChanged(level);
}
emitscoreChanged(score);
//判断是否已有满行
removeFullLines();
if(!
isWaitingAfterLine)
newPiece();
}
//移除整行
voidTetrixBoard:
:
removeFullLines()
{
intnumFullLines=0;
//循环判断有几行已满
for(inti=BoardHeight-1;i>=0;--i){
boollineIsFull=true;
//判断是否已满一行
for(intj=0;jif(shapeAt(j,i)==NoShape){
lineIsFull=false;
break;
}
}
//上面所有行下移
if(lineIsFull){
++numFullLines;
for(intk=i;kfor(intj=0;jshapeAt(j,k)=shapeAt(j,k+1);
}
//整行清零
for(intj=0;j{
shapeAt(j,BoardHeight-1)=NoShape;
score+=numFullLines-1;
}
}
}
//如果已满行数大于0,则进行加分等操作,并更新窗口
if(numFullLines>0){
numLinesRemoved+=numFullLines;
score+=10*numFullLines;
//同时发送信号至相应的槽
emitlinesRemovedChanged(numLinesRemoved);
emitscoreChanged(score);
(500,this);
isWaitingAfterLine=true;
curPiece.setShape(NoShape);
update();
}
}
//新方块
voidTetrixBoard:
:
newPiece()
{
curPiece=nextPiece;
//预先随机设置好一下块方块
nextPiece.setRandomShape();
showNextPiece();
//设置其初始下落的位置,在游戏区顶部中央
curX=BoardWidth/2+1;
curY=BoardHeight-1+curPiece.minY();
//判断其是否还能移动,如果不能,则停止游戏
if(!
tryMove(curPiece,curX,curY)){
curPiece.setShape(NoShape);
//painter.drawText(rect,tr("游戏结束"));
timer.stop();
isStarted=false;
}
}
//展示下一个方块
voidTetrixBoard:
:
showNextPiece()
{
if(!
nextPieceLabel)
return;
intdx=nextPiece.maxX()-nextPiece.minX()+1;
intdy=nextPiece.maxY()-nextPiece.minY()+1;
QPixmappixmap(dx*squareWidth(),dy*squareHeight());//映射要显示方块像素
QPainterpainter(&pixmap);//开始绘制该方块
painter.fillRect(pixmap.rect(),nextPieceLabel->palette().background());
//先绘制要显示方块的背景色
//再开始绘制方块本身
for(inti=0;i<4;++i){
intx=nextPiece.x(i)-nextPiece.minX();
inty=nextPiece.y(i)-nextPiece.minY();
drawSquare(painter,x*squareWidth(),y*squareHeight(),
nextPiece.shape());
}
nextPieceLabel->setPixmap(pixmap);//最后加载它
}
//判断是否还能移动
boolTetrixBoard:
:
tryMove(constTetrixPiece&newPiece,intnewX,intnewY)
{
for(inti=0;i<4;++i){
intx=newX+newPiece.x(i);
inty=newY-newPiece.y(i);
if(x<0||x>=BoardWidth||y<0||y>=BoardHeight)
returnfalse;
if(shapeAt(x,y)!
=NoShape)//判断当前位置是否有其他方块
returnfalse;
}
curPiece=newPiece;
curX=newX;
curY=newY;
update();
returntrue;
}
//intsquareWidth(){returncontentsRect().width()/BoardWidth;}
//intsquareHeight(){returncontentsRect().height()/BoardHeight;}
voidTetrixBoard:
:
drawSquare(QPainter&painter,intx,inty,TetrixShapeshape)
{
//google色彩
staticconstQRgbcolorTable[8]={
0x000000,0x1851ce,0xc61800,0xefb