从网上下载了一个Qt实现的俄罗斯方块单机版的源码,觉得非常有意思,故以博客形式记录下来,以便慢慢来研究。在centos6.6下编译运行(注意程序运行需要读取pro目录的配置文件,若把编译目录选择在pro外的话运行会报错):
(1)main.cpp
#include <QApplication> #include <QTextCodec> #include <QCursor> #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 <QDesktopWidget> #include <QApplication> #include <QWidget> #include <QGraphicsView> #include <QSettings> #include <QStringList> #include <QImage> #include <QPoint> #include <QKeyEvent> #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_OBJECT signals: //发送信号给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 <QDebug> /************************************************************************** * 常量 * **************************************************************************/ /************************************************************************** * 宏 * **************************************************************************/ /************************************************************************** * 数据类型 * **************************************************************************/ /************************************************************************** * 全局变量 * **************************************************************************/ /************************************************************************** * 局部函数原型 * **************************************************************************/ /************************************************************************** * 类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<QRgb> 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()); }