QT写的反应测试游戏源码

10 篇文章 0 订阅
9 篇文章 1 订阅
#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);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值