#ifndef REACTIONGAME_H
#define REACTIONGAME_H
#include <QWidget>
#include <QPainter>
#include <QPixmap>
#include <QTimer>
#include <QLCDNumber>
//==================================================================================
//QT写的反应测试游戏.拖动本拉登头像,逃避美国大兵的追击。时间越长代表你的反应能力和智商就越高
//WGM约战平台游戏反应测试游戏.有利于提升你在CS中的反应能力和逻辑能力.
//程序编程人员:Jason's.Alex QQ:531401335
//QT社区群:167304303
//日期:2012/2/10
//==================================================================================
class ReactionGame : public QWidget
{
Q_OBJECT
public:
explicit ReactionGame(QWidget *parent = 0);
virtual ~ReactionGame();
void LoadResources();//载入资源
void ReleaseResources();//释放资源
virtual void paintEvent(QPaintEvent *);
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
struct BlockAttr
{
BlockAttr(const QPixmap &image):pixmap(image),xDecrease(false),yDecrease(false){}
QPoint point;
QPixmap pixmap;
bool xDecrease;
bool yDecrease;
};
signals:
void GameOver(const float &score,const QString&);//游戏结束
private:
void CalculatePos(BlockAttr *block);//计算位置
bool HasCollide(const BlockAttr *,const BlockAttr *);//计算时候碰撞
bool CheckValidBound(const BlockAttr *);//检测有效边界
void ResetGame();//重置游戏
void inilizetionGame();//初始化游戏
void NarrowValidRect(QRect *rect);//缩小有效矩形
const QString GetIQHint(const float score);//获取IQ提示
private slots:
void DrawEngine();//绘图引擎
private:
QPainter *painter;
BlockAttr *block1,*block2,*block3,*block4,*dropBlock;
int factor,speed;//伸展因子.和速度
QTimer *timer;
QRect validRect;//有效的矩形区域
int counter;
float score;//分数
QLCDNumber *lcd;//LCD显示计数器
};
#endif // REACTIONGAME_H
#include "reactiongame.h"
#include <QDebug>
#include <QResizeEvent>
#include <QFont>
//==================================================================================
//QT写的反应测试游戏.拖动本拉登头像,逃避美国大兵的追击。时间越长代表你的反应能力和智商就越高
//WGM约战平台游戏反应测试游戏.有利于提升你在CS中的反应能力和逻辑能力.
//程序编程人员:Jason's.Alex QQ:531401335
//QT社区群:167304303
//日期:2012/2/10
//==================================================================================
ReactionGame::ReactionGame(QWidget *parent) :
QWidget(parent)
{
timer=new QTimer(this);
connect(timer,SIGNAL(timeout()),SLOT(DrawEngine()));
lcd=new QLCDNumber(this);
}
ReactionGame::~ReactionGame()
{
}
void ReactionGame::LoadResources()//载入资源
{
block1=new BlockAttr(QPixmap(":/gamepix/game/1"));
block2=new BlockAttr(QPixmap(":gamepix/game/2"));
block3=new BlockAttr(QPixmap(":/gamepix/game/3"));
block4=new BlockAttr(QPixmap(":/gamepix/game/4"));
dropBlock=new BlockAttr(QPixmap(":/gamepix/game/drop"));
this->inilizetionGame();
}
void ReactionGame::ReleaseResources()//释放资源
{
delete block1;
delete block2;
delete block3;
delete block4;
delete dropBlock;
}
void ReactionGame::inilizetionGame()//初始化游戏
{
block1->point.setX(this->width()/2);
block1->point.setY(0);
block2->point.setX(0);
block2->point.setY(this->height()/2);
block3->point.setX(this->width()/2);
block3->point.setY(this->height()-block3->pixmap.height());
block4->point.setX(this->width()-block4->pixmap.width());
block4->point.setY(this->height()/2);
dropBlock->point.setX(this->width()/2);
dropBlock->point.setY(this->height()/2);
validRect.setX(100);
validRect.setY(100);
validRect.setWidth(this->width()-200);
validRect.setHeight(this->height()-200);
counter=1;
factor=1;
speed=2;
score=0;
}
void ReactionGame::paintEvent(QPaintEvent *)
{
painter=new QPainter(this);
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(Qt::red);
painter->setBrush(QColor(0xbe,0xbe,0xbe));
painter->drawRect(this->rect());
painter->setPen(Qt::yellow);
painter->setBrush(QColor(0xff,0x9d-speed*5,0x6f));
painter->drawRect(this->validRect);
painter->setPen(Qt::blue);
painter->setFont(QFont("Helvetica",12,QFont::Bold));
painter->drawText(this->width()/4,20,tr("Reaction:")+QString::number(score));
painter->drawPixmap(block1->point,block1->pixmap);
painter->drawPixmap(block2->point,block2->pixmap);
painter->drawPixmap(block3->point,block3->pixmap);
painter->drawPixmap(block4->point,block4->pixmap);
painter->drawPixmap(dropBlock->point,dropBlock->pixmap);
if(counter==1)
{
painter->setPen(Qt::magenta);
painter->drawText(validRect,tr("This game is to test the player an instant reaction and logical thinking ability\n"//这个游戏是测试玩家瞬间的反应和逻辑思维能力
"Drag the picture of Osama bin Laden, to avoid the pursuit of American soldiers!\n"//拖动本拉登头像避开美国大兵的追击!
"The longer you pursue on behalf of the higher IQ!"));//追击时间越久代表你智商越高
}
delete painter;
this->update();
}
void ReactionGame::mouseMoveEvent(QMouseEvent *e)
{
dropBlock->point.setX(e->pos().x()-dropBlock->pixmap.width()/2);
dropBlock->point.setY(e->pos().y()-dropBlock->pixmap.height()/2);
}
void ReactionGame::mousePressEvent(QMouseEvent *e)
{
if(e->type()==QMouseEvent::MouseButtonPress)
{
QPoint begin=dropBlock->point;
QPoint end(dropBlock->point.x()+dropBlock->pixmap.size().width(),dropBlock->point.y()+dropBlock->pixmap.size().height());
if(begin.x()<=e->pos().x()&&begin.y()<=e->pos().y()&&end.x()>=e->pos().x()&&end.y()>=e->pos().y())
{
timer->start(1);
}
}
}
void ReactionGame::mouseReleaseEvent(QMouseEvent *e)
{
if(e->type()==QMouseEvent::MouseButtonRelease)
{
this->ResetGame();
}
}
void ReactionGame::DrawEngine()//绘制引擎
{
score=float(speed*counter)/350;//显示分数
for(int i=0;i<speed;++i)
{
CalculatePos(block1);
CalculatePos(block2);
CalculatePos(block3);
CalculatePos(block4);
if(HasCollide(dropBlock,block1)||HasCollide(dropBlock,block2)||
HasCollide(dropBlock,block3)||HasCollide(dropBlock,block4)||!this->CheckValidBound(dropBlock))//如果产生碰撞
{
emit GameOver(score,this->GetIQHint(score));
this->ResetGame();
}
}
counter++;
lcd->display((double)counter/100);
if(counter%500==0)//每五秒提升一次速度
{
speed+=1;
}
if(counter%1000==0)//每十秒缩小有效范围
{
NarrowValidRect(&this->validRect);
}
}
void ReactionGame::ResetGame()//重置游戏
{
timer->stop();
this->inilizetionGame();
this->update();
}
void ReactionGame::CalculatePos(BlockAttr *block)//计算位置
{
int x=block->point.x();
int y=block->point.y();
if(x==0)
{
block->xDecrease=false;
}else if(x+block->pixmap.width()==this->width())
{
block->xDecrease=true;
}
if(y==0)
{
block->yDecrease=false;
}else if(y+block->pixmap.width()==this->height())
{
block->yDecrease=true;
}
if(block->xDecrease)
{
block->point.setX(x-factor);
}else
{
block->point.setX(x+factor);
}
if(block->yDecrease)
{
block->point.setY(y-factor);
}else
{
block->point.setY(y+factor);
}
}
const QString ReactionGame::GetIQHint(const float score)
{
if(score<20)
return tr("Haha, oh you only for fuck off!! As relatively cool *_*");//哈哈,你只适合打飞机哦!!那样比较爽..
else if(score>20&&score<=30)
return tr("Hey. Your life can only do a cannon fodder! -_-!");//哎...你的人生只能做炮灰了!
else if(score>30&&score<=40)
return tr("Wow! Is designed to play the pieces of the original idol Oh! :)");//哇!原来是专门打残局的偶像哦!:)
else if(score>40)
return tr("You'll never who they think are cheating! Or face it! :(");//你一辈子都被他们认为是作弊的!还是面对现实吧! :(
}
bool ReactionGame::HasCollide(const BlockAttr *staticBlock, const BlockAttr *dynamicBlock)//是否产生碰撞
{
QPoint staticCenter(staticBlock->point.x()+staticBlock->pixmap.width()/2,staticBlock->point.y()+staticBlock->pixmap.height()/2);//计算中心点
QPoint dynamicCenter(dynamicBlock->point.x()+dynamicBlock->pixmap.width()/2,dynamicBlock->point.y()+dynamicBlock->pixmap.height()/2);
int staticWidth=staticBlock->pixmap.width();//计算矩形宽度和高度
int staticHeiget=staticBlock->pixmap.height();
int dynamicWidth=dynamicBlock->pixmap.width();
int dynamicHeight=dynamicBlock->pixmap.height();
int xDistance=abs(staticCenter.x()-dynamicCenter.x());//计算。两个矩形中心点的距离
int yDistance=abs(staticCenter.y()-dynamicCenter.y());
if((staticWidth+dynamicWidth)/2>=xDistance&&(staticHeiget+dynamicHeight)/2>=yDistance)//计算是否产生碰撞
{
return true;
}
return false;
}
bool ReactionGame::CheckValidBound(const BlockAttr *block)//验证是否在有效范围
{
QPoint blockCenter(block->point.x()+block->pixmap.width()/2,block->point.y()+block->pixmap.height()/2);//计算中心点
QPoint rectCenter(validRect.x()+validRect.width()/2,validRect.y()+validRect.height()/2);
int xDistance=validRect.width()/2;//计算中心到无效区域的距离
int yDistance=validRect.height()/2;
if(abs(blockCenter.x()-rectCenter.x())+block->pixmap.width()/2-2>=xDistance||abs(blockCenter.y()-rectCenter.y())+block->pixmap.height()/2-2>=yDistance)
{
return false;
}
return true;
}
void ReactionGame::NarrowValidRect(QRect *rect)//缩小矩形
{
int narrowFactor=10;
rect->setX(rect->x()+narrowFactor);
rect->setY(rect->y()+narrowFactor);
rect->setWidth(rect->width()-narrowFactor);
rect->setHeight(rect->height()-narrowFactor);
}