博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt浅谈之四十九俄罗斯方块(代码来自网络)
阅读量:4180 次
发布时间:2019-05-26

本文共 39569 字,大约阅读时间需要 131 分钟。

一、简介

      从网上下载了一个Qt实现的俄罗斯方块单机版的源码,觉得非常有意思,故以博客形式记录下来,以便慢慢来研究。在centos6.6下编译运行(注意程序运行需要读取pro目录的配置文件,若把编译目录选择在pro外的话运行会报错):

 

二、详解

1、部分代码

 

(1)main.cpp

#include 
#include
#include
#include "TetrixWidget.h"int main( int argc, char **argv ){ QApplication a( argc, argv ); QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); //则更换图标 QCursor myCursor( QPixmap( GLOBAL_CURSOR_IMAGE ) ) ; QApplication::setOverrideCursor( myCursor ) ; //这个是因为要使用Phonon这里要设置一个名字,可能是考虑到版权相关的问题吧,不然会有一个警告 //并无其他实际意义 a.setApplicationName("MyTetrix Game"); TetrixWidget widget ; widget.show(); return a.exec();}

(2)TetrixWidget.h

#ifndef TETRIXWIDGET_H#define TETRIXWIDGET_H#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include "GameGraphicsScene.h"#include "GameBackGroundItem.h"#include "GameLogoImageItem.h"#include "GameButtonItem.h"#include "GameArrowItem.h"#include "GameMovBackGrouItem.h"#include "GameIntroductionItem.h"#include "GameOptionItem.h"#include "GameHighWinItem.h"#include "GameGameSound.h"#include "globaldefines.h"/************************************************************************** * 常量 * **************************************************************************//************************************************************************** * 宏定义 * **************************************************************************//************************************************************************** * 数据类型 * **************************************************************************//************************************************************************** * 类声明 * **************************************************************************/class TetrixWidget : public QWidget{ Q_OBJECTsignals: //发送信号给ArrowItem,改变其坐标到坐标索引的index void moveArrowat( int index ) ; //这个是遮蔽箭头item上面的箭头的信号 //这个信号放在这个类里是因为,按钮弹出的Item会通过按Esc来返回,这样就不能再发信号还原 //其状态 void coverOnArowItemSignal( bool state ) ; /**********************这个是当游戏被停用时的发送的信号********************/ //这个是当游戏被停用时的发送的信号 //就是当鼠标点击电脑桌面其他位置时,就是我们平常所说的整个游戏软件失去焦点时。发送这个信号 void gameDeactivateSignal() ;public: TetrixWidget(QWidget *parent=0) ; ~TetrixWidget() ;private: QGraphicsView *gameView ; GameGraphicsScene *gameScene ; void setTetrixWigAttribute() ; //设置TetrixWidget类的属性 void initGameSceneAndView() ; //初始化游戏的场景与视图 QSettings *configIni ; //这个是用于读取配置文件指针 //这是定义的一个表,用来存储图片名字与图片的指针 //这个作为一个大的容器,所以图片都放在里面。便于之后用 NameAndImageHash nameImageHash ; //根据组名及每组对应的图片数目的A值来读取配置文件,并且加载图片文件。 void initAndLoadImage( QString groupname, QString A_valueString ) ; void loadAllImageFile() ; //加载所有的图片 //这个坐标ponit用于取图片上某个坐标点的色素作为透明色,默认为QPoint( 0,0 ) QImage *getTransImage( QImage *image , QPoint ponit = QPoint( 0,0 ) ) ; /* 这个是处理所有的粉红色背景的图片,使只编程透明色背景 */ void dealPinkBackGroundImage( QString groupname, QString A_valueString ) ; /* 这个是因为当第三层出现时,用户按下Esc键,要回到第二层游戏首页, 所以在这里用这个hash表来记录 */ NumAndPointerHash numPointer ; /* 这个是用来记录当前在第二层上面的Item,通过这个序号在NumAndPointerHash 中查找Item对应的指针,默认为-1 */ int nowIndex ; /* 这里是因为,这个设置的图片太小,要把下面的开始与退出按钮给隐藏掉, 不然用户移动鼠标会误点到 */ void setSomeItemVisible( bool visible ) ; //从配置文件中读出所要的音量的值 inline int getVolumeValueFromFile( QString groupname ,QString A_valueString ) ; //从配置文件中读取是否要设置全屏 inline bool getFullScreenValueFromFile( QString groupname ,QString A_valueString ) ; /****************************最底层的Item******************************/ GameLogoImageItem *logoImageItem ; void addGameLogoImageItem( ) ; //添加GameLogoImageItem到场景去 GameBackGroundItem *backGroundItem ; //这是定义的一个表,用来存储图片名字与图片的坐标 //部分图片的坐标不需要写在配置文件,因为其默认坐标一直都是(0,0) NameAndPointHash namePointHash ; //根据组名及每组对应的图片数目的A值来读取配置文件,并且记录到namePointHash中去。 void initNameAndPointHash( QString groupname ,QString A_valueString ) ; /****************************第二层的Item******************************/ GameButtonItem *dianwoButton ; //点我的广告按钮 GameButtonItem *moregameButton ; //更多的游戏按钮 GameButtonItem *startgameButton ; //开始游戏按钮 GameButtonItem *instrgameButton ; //游戏介绍按钮 GameButtonItem *gameoptionButton ; //游戏选项按钮 GameButtonItem *gamehihgscButton ; //游戏排行榜按钮 GameButtonItem *exitgameButton ; //退出游戏按钮 GameArrowItem *arrowItem ; //箭头Item /* 添加所有的第二层的Item,通过一个接口把所有的第二层的Item全部放进来,方便管理 */ void addAllSecondLayerItem() ; //分开进行添加这样不至于让一个函数变的很长 void addDianWoButton() ; //添加点我按钮 void addMoreGameButton() ; //添加更多的游戏按钮 void addStartGameButton() ; //添加开始游戏按钮 void addInstrGameButton() ; //添加游戏介绍按钮 void addGameOptionButton() ; //添加游戏选项按钮 void addGameHihgscButton() ; //添加游戏排行榜按钮 void addExitGameButton() ; //添加退出游戏按钮 void addArrowItem() ; //添加箭头Item /****************************第三层的Item******************************/ GameMovBackGrouItem *movBacGrouItem ; //动态背景图片 GameIntroductionItem *introduItem ; //游戏介绍Item GameOptionItem *optionItem ; //游戏选项Item GameHighWinItem *highWinItem ; //游戏排行榜Item /**************************游戏的背景音乐与音效的处理*************************/ GameGameSound *gameSound ; //游戏的背景音乐与音效 void initGameGameSound() ; //初始化游戏的背景音乐与音效private slots: void addGameBackGroundItem( ) ; //添加GameBackGroundItem到场景去 void mouseOnStartgameButton( ) ; //光标在开始游戏按钮 void mouseOnInstrgameButton( ) ; //光标在游戏介绍按钮 void mouseOnGameOptionButton( ) ; //光标在游戏选项按钮 void mouseOnGameHihgscButton( ) ; //光标在游戏排行榜按钮 void mouseOnExitgameButton( ) ; //光标在退出游戏按钮 void clickOnStartgameButton( ) ; //单击开始游戏按钮 void clickOnInstrgameButton( ) ; //单击游戏介绍按钮 void clickOnGameOptionButton( ) ; //单击游戏选项按钮 void clickOnGameHihgscButton( ) ; //单击游戏排行榜按钮 void clickOnExitgameButton( ) ; //单击退出游戏按钮 /* 这个是根据当前箭头序号来确定进入到哪个Item的槽函数 */ void clickOnButton( int index ) ; /* 用户按Esc键返回到第二层,返回游戏首页的信号的槽函数 */ void backToSecondLaySlot( int index ) ; //这个是前景Item的退回到游戏首页的按钮的槽函数 void backToGameHomeSlot() ;protected: //事件过滤器 bool eventFilter ( QObject * watched, QEvent * event ) ; void resizeEvent ( QResizeEvent * event );};#endif // TETRIXWIDGET_H

(3)TetrixWidget.cpp

/************************************************************************* 版权所有 (C)2011, 上海欣诺有限公司。** 文件名称:  TetrixWidget.cpp* 文件标识:* 内容摘要:  TetrixWidget类的实现* 其它说明:* 当前版本: 1.0* 作    者:* 完成日期:** 修改记录1:*    修改日期:*    版 本 号:*    修 改 人:*    修改内容:* 修改记录2:…************************************************************************/#include "TetrixWidget.h"#include 
/************************************************************************** * 常量 * **************************************************************************//************************************************************************** * 宏 * **************************************************************************//************************************************************************** * 数据类型 * **************************************************************************//************************************************************************** * 全局变量 * **************************************************************************//************************************************************************** * 局部函数原型 * **************************************************************************//************************************************************************** * 类TetrixWidget实现--公有部分 * **************************************************************************//*************************************************************************** 函数名称: TetrixWidget* 功能描述: 构造函数* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/TetrixWidget::TetrixWidget(QWidget *parent) :QWidget(parent),nowIndex( -1 ){ //初始化,设置其读取ini为后缀的配置文件 configIni = new QSettings( CONFIGUREPATH,QSettings::IniFormat ) ; //首先加载是两个logo文件 initAndLoadImage( GROUPNAME_LOGO,LOGO_COUNT ) ; /* 设置控件显示的参数,因为其大小是根据logo图片的大小还算的,所以要放在读取配置文件之后 */ setTetrixWigAttribute() ; //初始化视图的大小也是根据两个logo图片的大小来确定的,所以要放在读取配置文件之后 initGameSceneAndView() ; addGameLogoImageItem() ; //添加GameLogoImageItem到场景去 /* 只所以把GameLogoImageItem添加到场景去再加载所有的图片, 是因为logo图片有个渐显的效果,可以利用这个间隙把所有的图片 全部加载进来,该处理的出来掉。这样可以有效的利用时间,让用户感觉不到 加载图片过程 */ loadAllImageFile() ; //加载所有的图片 /* 根据组名及每组对应的图片数目的A值来读取配置文件,并且记录到namePointHash中去。 */ initNameAndPointHash( GROUPNAME_COORDINATE ,COORDINATE_COUNT) ;}/************************************************************************ 函数名称: ~TetrixWidget()* 功能描述: 析构函数* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------**************************************************************************/TetrixWidget::~TetrixWidget(){ //这个显示delete,qt都可以通过qt来进行delete的 delete gameSound ;}/*************************************************************************** 函数名称: setTetrixWigAttribute* 功能描述: 设置TetrixWidget类的属性* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::setTetrixWigAttribute(){ /* 这里是设置屏蔽窗口最大化的按钮的属性,在linux下没有效果,在windows有效果不知道为啥 */ this->setWindowFlags( Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint ); //设置居中屏幕显示 QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以 /* 这个是根据logo的大小来确定的,由于控件比图片多一个宽口管理其,所以height加40进行调整 ,以达到初始显示在屏幕中间的效果 */ if( nameImageHash.contains( LOGO_1 ) ) { int width = nameImageHash.value(LOGO_1)->size().width() ; int height = nameImageHash.value(LOGO_1)->size().height() + 40 ; move((desktop->width() - width)/2, (desktop->height() - height)/2); } //安装事件过滤器 this->installEventFilter( this ); setWindowTitle("俄罗斯方块单机版 V1.0");}/*************************************************************************** 函数名称: initAndLoadImage* 功能描述: 根据组名及每组对应的图片数目的A值来读取配置文件,并且加载图片文件。* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::initAndLoadImage(QString groupname, QString A_valueString){ if( !groupname.isEmpty() ) { configIni->beginGroup( groupname ); configIni->setIniCodec( "UTF-8" ); int count = configIni->value( A_valueString).toInt() ; QStringList keyslist = configIni->allKeys() ; //configIni->allKeys()因为这个里面有包含啦求数目的那条A值 if( keyslist.count() == (count + 1) ) { foreach( QString value,keyslist ) { //如果为数目的A值,则不做处理 if( QString::compare( value , A_valueString ) ) { QString imagePath = configIni->value( value ).toString() ; QImage *iamge = new QImage( imagePath ) ; //如果不能加载图片文件,则退出 if( iamge->isNull() ) { QString errorString = QString("File :%1 is not exit !" ).arg(imagePath) ; DEBUGP( errorString ) ; configIni->endGroup(); return ; } //把图片名字与图片加入到hash表中 nameImageHash.insert( value,iamge ) ; } } } else { DEBUGP( "Configure File Num Error !" ) ; configIni->endGroup(); return ; } configIni->endGroup(); }}/************************************************************************** 函数名称: initNameAndPointHash* 功能描述: 根据组名及每组对应的图片数目的A值来读取配置文件,并且记录到namePointHash中去* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::initNameAndPointHash(QString groupname, QString A_valueString){ if( !groupname.isEmpty() ) { configIni->beginGroup( groupname ); configIni->setIniCodec( "UTF-8" ); int count = configIni->value( A_valueString ).toInt() ; QStringList keyslist = configIni->allKeys() ; //configIni->allKeys()因为这个里面有包含啦求数目的那条A值 if( keyslist.count() == (count + 1) ) { foreach( QString key,keyslist ) { //如果为数目的A值,则不做处理 if( QString::compare( key , A_valueString ) ) { QPoint pos = configIni->value(key).toPoint() ; //DEBUGP( pos ) ; namePointHash.insert( key,pos ) ; } } } configIni->endGroup(); }}/************************************************************************** 函数名称: getTransImage* 功能描述: 这个坐标ponit用于取图片上某个坐标点的色素作为透明色,默认为QPoint( 0,0 )* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/QImage *TetrixWidget::getTransImage(QImage *image, QPoint ponit){ //判断所取的点是否在图片内部 if( image->valid( ponit ) ) { QRgb rgb = image->pixel( ponit ); QVector
rgbVector = image->colorTable () ; for (int i = 0; i < rgbVector.size(); ++i) { if( rgbVector.at(i) == rgb ) { /* 注意这里如果要变成黑色背景的话就是QRgb rgb2 = QColor(0, 0, 0, 0).rgb() ; 留意 rgb()与rgba()的区别 */ QRgb rgb2 = QColor(0, 0, 0, 0).rgba() ; image->setColor( i,rgb2 ); return image ; } } } return image ;}/************************************************************************** 函数名称: initGameSceneAndView* 功能描述: 初始化游戏的场景与视图* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::initGameSceneAndView(){ gameScene = new GameGraphicsScene() ; gameScene->setBackgroundBrush(Qt::black); //这里要是不限制场景的大小的话,之后小鱼游动时,其场景会增大,之后显示就会移动 //因为小鱼要被完全隐藏掉之后,才掉头重新开始游这样就可能增大场景,故再这里给写死 gameScene->setSceneRect(0, 0, SCENEWIDTH, SCENEHEIGHT); gameView = new QGraphicsView(this) ; gameView->setScene(gameScene); //设置文字去锯齿显示 gameView->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //设置大小,跟logo图片的大小一样大,不能写死,这样灵活些 if( nameImageHash.contains( LOGO_1 ) ) { /* 在这里把长宽进行微调,不然会出现在场景中滚动鼠标是,场景上下移动的问题 */ int width = nameImageHash.value(LOGO_1)->size().width()+ 2 ; int height = nameImageHash.value(LOGO_1)->size().height() + 2 ; gameView->resize( width,height ); } //关闭水平滚动条与垂直滚动条 gameView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); gameView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);}/************************************************************************** 函数名称: loadAllImageFile* 功能描述: 加载所有的图片* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::loadAllImageFile(){ //加载ModeWin组的文件 initAndLoadImage( GROUPNAME_MODEWIN,MODEWIN_COUNT ) ; //加载DianWoWin组的文件 initAndLoadImage( GROUPNAME_DIANWOWIN,DIANWOWIN_COUNT ) ; //加载OptionWin组的文件 initAndLoadImage( GROUPNAME_OPTIONWID,OPTIONWID_COUNT ) ; //加载Box组的文件 initAndLoadImage( GROUPNAME_BOX,BOX_COUNT ) ; //加载BackWin组的文件 initAndLoadImage( GROUPNAME_BACKWIN,BACKWIN_COUNT ) ; //加载BombWin组的文件 initAndLoadImage( GROUPNAME_BOMBWIN,BOMBWIN_COUNT ) ; //加载MainWin组的文件 initAndLoadImage( GROUPNAME_MAINWIN,MAINWIN_COUNT ) ; //修改MustModify组A值所对应的图片,去掉其背景粉红色,变为透明背景 dealPinkBackGroundImage( GROUPNAME_MUSTMODIFY,MUSTMODIFY_COUNT ) ;}/************************************************************************** 函数名称: dealPinkBackGroundImage* 功能描述: 添加dealPinkBackGroundImage到场景去* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::dealPinkBackGroundImage(QString groupname, QString A_valueString ){ if( !groupname.isEmpty() ) { configIni->beginGroup( groupname ); configIni->setIniCodec( "UTF-8" ); int count = configIni->value( A_valueString).toInt() ; QStringList keyslist = configIni->allKeys() ; //configIni->allKeys()因为这个里面有包含啦求数目的那条A值 if( keyslist.count() == (count + 1) ) { foreach( QString key,keyslist ) { //如果为数目的A值,则不做处理 if( QString::compare( key , A_valueString ) ) { //DEBUGP( key ) ; //对图片进行处理,去掉粉红的背景 QImage *image = getTransImage( nameImageHash.value( key ) ); //重新发修改后的值加入到hash表中 nameImageHash.insert( key,image ) ; } } } //注意读完这个组一定要关闭,否则会影响到下面的读取 configIni->endGroup(); }}/************************************************************************** 函数名称: addGameLogoImageItem* 功能描述: 添加GameLogoImageItem到场景去* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addGameLogoImageItem(){ logoImageItem = new GameLogoImageItem() ; // connect(logoImageItem,SIGNAL(addGameBackGroundItem()) ,this,SLOT(addGameBackGroundItem())) ; logoImageItem->setGameScene( gameScene,nameImageHash);}/************************************************************************** 函数名称: addAllSecondLayerItem* 功能描述: 添加所有的第二层的Item,通过一个接口把所有的第二层的Item全部放进来,方便管理* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addAllSecondLayerItem(){ //DEBUGP( "addAllSecondLayerItem" ) ; //点我广告的按钮 addDianWoButton() ; //更多的游戏按钮 addMoreGameButton() ; //开始游戏按钮 addStartGameButton() ; //游戏介绍按钮 addInstrGameButton() ; //游戏选项按钮 addGameOptionButton() ; //游戏排行榜按钮 addGameHihgscButton() ; //退出游戏按钮 addExitGameButton() ; //箭头Item addArrowItem() ;}/************************************************************************** 函数名称: addArrowItem* 功能描述: 添加箭头Item* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addArrowItem(){ //箭头Item arrowItem = new GameArrowItem( MODEWIN_ARROW ) ; //在这里连接改变坐标的信号与槽 connect(this,SIGNAL(moveArrowat(int)),arrowItem,SLOT(setPointListIndex(int))) ; //这个是根据当前箭头序号来确定进入到哪个Item的槽函数 connect(arrowItem,SIGNAL(enterIntoButton(int)),this,SLOT(clickOnButton(int))); //通过这个信号返回到第二层----游戏首页 connect(arrowItem,SIGNAL(backToSecondLay(int)),this,SLOT(backToSecondLaySlot(int))); arrowItem->setGameScene(gameScene,nameImageHash,namePointHash); /* 这里为啦保持跟上面的一直,所以把设置Z轴的放在这里,其实不必要放在这里, 因为箭头类是一个单独的类,只有一个对象在用 */ arrowItem->setZValue(1.0);}/************************************************************************** 函数名称: addExitGameButton* 功能描述: 添加退出游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addExitGameButton(){ //退出游戏按钮 exitgameButton = new GameButtonItem( MODEWIN_EXIT ) ; connect(exitgameButton,SIGNAL(mouseOnMe()), this,SLOT(mouseOnExitgameButton())) ; connect(exitgameButton,SIGNAL(buttonClick()),this,SLOT(close())) ; exitgameButton->setGameScene(gameScene,nameImageHash,namePointHash); exitgameButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: addGameHihgscButton* 功能描述: 添加游戏排行榜按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addGameHihgscButton(){ //游戏排行榜按钮 gamehihgscButton = new GameButtonItem( MODEWIN_HIGHSCORE ) ; connect(gamehihgscButton,SIGNAL(mouseOnMe()), this,SLOT(mouseOnGameHihgscButton())) ; connect(gamehihgscButton,SIGNAL(buttonClick()),this,SLOT(clickOnGameHihgscButton())); gamehihgscButton->setGameScene(gameScene,nameImageHash,namePointHash); gamehihgscButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: addGameOptionButton* 功能描述: 添加游戏选项按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addGameOptionButton(){ //游戏选项按钮 gameoptionButton = new GameButtonItem( MODEWIN_OPTION ) ; connect(gameoptionButton,SIGNAL(mouseOnMe()), this,SLOT(mouseOnGameOptionButton())) ; connect(gameoptionButton,SIGNAL(buttonClick()), this,SLOT(clickOnGameOptionButton())) ; gameoptionButton->setGameScene(gameScene,nameImageHash,namePointHash); gameoptionButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: addInstrGameButton* 功能描述: 添加游戏介绍按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addInstrGameButton(){ //游戏介绍按钮 instrgameButton = new GameButtonItem( MODEWIN_INSTRUCTION ) ; connect(instrgameButton,SIGNAL(mouseOnMe()), this,SLOT(mouseOnInstrgameButton())) ; connect(instrgameButton,SIGNAL(buttonClick()) ,this,SLOT(clickOnInstrgameButton())) ; instrgameButton->setGameScene(gameScene,nameImageHash,namePointHash); instrgameButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: addDianWoButton* 功能描述: 添加点我按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addDianWoButton(){ //点我广告的按钮 dianwoButton = new GameButtonItem( DIANWOWIN_BUTTON ) ; dianwoButton->setGameScene(gameScene,nameImageHash,namePointHash); dianwoButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: addMoreGameButton* 功能描述: 添加更多的游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addMoreGameButton(){ //更多的游戏按钮 moregameButton = new GameButtonItem( MODEWIN_MOREGAME ) ; moregameButton->setGameScene(gameScene,nameImageHash,namePointHash); moregameButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: addStartGameButton* 功能描述: 添加开始游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addStartGameButton(){ startgameButton = new GameButtonItem( MODEWIN_START ) ; connect(startgameButton,SIGNAL(mouseOnMe()), this,SLOT(mouseOnStartgameButton())) ; connect(startgameButton,SIGNAL(buttonClick()), this,SLOT(clickOnStartgameButton())) ; startgameButton->setGameScene(gameScene,nameImageHash,namePointHash); startgameButton->setZValue(1.0); //因为不是全部都在同一层,所有得分开来设置其Z轴的值}/************************************************************************** 函数名称: setSomeItemVisible* 功能描述: 这里是因为,这个设置的图片太小,要把下面的开始与退出按钮给隐藏掉,* 不然用户移动鼠标会误点到* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:控制这四个按钮的显示与隐藏* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::setSomeItemVisible(bool visible){ startgameButton->setVisible( visible ); exitgameButton->setVisible( visible ); dianwoButton->setVisible( visible ); moregameButton->setVisible( visible );}/************************************************************************** 函数名称: getVolumeValueFromFile* 功能描述: 从配置文件中读出所要的音量的值* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:控制这四个按钮的显示与隐藏* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/inline int TetrixWidget::getVolumeValueFromFile(QString groupname, QString A_valueString){ configIni->beginGroup( groupname ); configIni->setIniCodec( "UTF-8" ); int volume = configIni->value( A_valueString ).toInt() ; configIni->endGroup(); return volume ;}/************************************************************************** 函数名称: getFullScreenValueFromFile* 功能描述: 从配置文件中读取是否要设置全屏* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:控制这四个按钮的显示与隐藏* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/inline bool TetrixWidget::getFullScreenValueFromFile(QString groupname, QString A_valueString){ configIni->beginGroup( groupname ); configIni->setIniCodec( "UTF-8" ); bool fullscreen = configIni->value( A_valueString ).toBool() ; configIni->endGroup(); return fullscreen ;}/************************************************************************** 函数名称: initGameGameSound* 功能描述: 初始化游戏的背景音乐与音效* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::initGameGameSound(){ int musicVolume = getVolumeValueFromFile( GROUPNAME_SETTINGS,SETTINGS_MUSIC ) ; int audioVolume = getVolumeValueFromFile( GROUPNAME_SETTINGS,SETTINGS_AUDIO ) ; gameSound = new GameGameSound( musicVolume,audioVolume ) ; gameSound->setGameSceneAndConfigF(gameScene,configIni);}/************************************************************************** 函数名称: addGameBackGroundItem* 功能描述: 添加addGameBackGroundItem到场景去* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::addGameBackGroundItem(){ //在添加背景图片前先移除两个logo图片 gameScene->removeItem( logoImageItem ); backGroundItem = new GameBackGroundItem() ; backGroundItem->setGameScene( gameScene,nameImageHash ); //添加所有的第二层的Item addAllSecondLayerItem() ; //初始化游戏的背景音乐与音效 initGameGameSound();}/************************************************************************** 函数名称: mouseOnStartgameButton* 功能描述: 光标在开始游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明: 5个Button发送过来的信号分别对应不同的槽函数,在槽函数中又分别发送同一信号* 不同参数,这样觉得有点麻烦,一下子用啦5个槽函数,目前没有想到更好的办法。* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::mouseOnStartgameButton(){ //DEBUGP( 0 ) ; emit moveArrowat( 0) ;}/************************************************************************** 函数名称: mouseOnInstrgameButton* 功能描述: 光标在游戏介绍按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::mouseOnInstrgameButton(){ //DEBUGP( 1 ) ; emit moveArrowat( 1 ) ;}/************************************************************************** 函数名称: mouseOnGameOptionButton* 功能描述: 光标在游戏选项按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::mouseOnGameOptionButton(){ //DEBUGP( 2 ) ; emit moveArrowat( 2 ) ;}/************************************************************************** 函数名称: mouseOnGameHihgscButton* 功能描述: 光标在游戏排行榜按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::mouseOnGameHihgscButton(){ //DEBUGP( 3 ) ; emit moveArrowat( 3 ) ;}/************************************************************************** 函数名称: mouseOnExitgameButton* 功能描述: 光标在退出游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::mouseOnExitgameButton(){ //DEBUGP( 4 ) ; emit moveArrowat( 4 ) ;}/************************************************************************** 函数名称: clickOnStartgameButton* 功能描述: 单击开始游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::clickOnStartgameButton(){ movBacGrouItem =new GameMovBackGrouItem( MAINWIN_BACKGROUND ) ; //这个作为序号0记录到hash表中 nowIndex = 0 ; numPointer.insert( nowIndex,(void *)movBacGrouItem ) ; connect( this,SIGNAL(coverOnArowItemSignal(bool)), gameScene,SIGNAL(changeCoveredStateSignal(bool))) ; //转发游戏窗口停用信号到场景中的游戏暂停信号 connect(this,SIGNAL(gameDeactivateSignal()),gameScene,SIGNAL(gameDeactivateSignal())) ; //连接从场景中转发出来的回到游戏首页的信号与槽函数 connect(gameScene,SIGNAL(backToGameHomeSignal()), this,SLOT(backToGameHomeSlot())) ; movBacGrouItem->setGameScene( gameScene,nameImageHash,namePointHash ); movBacGrouItem->setZValue( 3.0 ) ; //这个是作为第三层显示的 //发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( true );}/************************************************************************** 函数名称: clickOnInstrgameButton* 功能描述: 单击游戏介绍按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::clickOnInstrgameButton(){ introduItem = new GameIntroductionItem( MODEWIN_HELP ) ; //这个作为序号1记录到hash表中 nowIndex = 1 ; numPointer.insert( nowIndex,(void *)introduItem ) ; //返回游戏首页的信号的槽函数 connect(introduItem,SIGNAL(backToSecondLay(int)),this,SLOT(backToSecondLaySlot(int))) ; connect( this,SIGNAL(coverOnArowItemSignal(bool)), gameScene,SIGNAL(changeCoveredStateSignal(bool))) ; introduItem->setGameScene( gameScene,nameImageHash ); introduItem->setZValue( 3.0 ) ; //这个是作为第三层显示的 //发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( true );}/************************************************************************** 函数名称: clickOnGameOptionButton* 功能描述: 单击游戏选项按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::clickOnGameOptionButton(){ int musicVolume = getVolumeValueFromFile( GROUPNAME_SETTINGS,SETTINGS_MUSIC ) ; int audioVolume = getVolumeValueFromFile( GROUPNAME_SETTINGS,SETTINGS_AUDIO ) ; bool fullScreen = getFullScreenValueFromFile( GROUPNAME_SETTINGS,SETTINGS_FULLSCREEN) ; //DEBUGP( audioVolume ) ; optionItem = new GameOptionItem( OPTIONWIN_SETTING,musicVolume,audioVolume,fullScreen ) ; connect(optionItem,SIGNAL(backToSecondLay(int)),this,SLOT(backToSecondLaySlot(int))) ; connect( this,SIGNAL(coverOnArowItemSignal(bool)), gameScene,SIGNAL(changeCoveredStateSignal(bool))) ; //这个作为序号1记录到hash表中 nowIndex = 2 ; numPointer.insert( nowIndex,(void *)optionItem ) ; optionItem->setGameScene( gameScene,nameImageHash,namePointHash ); optionItem->setConfigureFile( configIni ); optionItem->setZValue( 3.0 ) ; //这个是作为第三层显示的 /* 这里是因为,这个设置的图片太小,要把下面的开始与退出按钮给隐藏掉, 不然用户移动鼠标会误点到 */ setSomeItemVisible( false ) ; //发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( true );}/************************************************************************** 函数名称: clickOnGameHihgscButton* 功能描述: 单击游戏排行榜按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::clickOnGameHihgscButton(){ highWinItem = new GameHighWinItem( MODEWIN_HIGHWIN ); connect(highWinItem,SIGNAL(backToSecondLay(int)),this,SLOT(backToSecondLaySlot(int))) ; connect( this,SIGNAL(coverOnArowItemSignal(bool)), gameScene,SIGNAL(changeCoveredStateSignal(bool))) ; //这个作为序号1记录到hash表中 nowIndex = 3 ; numPointer.insert( nowIndex,(void *)highWinItem ) ; highWinItem->setGameScene( gameScene,nameImageHash,namePointHash ); highWinItem->setZValue( 3.0 ) ; //这个是作为第三层显示的 //发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( true );}/************************************************************************** 函数名称: clickOnExitgameButton* 功能描述: 单击退出游戏按钮* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::clickOnExitgameButton(){ //退出程序 this->close() ;}/************************************************************************** 函数名称: clickOnButton* 功能描述: 这个是根据当前箭头序号来确定进入到哪个Item的槽函数* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::clickOnButton(int index){ switch( index ) { case 0: clickOnStartgameButton() ; break ; case 1: clickOnInstrgameButton() ; break ; case 2: clickOnGameOptionButton() ; break ; case 3: clickOnGameHihgscButton() ; break ; case 4: clickOnExitgameButton() ; break ; default: break ; }}/************************************************************************** 函数名称: backToSecondLaySlot* 功能描述: 用户按Esc键返回到第二层,返回游戏首页的信号的槽函数* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明: 通过这个当前箭头所对应的序号的值* 比如说* 0---->开始游戏* 1---->游戏介绍* 。。。。。。* 在NumAndPointerHash表中查找相应的Item的指针的值* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::backToSecondLaySlot( int index ){ void * item ; /*如果当用户本来就在第二层游戏首页时,这个时候却按下Esc键,这个时候这个item为空。首先得判断hash表中有没这个key值 */ if( numPointer.contains( index ) ) { item = numPointer.value( index ) ; if( item ) { //因为每个类型的指针的类型是不同的,所以这里得这样分开来写 switch( index ) { case 0: //在这里发送信号,先去删除动态珊瑚背景层之上的东西,也就是第四层与第五层的东西 //因为第四层与第五层都是作为动态珊瑚背景(第三层)的成员变量,所以在这里得在删除第三层前 //删掉第四层与第五层的东西 ((GameMovBackGrouItem *)item)->removeFourthAndFifthItemFun(); gameScene->removeItem( (GameMovBackGrouItem *)item ); delete ((GameMovBackGrouItem *)item); //再次发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( false ); break ; case 1: gameScene->removeItem( (GameIntroductionItem *)item ); delete (GameIntroductionItem *)item ; //再次发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( false ); break ; case 2: //使得四个按钮恢复显示 setSomeItemVisible( true ) ; gameScene->removeItem( (GameOptionItem *)item ); delete (GameOptionItem *)item ; //再次发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( false ); break ; case 3: gameScene->removeItem( (GameHighWinItem *)item ); delete (GameHighWinItem *)item ; //再次发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( false ); break ; case 4: break ; default: DEBUGP( "index error !" ) ; break ; } //清空现在的记录,以便下次再进行切换 nowIndex = -1 ; numPointer.remove( index ) ; } }}/************************************************************************** 函数名称: backToGameHomeSlot* 功能描述: 这个是前景Item的退回到游戏首页的按钮的槽函数* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/void TetrixWidget::backToGameHomeSlot(){ //因为这个时候是进入游戏之后才可以看到游戏的前景 backToSecondLaySlot( 0 ) ;}/************************************************************************** 函数名称: eventFilter* 功能描述: 事件过滤器* 访问的表:* 修改的表:* 输入参数:* 输出参数:* 返 回 值:* 其它说明:这个是重载事件过滤器函数,通过这个函数判断,当鼠标移动到其他的软件的窗口时,* 这个时候整个游戏软件被停用。在这个时候发送暂停游戏的消息* 修改日期 版本号 修改人 修改内容* -----------------------------------------------***************************************************************************/bool TetrixWidget::eventFilter(QObject *watched, QEvent *event){ if( watched == this ) { //窗口停用,及一般人认为的失去焦点 if(QEvent::WindowDeactivate == event->type()) { // //DEBUGP( "eventFilter" ) ; emit gameDeactivateSignal() ; return true ; } else { return false ; } } return false ;}void TetrixWidget::resizeEvent(QResizeEvent *event){ gameScene->setSceneRect(0, 0, gameView->width(), gameView->height());}

 

三、总结

(1)上述代码是一个非常不错的项目例子,自己也在拜读代码(也有很多不懂的地方),并在实际工作中加以应用。

(2)上述代码已上传到CSDN:。
(3)若有问题或建议,请留言,在此感谢!

你可能感兴趣的文章
MySQL中一条SQL是如何执行的?
查看>>
MySQL的索引是什么?怎么优化?
查看>>
2万字长文包教包会 JVM 内存结构
查看>>
不懂 spring 就彻底放弃 Java 吧!
查看>>
从MySQL高可用架构看高可用架构设计
查看>>
可以秒杀全场的SpringCloud微服务电商实战项目,文档贼全!
查看>>
java架构之路(多线程)synchronized详解以及锁的膨胀升级过程
查看>>
java架构之路(多线程)AQS之ReetrantLock显示锁的使用和底层源码解读
查看>>
百度现场面试:JVM+算法+Redis+数据库!(三面)
查看>>
java架构之路(多线程)JMM和volatile关键字
查看>>
创业感悟:技术兄弟为什么一直没有起来
查看>>
(转载)linux命令之十八locate 命令
查看>>
Linux发行光盘(红旗 5.0 SP2发行版,已不使用仅参考)
查看>>
linux下如何将文件打包、压缩并分割成制定大小
查看>>
CentOS6.5升级内核到3.10.28
查看>>
linux内核补丁安装和编译安装
查看>>
(转载)linux命令之十九find 命令
查看>>
(转载)linux命令之二十 find命令之exec
查看>>
(转载)linux命令之二十一find命令之xargs
查看>>
centos下C编程调用libvirt的API访问KVM虚拟机
查看>>