首页 > 其他 > 详细

Qt版贪吃蛇游戏

时间:2015-02-27 21:36:05      阅读:425      评论:0      收藏:0      [点我收藏+]

   Qt版贪吃蛇游戏

转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907

       最近在学习Qt,用了一个多月的时间掌握了Qt中最基本的知识,也完成了《Qt版音乐播放器》、《Qt版贪吃蛇游戏》、《Qt版双人俄罗斯方块》以及《Qt版科学计算器》等,之前在VC下写过这些程序,所以在Qt下只是改变了显示等语句,我写过《C++版贪吃蛇游戏》、《VC版贪吃蛇游戏》,当时将与显示等无关的东西封装起来,在Qt下直接用,只改变了显示等语句。

以下是Windows 7下运行截图:

技术分享

以下是Ubuntu下运行截图:

技术分享


       我在Windows下编写好之后,将源码在Ubuntu下重新编译运行,就可以在Ubuntu下运行,这也充分体现出Qt一次编写,到处运行的优势。

       关于贪吃蛇游戏的设计原理就不讲了,具体可以参考我的博客《C++版贪吃蛇游戏》、《VC版贪吃蛇游戏》。

       下面主要说一下Qt与VC不同的东西。

先看头文件中变量以及槽的定义:

class Snake : public QMainWindow
{
    Q_OBJECT

public:
    explicit Snake(QWidget *parent = 0);
    ~Snake();
private slots:
    void gameStart();
    void onPause();
    void superSpeed();
    void fastSpeed();
    void midSpeed();
    void slowSpeed();
    void verySlowSpeed();
private:
    Ui::Snake *ui;

    int image[20][20];        //游戏面板,即小蛇活动范围
    int FoodX;                //事物出现的X坐标
    int FoodY;                //事物出现的Y坐标
    int snakeX;               //记录小蛇的头部X坐标
    int snakeY;               //记录小蛇的头部Y坐标
    int head;                 //小蛇头部下标
    int tail;                 //小蛇尾部下标
    int snake[2][20000];         //记录小蛇所有身体的坐标
    int node;                 //小蛇的节数
    int direction;            //小蛇头部的方向
    int i,j;
    int gamespeed;            //速度
    int score;                //记录分数
    bool IsPause;            //暂停
    bool p;
    int GameOver;             //使游戏结束的变量
    int level;                //设置等级
    int length;               //为了设置等级而与node一样记录设的长度

    int timerID;
    /////////////


    void ReInit();
    int  DrawSnake();           //记录小蛇每次移动后头部及身体的下一坐标
    void Automove();            //使小蛇自动移动
    int  Gameover();            //判断游戏是否结束
    int  Generatefood();        //产生食物
    void shiftLeft();           //控制左移
    void shiftRight();          //控制右移
    void shiftDown();           //控制下移
    void shiftUp();	        //控制上移

protected:
    void keyPressEvent(QKeyEvent  *event);
    void timerEvent(QTimerEvent *event);
    void paintEvent(QPaintEvent *event);
};


不同的只是
    void keyPressEvent(QKeyEvent  *event);
    void timerEvent(QTimerEvent *event);
    void paintEvent(QPaintEvent *event);
三个槽的实现是Qt的方式。

转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907

具体代码如下:

/////////////////////////////////////////////

void Snake::keyPressEvent(QKeyEvent *event)
{
   if(direction == 2 || direction == 8)
   {
       if(event->key() == Qt::Key_Right)
           shiftRight();
       else if(event->key() == Qt::Key_Left)
           shiftLeft();
       else if(event->key() == Qt::Key_0)
           onPause();

   }
   else if(direction == 4 || direction == 6)
   {
       if(event->key() == Qt::Key_Up)
           shiftUp();
       else if(event->key() == Qt::Key_Down)
           shiftDown();
       else if(event->key() == Qt::Key_0)
           onPause();
   }
}

void Snake::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == timerID)
    {
        if(!GameOver)
        {
            if(!IsPause)
                Automove();			              // 小蛇自动移动
            Gameover();                                       //判断游戏是否结束
            if(GameOver==1)
            {
                killTimer(timerID);

                if(level>8)
                    if(QMessageBox::question(this,tr("提示"),tr("你一定是骨灰级玩家!小弟佩服!还想挑战吗?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)
                    {
                        ReInit();
                        gameStart();
                    }
                    else
                        close();
                else if(level>5)
                    if(QMessageBox::question(this,tr("提示"),tr("你一定是高手!还想挑战吗?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)
                    {
                        ReInit();
                        gameStart();
                    }
                    else
                        close();
                else if(QMessageBox::question(this,tr("提示"),tr("继续努力!还想挑战吗?"),QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)
                {
                    ReInit();
                    gameStart();
                }
                else
                    close();
            }
            DrawSnake();      //判断是否吃食物
        }
        this->repaint();
    }
}

void Snake::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    int nSize = 20;
    int offset = 1;
    QImage img;
    img.load(":/images/border.png");
    QBrush brushborder(img);
    painter.setBrush(brushborder);

    QRect bottomrec(0,nSize*22+offset,nSize*22,nSize);
    painter.fillRect(bottomrec,brushborder);

    QRect toprec(0,20+offset,nSize*22,nSize);
    painter.fillRect(toprec,brushborder);

    QRect leftrec(0,20+offset,nSize,nSize*21);
    painter.fillRect(leftrec,brushborder);

    QRect rightrec(nSize*21,20+offset,nSize,nSize*21);
    painter.fillRect(rightrec,brushborder);


    QRect rect(20,40+offset,nSize*20,nSize*20);
    QImage imageBack;
    imageBack.load(":/images/grass.png");
    QBrush brushBack(imageBack);
    painter.setBrush(brushBack);
    painter.drawRect(rect);

    QRect rc;
    QBrush brush(QColor(255,0,0));
    painter.setBrush(brush);

    QString Level = "Level:";
    Level += QString::number(level);
    ui->label_Level->setText(Level);

    QString Score = "Score:";
    Score += QString::number(score);
    ui->label_Score->setText(Score);

    for(i=0;i<20;i++)
    {
        for(j=0;j<20;j++)
        {
            rc = QRect(j*nSize+20,i*nSize+40+offset,nSize,nSize);
            if(image[i][j]!=0)
            {
                if(image[i][j]==3)
                {
                    QImage img;
                    img.load(":/images/body.png");
                    QBrush brush(img);
                    painter.setBrush(brush);
                    painter.fillRect(rc,brush);
                }
                else if(image[i][j] == 1)
                {
                    if(direction==2)
                    {
                        QImage img;
                        img.load(":/images/headdown.png");
                        QBrush brush(img);
                        painter.setBrush(brush);
                        painter.fillRect(rc,brush);
                    }
                    else if(direction == 4)
                    {
                        QImage img;
                        img.load(":/images/headleft.png");
                        QBrush brush(img);
                        painter.setBrush(brush);
                        painter.fillRect(rc,brush);
                    }
                    else if(direction == 6)
                    {
                        QImage img;
                        img.load(":/images/headright.png");
                        QBrush brush(img);
                        painter.setBrush(brush);
                        painter.fillRect(rc,brush);
                    }
                    else
                    {
                        QImage img;
                        img.load(":/images/headup.png");
                        QBrush brush(img);
                        painter.setBrush(brush);
                        painter.fillRect(rc,brush);
                    }

                }
                else if(image[i][j] == 2)
                {
                    QImage img;
                    img.load(":/images/apple.png");
                    QBrush brush(img);
                    painter.setBrush(brush);
                    painter.fillRect(rc,brush);
                }
            }

        }
    }
}

//////////////////////////////////////////////////////////////////////


还有一个是按键响应的信号和槽建立关联代码:

/////////////////////////////////////////
    connect(ui->action_startGame, SIGNAL(triggered()), this, SLOT(gameStart()));
    connect(ui->action_pause, SIGNAL(triggered()) ,this,  SLOT(onPause()));
    connect(ui->action_quit, SIGNAL(triggered()), this, SLOT(close()));

    connect(ui->action_veryFast, SIGNAL(triggered()), this, SLOT(superSpeed()));
    connect(ui->action_fast, SIGNAL(triggered()), this, SLOT(fastSpeed()));
    connect(ui->action_mid, SIGNAL(triggered()), this, SLOT(midSpeed()));
    connect(ui->action_slow, SIGNAL(triggered()), this, SLOT(slowSpeed()));
    connect(ui->action_verySlow, SIGNAL(triggered()), this, SLOT(verySlowSpeed()));

还有一个小细节就是随机函数:qsrand() 用于产生食物的位置:

//产生食物
int  Snake::Generatefood()
{
    qsrand(QTime::currentTime().msec());                          //以时间为种子生成随机序列
    do{
        FoodX=qrand()%20;                                         //食物输出的X坐标
        FoodY=qrand()%20;                                         //食物输出的Y坐标
    }while(image[FoodX][FoodY]!=0);                               //产生的食物坐标限定在游戏面板内,且食物坐标不与小蛇身体坐标重合
    image[FoodX][FoodY]=2;
    return image[FoodX][FoodY];
}


转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907

Qt版贪吃蛇游戏

原文:http://blog.csdn.net/u012027907/article/details/43970135

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!