Qt貪喫蛇

/**
2018年6月19日
我開始想qt大作業項目作什麼後來準備做了這個小遊戲
這個小遊戲比較簡單由於我也是初學者所以我找了部分代碼來對做參考
我主要完成的部分是後面的GameWidget.cpp和mainWidget.cpp的內容
其他的部分我主要參看了網上的源碼。
*/


#ifndef GAMEWIDGET_H
#define GAMEWIDGET_H

#include <QWidget>
#include <QPalette>
#include <QIcon>
#include <QPushButton>
#include <QPainter>
#include <QDebug>
#include <QTime>
#include <QTimer>
#include <QMessageBox>
#include <QKeyEvent>
#include <QLabel>
#include <QFont>
#include <QSound>
class GameWidget : public QWidget
{
    Q_OBJECT
public:
    explicit GameWidget(QWidget *parent = 0);
    ~GameWidget();
    void paintEvent(QPaintEvent *);
    void keyPressEvent(QKeyEvent *);
private:
    QPushButton *upbtn;
    QPushButton *leftbtn;
    QPushButton *downbtn;
    QPushButton *rightbtn;
    QPushButton *startbtn;
    QPushButton *returnbtn;
    int direction;
    int snake[100][2];
    int snake1[100][2];
    int foodcount;
    QTimer *timer;
    int foodx,foody;
    int score;
    int level;
    QLabel *scorelabel;
    QLabel *levellabel;
    QLabel *scoreshow;
    QLabel *levelshow;
    QString str1,str2;
    QSound *sound;
    QSound *sound1;
signals:
    void UpSignal();
    void DownSignal();
    void LeftSignal();
    void RightSignal();
public slots:
    void upbtnSlot();
    void leftbtnSlot();
    void rightbtnSlot();
    void downbtnSlot();
    void startbtnSlot();
    void returnbtnSlot();
    void timeoutSlot();
};

#endif // GAMEWIDGET_H
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include "GameWidget.h"
#include <QWidget>
#include <QIcon>
#include <QPalette>
#include <QBrush>
#include <QPixmap>
#include <QPushButton>
#include <QMessageBox>
#include <QLabel>
#include <QFont>
class mainWidget : public QWidget
{
    Q_OBJECT

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();
    //void resizeEvent(QResizeEvent *);
private:
    QPushButton *startbtn;
    QPushButton *exitbtn;
    GameWidget *g;
    QLabel *label;
signals:
public slots:
    void exitSlot();
    void startSlot();
};

#endif // MAINWIDGET_H
#include "GameWidget.h"
#define ROW 13
#define COL 16
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
GameWidget::GameWidget(QWidget *parent) : QWidget(parent)
{
    //界面的生成
    //調用圖片對遊戲加成
    this->setAutoFillBackground(true);
    this->setWindowTitle("遊戲開始");
    this->setWindowIcon(QIcon(":/new/prefix1/img/1.png"));
    this->resize(480,270);
    this->setMaximumSize(480,270);
    QPalette palette;
    palette.setBrush(QPalette::Background,QBrush(QPixmap(":/new/prefix1/img/green.jpg").scaled(this->size())));
    this->setPalette(palette);
    //聲音區
    sound=new QSound(":/listen/img/5611.wav");
    sound1=new QSound(":/listen/img/die.wav");
    //按鈕區
    upbtn=new QPushButton("↑",this);
    upbtn->setGeometry(QRect(380,90,40,30));

    leftbtn=new QPushButton("←",this);
    leftbtn->setGeometry(QRect(340,130,40,30));

    rightbtn=new QPushButton("→",this);
    rightbtn->setGeometry(QRect(420,130,40,30));

    downbtn=new QPushButton("↓",this);
    downbtn->setGeometry(QRect(380,170,40,30));

    startbtn=new QPushButton("開始",this);
    startbtn->setGeometry(QRect(350,220,40,30));

    returnbtn=new QPushButton("返回",this);
    returnbtn->setGeometry(QRect(410,220,40,30));

    //設置分數等級爲0
    score=0;
    level=0;
    //顯示分數等級標籤區
    QFont font;
    font.setFamily("Consolas");
    font.setBold(true);
    font.setPixelSize(19);

    scorelabel=new QLabel("分數:",this);
    scorelabel->setFont(font);
    scorelabel->setGeometry(QRect(325,1,60,30));

    levellabel=new QLabel("等級:",this);
    levellabel->setFont(font);
    levellabel->setGeometry(QRect(325,30,60,30));

    str1=QString::number(score);
    str2=QString::number(level);

    scoreshow=new QLabel(this);
    scoreshow->setFont(font);
    scoreshow->setGeometry(QRect(385,1,60,30));
    scoreshow->setText(str1);

    levelshow=new QLabel(this);
    levelshow->setFont(font);
    levelshow->setGeometry(QRect(385,30,60,30));
    levelshow->setText(str2);
    //設置按鈕操作
    connect(leftbtn,SIGNAL(clicked()),this,SLOT(leftbtnSlot()));
    connect(rightbtn,SIGNAL(clicked()),this,SLOT(rightbtnSlot()));
    connect(upbtn,SIGNAL(clicked()),this,SLOT(upbtnSlot()));
    connect(downbtn,SIGNAL(clicked()),this,SLOT(downbtnSlot()));
    connect(startbtn,SIGNAL(clicked()),this,SLOT(startbtnSlot()));
    connect(returnbtn,SIGNAL(clicked()),this,SLOT(returnbtnSlot()));
    //設置鍵盤操作
    connect(this,SIGNAL(UpSignal()),upbtn,SLOT(click()));
    connect(this,SIGNAL(DownSignal()),downbtn,SLOT(click()));
    connect(this,SIGNAL(LeftSignal()),leftbtn,SLOT(click()));
    connect(this,SIGNAL(RightSignal()),rightbtn,SLOT(click()));
    foodcount=0;
    //設置隨機數(爲了食物出現的位置)
    int i=1;
    QTime t;
    t= QTime::currentTime();
    qsrand(t.msec()+t.second()*1000);
    snake[0][0]=qrand()%COL;
    snake[0][1]=qrand()%ROW;
    foodx=qrand()%COL;
    foody=qrand()%ROW;
    direction=qrand()%4;
    while(i)
    {
        if(snake[0][0]==foodx&&snake[0][1]==foody)
        {
            foodx=qrand()%COL;
            foody=qrand()%ROW;
            i=1;
        }
        else
            i=0;
    }
    timer=new QTimer(this);
    timer->setInterval(500);
    connect(timer,SIGNAL(timeout()),this,SLOT(timeoutSlot()));

}

GameWidget::~GameWidget()
{
    delete startbtn;
    delete returnbtn;
    delete leftbtn;
    delete rightbtn;
    delete upbtn;
    delete downbtn;
    delete timer;
    delete sound;
    delete sound1;
}
void GameWidget::upbtnSlot()
{
    if(direction==DOWN)
        return;
    else
    {
    direction=UP;
    }
}

void GameWidget::downbtnSlot()
{
    if(direction==UP)
        return;
    else
    {
   direction=DOWN;
    }
}

void GameWidget::leftbtnSlot()
{
    if(direction==RIGHT)
        return;
    else
    {
    direction=LEFT;
    }
}

void GameWidget::rightbtnSlot()
{
    if(direction==LEFT)
        return;
    else
    {
    direction=RIGHT;
    }
}

void GameWidget::startbtnSlot()
{
    timer->start();
}

void GameWidget::returnbtnSlot()
{
    delete this;
}

void GameWidget::timeoutSlot()
{
    //判斷是否知道食物
   if(snake[0][0]==foodx&&snake[0][1]==foody)
    {
       //喫到食物發出聲音
       sound->play();
        //如果喫到食物,食物座標更新
       int i=0;
        foodcount++;
        score++;
        str1=QString::number(score);
        scoreshow->setText(str1);
        QTime t;
        t= QTime::currentTime();
        qsrand(t.msec()+t.second()*1000);
        foodx=qrand()%COL;
        foody=qrand()%ROW;
        while(i<=foodcount)
        {
            i++;
            //判斷食物是否出現在蛇身上,如果出現在蛇身上重新產生食物
            if(snake[i][0]==foodx&&snake[i][1]==foody)
            {
                foodx=qrand()%COL;
                foody=qrand()%ROW;
                i=0;
            }
        }
        switch(score)
        {
        case 10:timer->setInterval(350);level++;break;
        case 20:timer->setInterval(250);level++;break;
        case 30:timer->setInterval(150);level++;break;
        }
        str2=QString::number(level);
        levelshow->setText(str2);
    }
    memcpy(snake1,snake,sizeof(snake));
    //實現蛇的遊動
    for(int i=foodcount;i>=1;i--)
    {
        snake[i][0]=snake[i-1][0];
        snake[i][1]=snake[i-1][1];
    }

    switch(direction)
    {
    case UP:snake[0][1]--;break;
    case DOWN:snake[0][1]++;break;
    case LEFT:snake[0][0]--;break;
    case RIGHT:snake[0][0]++;break;
    }
    //判斷蛇是否撞到自身
    for(int i=1;i<=foodcount;i++)
    {


        if(snake[0][0]==snake[i][0]&&snake[0][1]==snake[i][1])
        {
            sound1->play();
            memcpy(snake,snake1,sizeof(snake));
            timer->stop();
            if(QMessageBox::question(this,"提示","遊戲結束,是否重新遊戲",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
               {
                QTime t;
                int i;
                t= QTime::currentTime();
                qsrand(t.msec()+t.second()*1000);
                snake[0][0]=qrand()%COL;
                snake[0][1]=qrand()%ROW;
                direction=qrand()%4;
                foodx=qrand()%COL;
                foody=qrand()%ROW;
                while(i)
                {
                    if(snake[0][0]==foodx&&snake[0][1]==foody)
                    {
                        foodx=qrand()%COL;
                        foody=qrand()%ROW;
                        i=1;
                    }
                    else
                        i=0;
                }
                foodcount=0;
                score=0;
                level=0;

                str1=QString::number(score);
                str2=QString::number(level);
                scoreshow->setText(str1);
                levelshow->setText(str2);
               }
            return;
        }
    }
    //判斷蛇是否撞到牆體
    if(snake[0][0]<0||snake[0][0]>=COL||snake[0][1]<0||snake[0][1]>=ROW)
    {
        sound1->play();
        memcpy(snake,snake1,sizeof(snake));
       timer->stop();
       if(QMessageBox::question(this,"提示","遊戲結束,是否重新遊戲",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
          {
           QTime t;
           int i;
           t= QTime::currentTime();
           qsrand(t.msec()+t.second()*1000);
           snake[0][0]=qrand()%COL;
           snake[0][1]=qrand()%ROW;
           direction=qrand()%4;
           foodx=qrand()%COL;
           foody=qrand()%ROW;
           while(i)
           {
               if(snake[0][0]==foodx&&snake[0][1]==foody)
               {
                   foodx=qrand()%COL;
                   foody=qrand()%ROW;
                   i=1;
               }
               else
                   i=0;
           }
           foodcount=0;
           score=0;
           level=0;

           str1=QString::number(score);
           str2=QString::number(level);
           scoreshow->setText(str1);
           levelshow->setText(str2);
          }
       else
        {
           delete this;
           return ;
        }

    }
    this->update();
}
//在畫蛇的這一方面我更多的參考了源碼,因爲比較麻煩,所以我參考了更多的源代碼
 void GameWidget::paintEvent(QPaintEvent *)
{
    //畫方格 
    QPainter painter(this);
    for(int i=0;i<ROW*20;i+=20)
        for(int j=0;j<COL*20;j+=20)
        painter.drawRect(j,i,20,20);
    //畫食物
    painter.drawImage(foodx*20,foody*20,QImage(":/new/prefix1/img/apple.png").scaled(QSize(20,20)));
    //畫蛇頭

    switch(direction)
    {
    case UP:painter.drawImage(snake[0][0]*20,snake[0][1]*20,QImage(":/new/prefix1/img/headup.png").scaled(QSize(20,20)));break;//蛇頭向上
    case DOWN:painter.drawImage(snake[0][0]*20,snake[0][1]*20,QImage(":/new/prefix1/img/headdown.png").scaled(QSize(20,20)));break;//蛇頭向下
    case LEFT:painter.drawImage(snake[0][0]*20,snake[0][1]*20,QImage(":/new/prefix1/img/headleft.png").scaled(QSize(20,20)));break;//蛇頭向下
    case RIGHT:painter.drawImage(snake[0][0]*20,snake[0][1]*20,QImage(":/new/prefix1/img/headright.png").scaled(QSize(20,20)));break;//蛇頭向下
    }


    //畫蛇身
    for(int i=1;i<=foodcount;i++)
    {
        if(i!=foodcount)
        {
        if((snake[i][0]==snake[i-1][0]&&snake[i][1]==snake[i-1][1]-1&&
           snake[i][0]==snake[i+1][0]-1&&snake[i][1]==snake[i+1][1])||
           (snake[i][0]==snake[i-1][0]-1&&snake[i][1]==snake[i-1][1]&&
            snake[i][0]==snake[i+1][0]&&snake[i][1]==snake[i+1][1]-1))
         painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/tl_corner.png").scaled(QSize(20,20)));
        else if((snake[i][0]==snake[i-1][0]-1&&snake[i][1]==snake[i-1][1]&&
                 snake[i][0]==snake[i+1][0]&&snake[i][1]==snake[i+1][1]+1)||
                 (snake[i][0]==snake[i-1][0]&&snake[i][1]==snake[i-1][1]+1&&
                  snake[i][0]==snake[i+1][0]-1&&snake[i][1]==snake[i+1][1]))
         painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/bl_corner.png").scaled(QSize(20,20)));
        else if((snake[i][0]==snake[i-1][0]+1&&snake[i][1]==snake[i-1][1]&&
                 snake[i][0]==snake[i+1][0]&&snake[i][1]==snake[i+1][1]-1)||
                 (snake[i][0]==snake[i-1][0]&&snake[i][1]==snake[i-1][1]-1&&
                  snake[i][0]==snake[i+1][0]+1&&snake[i][1]==snake[i+1][1]))
         painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/tr_corner.png").scaled(QSize(20,20)));
        else if((snake[i][0]==snake[i-1][0]&&snake[i][1]==snake[i-1][1]+1&&
                 snake[i][0]==snake[i+1][0]+1&&snake[i][1]==snake[i+1][1])||
                 (snake[i][0]==snake[i-1][0]+1&&snake[i][1]==snake[i-1][1]&&
                  snake[i][0]==snake[i+1][0]&&snake[i][1]==snake[i+1][1]+1))
         painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/br_corner.png").scaled(QSize(20,20)));
        else if(snake[i][1]==snake[i-1][1]&&snake[i][0]!=snake[i-1][0])
       painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/h_body.png").scaled(QSize(20,20)));
        else if(snake[i][0]==snake[i-1][0]&&snake[i][1]!=snake[i-1][1])
         painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/v_body.png").scaled(QSize(20,20)));
        }
        else
        {
            //畫蛇尾
            if(snake[i][0]==snake[i-1][0]+1&&snake[i][1]==snake[i-1][1])
                painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/tailleft.png").scaled(QSize(20,20)));
            else if(snake[i][0]==snake[i-1][0]-1&&snake[i][1]==snake[i-1][1])
                painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/tailright.png").scaled(QSize(20,20)));
            else if(snake[i][0]==snake[i-1][0]&&snake[i][1]==snake[i-1][1]-1)
                painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/taildown.png").scaled(QSize(20,20)));
             else if(snake[i][0]==snake[i-1][0]&&snake[i][1]==snake[i-1][1]+1)
                painter.drawImage(snake[i][0]*20,snake[i][1]*20,QImage(":/new/prefix1/img/tail.png").scaled(QSize(20,20)));
        }
    }
}
void GameWidget::keyPressEvent(QKeyEvent *k)
{
  int key = k->key();
  if(key==87)
  {
      //if(direction==DOWN)
          //return ;
     // else
      //direction=UP;
      emit UpSignal();
  }
  else if(key==83)
  {
      /*if(direction==UP)
          return;
      else
      direction=DOWN;*/
      emit DownSignal();
  }
  else if(key==65)
  {
      /*if(direction==RIGHT)
          return;
      else
      direction=LEFT;*/
      emit LeftSignal();
  }
  else if(key==68)
  {
      /*if(direction==LEFT)
          return;
      else
      direction=RIGHT;*/
      emit RightSignal();
  }
}



#include "mainWidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    mainWidget w;
    w.show();
    return a.exec();
}

#include "mainWidget.h"

mainWidget::mainWidget(QWidget *parent)
    : QWidget(parent)
{
    this->resize(480,270);
    this->setMaximumSize(480,270);
    this->setWindowIcon(QIcon(":/new/prefix1/img/icon.png"));
    this->setWindowTitle("貪喫蛇");
    QPalette palette;
    palette.setBrush(QPalette::Background,QBrush(QPixmap(":/new/prefix1/img/back.jpg").scaled(this->size())));
    this->setPalette(palette);

    startbtn=new QPushButton(this);
    startbtn->setIcon(QIcon(":/new/prefix1/img/start.png"));
    startbtn->setIconSize(QSize(75,75));
    startbtn->setGeometry(QRect(250,170,75,75));
    startbtn->setFlat(true);

    exitbtn=new QPushButton(this);
    exitbtn->setIcon(QIcon(":/new/prefix1/img/quit.png"));
    exitbtn->setIconSize(QSize(70,70));
    exitbtn->setGeometry(QRect(350,170,70,70));
    exitbtn->setFlat(true);
    //設置說明標籤
    QFont font;
    font.setFamily("Consolas");
    font.setBold(true);
    font.setPixelSize(13);
    label=new QLabel(this);
    label->setText("遊戲說明:貪喫蛇遊戲可使用按鈕或者使用WSAD控制蛇的走動");
    label->setFont(font);
    label->setGeometry(QRect(10,10,400,50));

    connect(exitbtn,SIGNAL(clicked()),this,SLOT(exitSlot()));
    connect(startbtn,SIGNAL(clicked()),this,SLOT(startSlot()));
}

mainWidget::~mainWidget()
{
    delete startbtn;
    delete exitbtn;
}
void mainWidget::exitSlot()
{
    if(QMessageBox::question(this,"退出遊戲","是否退出當前遊戲",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes)
    {
        delete this;
        exit(0);
    }
}
void mainWidget::startSlot()
{

    g=new GameWidget(this);
    g->show();
}
//重寫resizeEvent
/*void mainWidget::resizeEvent(QResizeEvent *)
{
    QPalette palette;
    palette.setBrush(QPalette::Background,QBrush(QPixmap("img/back.jpg").scaled(this->size())));
    this->setPalette(palette);
    startbtn->setGeometry(QRect(this->size().width()-230,this->size().height()-100,75,75));
    exitbtn->setGeometry(QRect(this->size().width()-130,this->size().height()-100,70,70));
}*/




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章