Qt怎么实现方块游戏


这篇“Qt怎么实现方块游戏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Qt怎么实现方块游戏”文章吧。

1.方块游戏架构

在这个游戏中,有一个区域用来摆放方块,该区域宽为10,高为20,以小正方形为单位,它可以看作是拥有20行10列的一个网格。标准的游戏中一共有7种方块,它们都是由4个小正方形组成的规则图形,依据形状分别用字母I、J、L、O、S、T和Z来命名。

这里使用图形视图框架来实现整个游戏的设计。小正方形由OneBox来表示,它继承自QGraphicsObject类,之所以继承自这个类,是因为这样就可以使用信号和槽机制,话可以使用属性动画。小正方形就是一个宽和高都为20像素的正方形图形项。游戏中的方块游戏由方块组BoxGroup类来实现,继承自QObject和QGraphicsItemGroup类,这样该类也可以使用信号和槽机制。方块组是一个宽和高都是80像素的图形项组,其中包含了4个小方块,通过设置小方块的位置来实现7种标准的方块图形。它们的形状和位置如下图,在BoxGroup类中实现了方块图形的创建、移动和碰撞检测。

方块移动区域在游戏场景中使用四条直线图形项所围成区域来表示,之所以要这样实现,是因为这样可以通过方块组是否与直线图形项碰撞来检测是否移动出界。整个游戏界面由MyView类来实现,该类继承自QGraphicsView类,实现了场景设置、游戏逻辑设计和游戏声音设置及其他控制功能。

整个游戏场景宽800像素,高500像素。方块移动区域宽200像素,高400像素,纵向每20个像素被视作一行,共有20行;横行也是每20个像素视作一列,所以共有10列,该区域可以看作一个由20行10列20×20像素的方格组成的网格。方块组在方块移动区域的初始位置为上方正中间,但方块组的最上方一行小正方形在方块移动区域以外,这样可以保证方块组完全出现在移动区域的最上方,方块组每移动一次,就是移动一个方格的位置。场景还设置了下一个要出现方块的提示方块、游戏暂停等控制按钮和游戏分数级别的显示文本,整个场景的示意图如下图所示:

2.游戏逻辑

当游戏开始后,首先创建一个新的方块组,并将其添加到场景中的方块移动区域上方。然后进行碰撞检测,如果这时已经发生了碰撞,那么游戏结束;如果没有发生碰撞,就可以使用键盘的方向键对其进行旋转变形或者左右移动。当到达指定事件时方块组会自动下移一个方格,这时再次判断是否发生碰撞,如果发生了碰撞,先消除满行的方格,然后出现新的方块组,并继续进行整个流程。其中方程块的移动、旋转、碰撞检测等都在BoxGroup类中进行;游戏的开始、结束、出现新的方程组、消除满行等都在MyView类中进行。游戏程序图以及方块组移动和旋转流程图如下:

2.1、方块组的移动和旋转

方块组的左移、右移、下移和旋转都是先进行该操作,然后判断是否发生碰撞,比如发生了碰撞就再进行反向操作。比如,使用方向键左移方块组,那么就先将方块组左移一格,然后进行碰撞检测,看是否与边界线或者其他方块碰撞了,如果发生了碰撞,那么就再移过来,即右移一个。方块组的移动和旋转流程如下:

2.2、碰撞检测

对于方块组的碰撞检测,其实是使用方块组中的4个小方块来进行的,这样就不用再为每个方块图形都设置一个碰撞检测时使用的形状。要进行碰撞检测时,对每一个小方块都使用函数来获取与它们碰撞的图形项的数目,因为现在小方块在方块组中,所以应该只有方块组与它们碰撞了(由于我们对小方块的形状进行了设置,所以挨着的四个小方块相互间不会被检测出发生了碰撞),也就是说与它们碰撞的图形项数目应该不会大于1,如果有哪个小方块发现与它碰撞的图形项的数目大于1,那么说明已经发生了碰撞。

2.3、游戏结束

当一个新的方块组出现时,就立即对齐进行碰撞检测,如果它一出现就与其他方块发生了碰撞,说明游戏已经结束了,这时由方块组发射游戏结束信号。

2.4、消除满行

游戏开始后,每当出现一个新的方块以前,都判断游戏移动区域的每一行是否已经拥有10个小方块。如果有一行已经拥有了10个小方块,说明改行已满,那么就销毁该行的所有小方块,然后让该行上面的所有小方块都下移一格。

3.效果图

4.具体实现

box.h

#ifndefBOX_H#defineBOX_H#include<QGraphicsObject>#include<QGraphicsItemGroup>classOneBox:publicQGraphicsObject{public:OneBox(constQColor&color=Qt::red);QRectFboundingRect()const;voidpaint(QPainter*painter,constQStyleOptionGraphicsItem*option,QWidget*widget);QPainterPathshape()const;private:QColorbrushColor;};classBoxGroup:publicQObject,publicQGraphicsItemGroup{Q_OBJECTpublic:enumBoxShape{IShape,JShape,LShape,OShape,SShape,TShape,ZShape,RandomShape};//8中俄罗斯方框形状BoxGroup();QRectFboundingRect()const;//在函数后用const表示不能改变类的成员voidclear_box_group(booldestroy_box=false);voidcreate_box(constQPointF&point,BoxShapeshape=RandomShape);//在函数的申明处可以将参数设定为默认值,定义处不需要boolisColliding();BoxShapegetCurrentShape(){returncurrent_shape;}//获得当前俄罗斯方块的形状protected:voidkeyPressEvent(QKeyEvent*event);signals:voidneed_new_box();voidgame_finished();publicslots:voidmove_one_step();voidstartTimer(intinterval);voidstop_timer();private:BoxShapecurrent_shape;QTransformold_transform;QTimer*timer;};#endif//BOX_H

box.cpp

#include"box.h"#include<QPainter>#include<QTimer>#include<QKeyEvent>//OneBox是从QGraphicsObject继承而来的OneBox::OneBox(constQColor&color):brushColor(color){}//该函数为指定后面的绘图区域的外边框QRectFOneBox::boundingRect()const{qrealpen_width=1;//小方块的边长为20.5像素returnQRectF(-10-pen_width/2,-10-pen_width/2,20+pen_width,20+pen_width);}voidOneBox::paint(QPainter*painter,constQStyleOptionGraphicsItem*option,QWidget*widget){//贴图,看起来有质感,否则单独用颜色去看,会感觉那些方块颜色很单一painter->drawPixmap(-10,-10,20,20,QPixmap(":/images/box.gif"));painter->setBrush(brushColor);//设置画刷颜色QColorpenColor=brushColor;penColor.setAlpha(20);//将颜色的透明度减小,使方框边界和填充色直接能区分开painter->setPen(penColor);//色绘制画笔//这里画矩形框,框内填充部分用画刷画,框外线条用画笔画painter->drawRect(-10,-10,20,20);//画矩形框}//在局部坐标点上返回item的shape,但是好像没有其它地方调用了该函数QPainterPathOneBox::shape()const{//QPainterPath是一个绘图操作的容器QPainterPathpath;path.addRect(-9.5,-9.5,19,19);returnpath;}//BoxGroup是从QGraphicsItemGroup,QObject继承而来的BoxGroup::BoxGroup(){setFlags(QGraphicsItem::ItemIsFocusable);//允许设置输入焦点old_transform=transform();//返回当前item的变换矩阵,当BoxGroup进行旋转后,可以使用它来进行恢复timer=newQTimer(this);connect(timer,SIGNAL(timeout()),this,SLOT(move_one_step()));current_shape=RandomShape;}QRectFBoxGroup::boundingRect()const{qrealpen_width=1;returnQRectF(-40-pen_width/2,-40-pen_width/2,80+pen_width,80+pen_width);//2*2个小方块组成一个小方块组}voidBoxGroup::keyPressEvent(QKeyEvent*event){staticqrealangle=0;switch(event->key()){//向下键位坠落键caseQt::Key_Down:{moveBy(0,20);//moveBy是系统自带的函数,不需要我们自己去实现while(!isColliding()){moveBy(0,20);}moveBy(0,-20);//往回跳clear_box_group();//到达底部后就将当前方块组的4个item移除,不销毁方块组emitneed_new_box();//发射信号,在MyView中接收break;}caseQt::Key_Left:{moveBy(-20,0);if(isColliding()){moveBy(20,0);}break;}caseQt::Key_Right:{moveBy(20,0);if(isColliding()){moveBy(-20,0);}break;}//实现小方块组变形caseQt::Key_Up:{setRotation(angle+90.0);angle=angle+90.0;//rotation();if(isColliding()){setRotation(angle-90);angle=angle-90.0;//rotation();}break;}}}//检测是否有碰撞boolBoxGroup::isColliding(){QList<QGraphicsItem*>item_list=childItems();//返回子item列表QGraphicsItem*item;foreach(item,item_list){if(item->collidingItems().count()>1)//collidingItems返回与当前item碰撞的子item列表returntrue;//代表至少有一个item发生了碰撞}returnfalse;}//将方块组从视图中移除掉,如果有需要(即参数为true的情况下)则销毁掉//其本质是将所有的小方块从方块组中移除掉,达到从视图中将方块组移除的目的voidBoxGroup::clear_box_group(booldestroy_box){QList<QGraphicsItem*>item_list=childItems();QGraphicsItem*item;foreach(item,item_list){removeFromGroup(item);//将item从方块组中移除掉if(destroy_box){OneBox*box=(OneBox*)item;box->deleteLater();//当控制返回到事件循环时,该目标被删除,即销毁}}}//创建俄罗斯方块组,根据形状参数选择方块组的颜色和形状voidBoxGroup::create_box(constQPointF&point,BoxShapeshape){staticconstQColorcolor_table[7]={QColor(200,0,0,100),QColor(255,200,0,100),QColor(0,0,200,100),QColor(0,200,0,100),QColor(0,200,255,100),QColor(200,0,255,100),QColor(150,100,100,100)};intshape_id=shape;//Box_Shape是枚举型,其实也是整型,因为它相当于整型的宏定义if(shape==RandomShape){shape_id=qrand()%7;//随机取一个颜色}QColorcolor=color_table[shape_id];//根据id选颜色QList<OneBox*>list;setTransform(old_transform);//恢复方块组前的变换矩阵for(inti=0;i<4;++i){//4个小方块组成一个方块组OneBox*temp=newOneBox(color);list<<temp;//将小方块加入list列表addToGroup(temp);}switch(shape_id){caseIShape:current_shape=IShape;//横着的一杆list.at(0)->setPos(-30,-10);list.at(1)->setPos(-10,-10);list.at(2)->setPos(10,-10);list.at(3)->setPos(30,-10);break;caseJShape:current_shape=JShape;//J型list.at(0)->setPos(10,-10);list.at(1)->setPos(10,10);list.at(2)->setPos(10,30);list.at(3)->setPos(-10,30);break;caseLShape:current_shape=LShape;//L型的方块组list.at(0)->setPos(-10,-10);list.at(1)->setPos(-10,10);list.at(2)->setPos(-10,30);list.at(3)->setPos(10,30);break;caseOShape://田字型current_shape=OShape;list.at(0)->setPos(-10,-10);list.at(1)->setPos(10,-10);list.at(2)->setPos(-10,10);list.at(3)->setPos(10,10);break;caseSShape://S型current_shape=SShape;list.at(0)->setPos(10,-10);list.at(1)->setPos(30,-10);list.at(2)->setPos(-10,10);list.at(3)->setPos(10,10);break;caseTShape://土子型current_shape=TShape;list.at(0)->setPos(-10,-10);list.at(1)->setPos(10,-10);list.at(2)->setPos(30,-10);list.at(3)->setPos(10,10);break;caseZShape://Z字型current_shape=ZShape;list.at(0)->setPos(-10,-10);list.at(1)->setPos(10,-10);list.at(2)->setPos(10,10);list.at(3)->setPos(30,10);break;default:break;}setPos(point);//将准备好的俄罗斯方块放入指定的位置,然后进行碰撞检测if(isColliding()){//如果俄罗斯方块一出现后就发生了碰撞,因为它是从中间出来的,所以一开始不可能是与左右两边发生碰撞,//只能是与下面碰撞,因此如果发生了碰撞,说明游戏已经结束,就可以发送游戏结束信号了,且定时器停止。stop_timer();emitgame_finished();}}//这个是系统里的函数,本程序中是在主函数中启动的//其实是该子类中的timeEvent()函数调用的voidBoxGroup::startTimer(intinterval){timer->start(interval);//启动定时器并且设置定时器间隔,然后在BoxGroup()的构造函数中设置了该定时器的信号与槽函数}//每当定时器到时间了,小方块组就向下移一步voidBoxGroup::move_one_step(){moveBy(0,20);//该函数是父类的函数,这里指向下移动一个单位,因为向下为正坐标if(isColliding()){//发生碰撞的情况下moveBy(0,-20);clear_box_group();//将方块组移除视图emitneed_new_box();//发生信号通知程序需要新的方块组出现}}voidBoxGroup::stop_timer(){timer->stop();//定时器停止}

myview.h

#ifndefMYVIEW_H#defineMYVIEW_H#include<QGraphicsView>classBoxGroup;classMyView:publicQGraphicsView{Q_OBJECTpublic:explicitMyView(QWidget*parent=0);//关键字explicit是为了防止隐式类型转换publicslots:voidstart_game();voidclear_full_rows();voidmove_box();voidgame_over();voidrestartGame();voidfinishGame();voidpauseGame();voidreturnGame();protected:private://遮罩面板QGraphicsWidget*maskWidget;//各种按钮QGraphicsWidget*mask_widget;//首页和游戏中需要用到的各种按钮QGraphicsWidget*start_button;QGraphicsWidget*finish_button;QGraphicsWidget*restart_button;QGraphicsWidget*pause_button;QGraphicsWidget*option_button;QGraphicsWidget*return_button;QGraphicsWidget*help_button;QGraphicsWidget*exit_button;QGraphicsWidget*show_menu_button;//显示人机交互的文本信息QGraphicsTextItem*game_wee_text;QGraphicsTextItem*game_pause_text;QGraphicsTextItem*game_over_text;QGraphicsTextItem*gameScoreText;QGraphicsTextItem*gameLevelText;QGraphicsLineItem*top_line;QGraphicsLineItem*bottom_line;QGraphicsLineItem*left_line;QGraphicsLineItem*right_line;BoxGroup*box_group;BoxGroup*next_box_group;qrealgame_speed;QList<int>rows;voidinit_view();voidinit_game();voidupdate_score(constintfull_row_num=0);};#endif//MYVIEW_H

myview.cpp

#include"myview.h"#include"box.h"#include<QIcon>#include<QPropertyAnimation>#include<QGraphicsBlurEffect>#include<QTimer>#include<QPushButton>#include<QGraphicsProxyWidget>#include<QApplication>#include<QLabel>#include<QFileInfo>staticconstqrealINITSSPEED=500;//游戏的初始化速度MyView::MyView(QWidget*parent){init_view();}voidMyView::start_game(){game_wee_text->hide();start_button->hide();option_button->hide();help_button->hide();exit_button->hide();mask_widget->hide();init_game();}voidMyView::clear_full_rows(){for(inty=429;y>50;y-=20){//每隔20行取一个item出来,括号里面的参数不能弄错,否则没有方块消失的效果QList<QGraphicsItem*>list=scene()->items(199,y,202,22,Qt::ContainsItemShape,Qt::DescendingOrder);//返回指定区域内所有可见的itemif(list.count()==10){//如果一行已满,则销毁该行的所有小方块foreach(QGraphicsItem*item,list){OneBox*box=(OneBox*)item;//box->deleteLater();//先为小方块使用了模糊图形效果,然后为其添加了放大再缩小的属性动画,等动画指定结束后才调用deleteLater()槽QGraphicsBlurEffect*blurEffect=newQGraphicsBlurEffect;box->setGraphicsEffect(blurEffect);QPropertyAnimation*animation=newQPropertyAnimation(box,"scale");animation->setEasingCurve(QEasingCurve::OutBounce);animation->setDuration(250);animation->setStartValue(4);animation->setEndValue(0.25);animation->start(QAbstractAnimation::DeleteWhenStopped);//connect(animation,SIGNAL(finished()),box,SLOT(deleteLater()));connect(animation,&QPropertyAnimation::finished,box,&OneBox::deleteLater);}rows<<y;//将满行的行号保存到rows中}}//如果满行,则下移上面的方块if(rows.count()>0){//move_box();QTimer::singleShot(400,this,SLOT(move_box()));}else{//没有满行,则新出现提示方块,且提示方块出更新新的提示方块box_group->create_box(QPointF(300,70),next_box_group->getCurrentShape());next_box_group->clear_box_group(true);next_box_group->create_box(QPointF(500,70));//}}voidMyView::move_box(){for(inti=rows.count();i>0;--i){introw=rows.at(i-1);//取出满行的行号,从最上面的位置开始//取出从区域上边界到当前满行之间所形成的矩形区域foreach(QGraphicsItem*item,scene()->items(199,49,202,row-47,Qt::ContainsItemShape,Qt::DescendingOrder)){item->moveBy(0,20);}}//更新分数update_score(rows.count());//出现新的方块组rows.clear();box_group->create_box(QPointF(300,70),next_box_group->getCurrentShape());next_box_group->clear_box_group(true);next_box_group->create_box(QPoint(500,70));}voidMyView::game_over(){//游戏结束pause_button->hide();show_menu_button->hide();mask_widget->show();game_over_text->show();restart_button->setPos(370,200);finish_button->show();}voidMyView::restartGame(){mask_widget->hide();game_over_text->hide();finish_button->hide();restart_button->setPos(600,150);//销毁当前方块组和当前方块中的所有小方块next_box_group->clear_box_group(true);box_group->clear_box_group();box_group->hide();foreach(QGraphicsItem*item,scene()->items(199,49,202,402,Qt::ContainsItemBoundingRect,Qt::DescendingOrder)){scene()->removeItem(item);OneBox*box=(OneBox*)item;box->deleteLater();}init_game();}voidMyView::finishGame(){game_over_text->hide();finish_button->hide();restart_button->setPos(600,150);restart_button->hide();pause_button->hide();show_menu_button->hide();gameScoreText->hide();gameLevelText->hide();top_line->hide();bottom_line->hide();left_line->hide();right_line->hide();next_box_group->clear_box_group(true);box_group->clear_box_group();box_group->hide();foreach(QGraphicsItem*item,scene()->items(199,49,202,402,Qt::ContainsItemBoundingRect,Qt::DescendingOrder)){scene()->removeItem(item);OneBox*box=(OneBox*)item;box->deleteLater();}mask_widget->show();game_wee_text->show();start_button->show();option_button->show();help_button->show();exit_button->show();scene()->setBackgroundBrush(QPixmap(":/images/background.png"));}voidMyView::pauseGame(){box_group->stop_timer();//中断游戏最主要的是停止方块下移的定时器工作restart_button->hide();pause_button->hide();show_menu_button->hide();mask_widget->show();game_pause_text->show();return_button->show();}voidMyView::returnGame(){return_button->hide();game_pause_text->hide();mask_widget->hide();restart_button->show();pause_button->show();show_menu_button->show();box_group->startTimer(game_speed);}voidMyView::init_view(){setRenderHint(QPainter::Antialiasing);//使用抗锯齿的方式渲染setCacheMode(CacheBackground);//设置缓存背景,这样可以加快渲染速度setWindowTitle(tr("Teris游戏"));setWindowIcon(QIcon(":/images/icon.png"));//设置标题处的图标setMinimumSize(810,510);//2者设置成一样说明视图尺寸不能再更改setMaximumSize(810,510);QGraphicsScene*scene=newQGraphicsScene;//新建场景指针scene->setSceneRect(5,5,800,500);//场景大小scene->setBackgroundBrush(QPixmap(":/images/background.png"));setScene(scene);//设置场景//俄罗斯方块可移动区域外界的4条线,与外界预留3个像素是为了方便进行碰撞检测top_line=scene->addLine(197,27,403,27);bottom_line=scene->addLine(197,453,403,453);left_line=scene->addLine(197,27,197,453);right_line=scene->addLine(403,27,403,453);//添加当前方块组box_group=newBoxGroup;//通过新建BoxGroup对象间接达到调用box的2个类connect(box_group,SIGNAL(need_new_box()),this,SLOT(clear_full_rows()));connect(box_group,SIGNAL(game_finished()),this,SLOT(game_over()));scene->addItem(box_group);//添加提示方块组next_box_group=newBoxGroup;scene->addItem(next_box_group);gameScoreText=newQGraphicsTextItem();//文本的父item为对应的场景gameScoreText->setFont(QFont("Times",50,QFont::Bold));//为文本设置字体gameScoreText->setPos(450,350);//分数在场景中出现的位置gameLevelText=newQGraphicsTextItem();gameLevelText->setFont(QFont("Times",50,QFont::Bold));gameLevelText->setPos(20,150);scene->addItem(gameLevelText);scene->addItem(gameScoreText);//开始游戏//start_game();//设置初始为隐藏状态top_line->hide();bottom_line->hide();left_line->hide();right_line->hide();gameScoreText->hide();gameLevelText->hide();//黑色遮罩QWidget*mask=newQWidget;mask->setAutoFillBackground(true);mask->setPalette(QPalette(QColor(0,0,0,50)));//alpha为不透明度mask->resize(900,600);//addWidget()函数的返回值是QGraphicsProxyWidget,如果不添加相应的头文件,则此处会报错mask_widget=scene->addWidget(mask);mask_widget->setPos(-50,-50);mask_widget->setZValue(1);//该层薄纱放在原图的上面,这里有点类似于opengl中的3维绘图//选项面板QWidget*option=newQWidget;//将关闭按钮放在option上QPushButton*option_close_button=newQPushButton(tr("关闭"),option);//第2个参数为按钮所在的widget//设置按钮的字体颜色是白色QPalettepalette;palette.setColor(QPalette::ButtonText,Qt::black);//第一个参数调色版的role,这里指的是按钮字体颜色option_close_button->setPalette(palette);//设置关闭按钮的位置,和单击后的响应option_close_button->move(120,300);connect(option_close_button,SIGNAL(clicked()),option,SLOT(hide()));//单击后消失option->setAutoFillBackground(true);option->setPalette(QPalette(QColor(0,0,0,180)));option->resize(300,400);QGraphicsWidget*option_widget=scene->addWidget(option);option_widget->setPos(250,50);option_widget->setZValue(3);option_widget->hide();//帮助面板QWidget*help=newQWidget;QPushButton*help_close_button=newQPushButton(tr("帮助"),help);help_close_button->setPalette(palette);help_close_button->move(120,300);connect(help_close_button,SIGNAL(clicked()),help,SLOT(hide()));help->setAutoFillBackground(true);help->setPalette(QPalette(QColor(0,0,0,180)));help->resize(300,400);QGraphicsWidget*help_widget=scene->addWidget(help);help_widget->setPos(250,50);help_widget->setZValue(3);help_widget->hide();//游戏欢迎文本game_wee_text=newQGraphicsTextItem();//第一个参数为文本内容,第二个参数为父itemgame_wee_text->setHtml(tr("<fontcolor=green>Tetris游戏</font>"));game_wee_text->setFont(QFont("Times",40,QFont::Bold));game_wee_text->setPos(300,100);game_wee_text->setZValue(2);//放在第2层//游戏暂停文本game_pause_text=newQGraphicsTextItem();//第一个参数为文本内容,第二个参数为父itemgame_pause_text->setHtml(tr("<fontcolor=green>游戏暂停中!</font>"));game_pause_text->setFont(QFont("Times",40,QFont::Bold));game_pause_text->setPos(300,100);game_pause_text->setZValue(2);//放在第2层game_pause_text->hide();//游戏结束文本game_over_text=newQGraphicsTextItem();//第一个参数为文本内容,第二个参数为父itemgame_over_text->setHtml(tr("<fontcolor=green>GAME OVER!</font>"));game_over_text->setFont(QFont("Times",40,QFont::Bold));game_over_text->setPos(300,100);game_over_text->setZValue(2);//放在第2层game_over_text->hide();scene->addItem(game_wee_text);scene->addItem(game_pause_text);scene->addItem(game_over_text);//游戏中使用的按钮QPushButton*button1=newQPushButton(tr("开始"));QPushButton*button2=newQPushButton(tr("选项"));QPushButton*button3=newQPushButton(tr("帮助"));QPushButton*button4=newQPushButton(tr("退出"));QPushButton*button5=newQPushButton(tr("重新开始"));QPushButton*button6=newQPushButton(tr("暂停"));QPushButton*button7=newQPushButton(tr("主菜单"));QPushButton*button8=newQPushButton(tr("返回游戏"));QPushButton*button9=newQPushButton(tr("结束游戏"));connect(button1,SIGNAL(clicked()),this,SLOT(start_game()));connect(button2,SIGNAL(clicked()),option,SLOT(show()));connect(button3,SIGNAL(clicked()),help,SLOT(show()));connect(button4,SIGNAL(clicked()),qApp,SLOT(quit()));//此处槽函数的接收对象为应用程序本身connect(button5,SIGNAL(clicked()),this,SLOT(restartGame()));connect(button6,SIGNAL(clicked()),this,SLOT(pauseGame()));connect(button7,SIGNAL(clicked()),this,SLOT(show_menu_button()));connect(button8,SIGNAL(clicked()),this,SLOT(returnGame()));//返回主菜单connect(button9,SIGNAL(clicked()),this,SLOT(finishGame()));start_button=scene->addWidget(button1);//restart_button并不是QPushbutton类型,而是QGraphicsItem类型,后面的类似option_button=scene->addWidget(button2);help_button=scene->addWidget(button3);exit_button=scene->addWidget(button4);restart_button=scene->addWidget(button5);pause_button=scene->addWidget(button6);show_menu_button=scene->addWidget(button7);return_button=scene->addWidget(button8);finish_button=scene->addWidget(button9);//设置位置start_button->setPos(370,200);option_button->setPos(370,250);help_button->setPos(370,300);exit_button->setPos(370,350);restart_button->setPos(600,150);pause_button->setPos(600,200);show_menu_button->setPos(600,250);return_button->setPos(370,200);finish_button->setPos(370,250);//将这些按钮都放在z方向的第二层start_button->setZValue(2);option_button->setZValue(2);help_button->setZValue(2);exit_button->setZValue(2);restart_button->setZValue(2);return_button->setZValue(2);finish_button->setZValue(2);//一部分按钮隐藏起来restart_button->hide();finish_button->hide();pause_button->hide();show_menu_button->hide();return_button->hide();}voidMyView::init_game(){box_group->create_box(QPointF(300,70));//创建方块组,在中间位置处出现box_group->setFocus();//设置人机交互焦点,这样就可以使用键盘来控制它box_group->startTimer(INITSSPEED);//启动定时器game_speed=INITSSPEED;//游戏速度,暂停时需要用到next_box_group->create_box(QPoint(500,70));//创建提示方块组scene()->setBackgroundBrush(QPixmap(":/images/background01.png"));gameScoreText->setHtml(tr("<fontcolor=red>00</font>"));gameLevelText->setHtml(tr("<fontcolor=white>第<br>一<br>幕</font>"));restart_button->show();pause_button->show();show_menu_button->show();gameScoreText->show();gameLevelText->show();top_line->show();bottom_line->show();left_line->show();right_line->show();//可能以前返回主菜单时隐藏了boxGroupbox_group->show();}voidMyView::update_score(constintfull_row_num){//更新分数intscore=full_row_num*100;intcurrentScore=gameScoreText->toPlainText().toInt();currentScore+=score;//显示当前分数gameScoreText->setHtml(tr("<fontcolor=red>%1</font>").arg(currentScore));//判断级别if(currentScore<500){//第一级,什么都不用做}elseif(currentScore<1000){//第二级gameLevelText->setHtml(tr("<fontcolor=white>第<br>二<br>幕</font>"));scene()->setBackgroundBrush(QPixmap(":/images/background02.png"));game_speed=300;box_group->stop_timer();box_group->startTimer(game_speed);}else{//添加下一个级别的设置}}

main.cpp

#include<QApplication>#include"myview.h"#include<QTextCodec>#include<QTime>intmain(intargc,char*argv[]){QApplicationapp(argc,argv);QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());//QTime提供了闹钟功能qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//secsTo()为返回当前的秒数MyViewview;//主函数是直接调用的视图类view.show();returnapp.exec();}

以上就是关于“Qt怎么实现方块游戏”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注主机评测网行业资讯频道。


上一篇:GoLang?bytes.Buffer怎么使用

下一篇:GoLang?OS包及File类型源码分析


Copyright © 2002-2019 测速网 www.inhv.cn 皖ICP备2023010105号
测速城市 测速地区 测速街道 网速测试城市 网速测试地区 网速测试街道
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!

热门搜索 城市网站建设 地区网站制作 街道网页设计 大写数字 热点城市 热点地区 热点街道 热点时间 房贷计算器