• Qt浅谈之四十九俄罗斯方块(代码来自网络)


    一、简单介绍

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


    二、具体解释

    1、部分代码

    (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上面的箭头的信号
        //这个信号放在这个类里是由于,button弹出的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 ;
        /*
        这里是由于,这个设置的图片太小。要把以下的開始与退出button给隐藏掉。
        不然用户移动鼠标会误点到
        */
        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 ;            //点我的广告button
        GameButtonItem *moregameButton ;          //很多其他的游戏button
        GameButtonItem *startgameButton ;         //開始游戏button
        GameButtonItem *instrgameButton ;         //游戏介绍button
        GameButtonItem *gameoptionButton ;        //游戏选项button
        GameButtonItem *gamehihgscButton ;        //游戏排行榜button
        GameButtonItem *exitgameButton ;          //退出游戏button
        GameArrowItem  *arrowItem ;               //箭头Item
        /*
        加入全部的第二层的Item,通过一个接口把全部的第二层的Item全部放进来。方便管理
        */
        void addAllSecondLayerItem() ;
        //分开进行加入这样不至于让一个函数变的非常长
        void addDianWoButton() ;       //加入点我button
        void addMoreGameButton() ;     //加入很多其他的游戏button
        void addStartGameButton() ;    //加入開始游戏button
        void addInstrGameButton() ;    //加入游戏介绍button
        void addGameOptionButton() ;   //加入游戏选项button
        void addGameHihgscButton() ;   //加入游戏排行榜button
        void addExitGameButton() ;     //加入退出游戏button
        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( ) ;        //光标在開始游戏button
        void mouseOnInstrgameButton( ) ;        //光标在游戏介绍button
        void mouseOnGameOptionButton( ) ;       //光标在游戏选项button
        void mouseOnGameHihgscButton( ) ;       //光标在游戏排行榜button
        void mouseOnExitgameButton( ) ;         //光标在退出游戏button
    
        void clickOnStartgameButton( ) ;        //单击開始游戏button
        void clickOnInstrgameButton( ) ;        //单击游戏介绍button
        void clickOnGameOptionButton( ) ;       //单击游戏选项button
        void clickOnGameHihgscButton( ) ;       //单击游戏排行榜button
        void clickOnExitgameButton( ) ;         //单击退出游戏button
    
        /*
        这个是依据当前箭头序号来确定进入到哪个Item的槽函数
        */
        void clickOnButton( int index ) ;
    
        /*
        用户按Esc键返回到第二层。返回游戏首页的信号的槽函数
        */
        void backToSecondLaySlot( int index ) ;
        //这个是前景Item的退回到游戏首页的button的槽函数
        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() { /* 这里是设置屏蔽窗体最大化的button的属性,在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" ) ; //点我广告的button addDianWoButton() ; //很多其他的游戏button addMoreGameButton() ; //開始游戏button addStartGameButton() ; //游戏介绍button addInstrGameButton() ; //游戏选项button addGameOptionButton() ; //游戏排行榜button addGameHihgscButton() ; //退出游戏button 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 * 功能描写叙述: 加入退出游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::addExitGameButton() { //退出游戏button 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 * 功能描写叙述: 加入游戏排行榜button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::addGameHihgscButton() { //游戏排行榜button 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 * 功能描写叙述: 加入游戏选项button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::addGameOptionButton() { //游戏选项button 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 * 功能描写叙述: 加入游戏介绍button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::addInstrGameButton() { //游戏介绍button 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 * 功能描写叙述: 加入点我button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::addDianWoButton() { //点我广告的button dianwoButton = new GameButtonItem( DIANWOWIN_BUTTON ) ; dianwoButton->setGameScene(gameScene,nameImageHash,namePointHash); dianwoButton->setZValue(1.0); //由于不是全部都在同一层,全部得分开来设置其Z轴的值 } /************************************************************************* * 函数名称: addMoreGameButton * 功能描写叙述: 加入很多其他的游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::addMoreGameButton() { //很多其他的游戏button moregameButton = new GameButtonItem( MODEWIN_MOREGAME ) ; moregameButton->setGameScene(gameScene,nameImageHash,namePointHash); moregameButton->setZValue(1.0); //由于不是全部都在同一层,全部得分开来设置其Z轴的值 } /************************************************************************* * 函数名称: addStartGameButton * 功能描写叙述: 加入開始游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 * 功能描写叙述: 这里是由于,这个设置的图片太小,要把以下的開始与退出button给隐藏掉。 * 不然用户移动鼠标会误点到 * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明:控制这四个button的显示与隐藏 * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::setSomeItemVisible(bool visible) { startgameButton->setVisible( visible ); exitgameButton->setVisible( visible ); dianwoButton->setVisible( visible ); moregameButton->setVisible( visible ); } /************************************************************************* * 函数名称: getVolumeValueFromFile * 功能描写叙述: 从配置文件里读出所要的音量的值 * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明:控制这四个button的显示与隐藏 * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 * 功能描写叙述: 从配置文件里读取是否要设置全屏 * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明:控制这四个button的显示与隐藏 * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 * 功能描写叙述: 光标在開始游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: 5个Button发送过来的信号分别相应不同的槽函数,在槽函数中又分别发送同一信号 * 不同參数。这样觉得有点麻烦。一下子用啦5个槽函数。眼下没有想到更好的办法。 * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::mouseOnStartgameButton() { //DEBUGP( 0 ) ; emit moveArrowat( 0) ; } /************************************************************************* * 函数名称: mouseOnInstrgameButton * 功能描写叙述: 光标在游戏介绍button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::mouseOnInstrgameButton() { //DEBUGP( 1 ) ; emit moveArrowat( 1 ) ; } /************************************************************************* * 函数名称: mouseOnGameOptionButton * 功能描写叙述: 光标在游戏选项button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::mouseOnGameOptionButton() { //DEBUGP( 2 ) ; emit moveArrowat( 2 ) ; } /************************************************************************* * 函数名称: mouseOnGameHihgscButton * 功能描写叙述: 光标在游戏排行榜button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::mouseOnGameHihgscButton() { //DEBUGP( 3 ) ; emit moveArrowat( 3 ) ; } /************************************************************************* * 函数名称: mouseOnExitgameButton * 功能描写叙述: 光标在退出游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ void TetrixWidget::mouseOnExitgameButton() { //DEBUGP( 4 ) ; emit moveArrowat( 4 ) ; } /************************************************************************* * 函数名称: clickOnStartgameButton * 功能描写叙述: 单击開始游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 * 功能描写叙述: 单击游戏介绍button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 * 功能描写叙述: 单击游戏选项button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 ) ; //这个是作为第三层显示的 /* 这里是由于,这个设置的图片太小,要把以下的開始与退出button给隐藏掉, 不然用户移动鼠标会误点到 */ setSomeItemVisible( false ) ; //发送信号来还原之前改变的箭头Item的遮蔽状态 emit coverOnArowItemSignal( true ); } /************************************************************************* * 函数名称: clickOnGameHihgscButton * 功能描写叙述: 单击游戏排行榜button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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 * 功能描写叙述: 单击退出游戏button * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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: //使得四个button恢复显示 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的退回到游戏首页的button的槽函数 * 訪问的表: * 改动的表: * 输入參数: * 输出參数: * 返 回 值: * 其他说明: * 改动日期 版本号号 改动人 改动内容 * ----------------------------------------------- * **************************************************************************/ 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:http://download.csdn.net/detail/taiyang1987912/9480721


    (3)若有问题或建议,请留言,在此感谢!


  • 相关阅读:
    ASP.NET MVC 音乐商店 目录
    ASP.NET MVC 音乐商店 9. 注册和结账
    SQL查询入门(下篇)
    【译】Asp.net MVC并不仅仅只是Linq to SQL
    SQL查询入门(中篇)
    【译】利用.LESS来提高CSS
    Silverlight 入门学习笔记(1)Silverlight是什么
    【译】详解Asp.net MVC DropDownLists
    Asp.net缓存简介
    SQL查询入门(上篇)
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7230938.html
Copyright © 2020-2023  润新知