您的位置:首页 > 编程语言 > Qt开发

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

2016-04-04 12:20 537 查看


一、简介

      从网上下载了一个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上面的箭头的信号
//这个信号放在这个类里是因为,按钮弹出的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());
}


三、总结

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

(2)上述代码已上传到CSDN:http://download.csdn.net/detail/taiyang1987912/9480721

(3)若有问题或建议,请留言,在此感谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux qt