用QT编写的贪吃蛇程序

初次学习QT,用C++和QT写了个贪吃蛇小程序,主要是用链表实现的,第一次写博客留作纪念,请大家指教。
mainwindous.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "snake.h"
#include 

namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void snakeshow();
    void newgame();
    void foodshow();
    void inifood();
    void drawrect();
 protected:
    void paintEvent(QPaintEvent*);
    void timerEvent(QTimerEvent*e);
    void keyPressEvent(QKeyEvent *event);
    snake* m_snake;
    food* m_food;
    snakecontrol* m_snakecontrol;
 private:
    Ui::MainWindow *ui;
    int m_nTimerId;
    int m_nspeed;
    int m_nscores;
 };

mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include "qevent.h"
#include "qmessagebox.h"
#include "qwindowdefs.h"
#include 
#define RECT_COLUMES 35
#define RECT_ROWS  20
#define RECT_WIDTH  40
#define RECT_HEIGHT  40
#define CONTRL_WIDTH 400  //控制区域宽度
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    ui->mainToolBar->hide();
    ui->mainToolBar->hide();
    resize(RECT_COLUMES*RECT_WIDTH + CONTRL_WIDTH, RECT_ROWS*RECT_HEIGHT);
    m_snakecontrol = new snakecontrol(this);
    m_snakecontrol->setGeometry(RECT_COLUMES*RECT_WIDTH, 0, CONTRL_WIDTH,      RECT_ROWS*RECT_HEIGHT);
    m_snake = new snake;
    m_nspeed = 1;
    m_nscores = 0;
    newgame();
    }
    MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::snakeshow()
{
    QPainter painter(this);
    painter.setBrush(Qt::darkBlue);
    painter.setPen(QPen(QColor(Qt::black),2));
    SNAKE* pta /*= new SNAKE*/;
    pta = m_snake->m_header;
    while (pta!= NULL)
   {
    painter.drawRect(pta->node.x(), pta->node.y(), RECT_WIDTH, RECT_HEIGHT);
    pta = pta->next;
   }
 }
 void MainWindow::paintEvent(QPaintEvent *)
{
 drawrect();
    snakeshow();
 foodshow();
 update();
}
void MainWindow::timerEvent(QTimerEvent *e)
{
   if (e->timerId() ==m_nTimerId)
   {
       m_snake->snakemove();
       SNAKE* pt = m_snake->m_header;
       SNAKE* saved = m_snake->m_header;
       while (saved->next!= NULL)
       {
          if (pt->node == saved->next->node) //撞到自己
          {
             QMessageBox::information(NULL, "GAME OVER", "GAME OVER", QMessageBox::Yes,     QMessageBox::Yes);
             newgame();
             return;
           }
           if (pt->node.x() >=(RECT_COLUMES-1)*RECT_WIDTH  || pt->node.x()< RECT_WIDTH)//撞到边界
           {
              QMessageBox::information(NULL, "GAME OVER", "GAME OVER", QMessageBox::Yes, QMessageBox::Yes);
              newgame();
              return;
           }
           if (pt->node.y() >= (RECT_ROWS-1)*RECT_HEIGHT || pt->node.y() < RECT_HEIGHT)//撞到边界
           {
               QMessageBox::information(NULL, "GAME OVER", "GAME OVER", QMessageBox::Yes, QMessageBox::Yes);
               newgame();
               return;
           }
           saved = saved->next;
       }
     if (m_snake->m_header->node == m_food->Food->node) //吃食物
     {
        SNAKE* pa = new SNAKE;
        switch (m_snake->m_header->dir)
        {
        case left:
	    pa->node.setX(m_food->Food->node.x()- RECT_WIDTH);
	    pa->node.setY(m_food->Food->node.y());
	    pa->next = m_snake->m_header;
	    pa->dir = left;
	    m_snake->m_header = pa;
	    m_food->Food->flag = true;
	    m_food->nextfood(m_snake->m_header);
	    break;
	case right:
	    pa->node.setX(m_food->Food->node.x() + RECT_WIDTH);
	    pa->node.setY(m_food->Food->node.y());
	    pa->next = m_snake->m_header;
	    pa->dir = right;
	    m_snake->m_header = pa;
	    m_food->Food->flag = true;
	    m_food->nextfood(m_snake->m_header);
	    break;
        case up:
	    pa->node.setX(m_food->Food->node.x());
	    pa->node.setY(m_food->Food->node.y()- RECT_WIDTH);
	    pa->next = m_snake->m_header;
	    pa->dir = up;
	    m_snake->m_header = pa;
	    m_food->Food->flag = true;
	    m_food->nextfood(m_snake->m_header);
	    break;      
        case down:
	    pa->node.setX(m_food->Food->node.x());
	    pa->node.setY(m_food->Food->node.y() + RECT_WIDTH);
	    pa->next = m_snake->m_header;
	    pa->dir=down;
	    m_snake->m_header = pa;
	    m_food->Food->flag = true;
	    m_food->nextfood(m_snake->m_header);
	    break;	        
        }
	    m_nscores = m_nscores + 1;
	    m_snakecontrol->setscores(m_nscores);
     }
     }
}

void MainWindow::newgame()
{
 if (m_snake->m_header->next != NULL)
	  delete m_snake;
    m_snake = new snake(7)
    m_nscores = 0  
    inifood();
    m_nTimerId = startTimer((11 - m_nspeed) * 100);
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
 {
 case  Qt::Key_Left:
  if (m_snake->m_header->dir != right)
  {
   m_snake->m_header->dir = left;
  }
  break;
 case Qt::Key_Right:
  if (m_snake->m_header->dir != left)
  {
   m_snake->m_header->dir = right;
  }
  break;
  case Qt::Key_Up:
  if (m_snake->m_header->dir != down)
  {
   m_snake->m_header->dir = up;
  }
  break;
 case  Qt::Key_Down:
  if (m_snake->m_header->dir != up)
  {
   m_snake->m_header->dir = down;
  }
  break;
  case Qt::Key_Equal:
  if (m_nspeed < 10 && m_nspeed > 0)
  {
    m_nspeed = m_nspeed + 1;
    m_snakecontrol->setspeed(m_nspeed);
    m_nTimerId = startTimer((11 - m_nspeed) * 100);
  }
  break;
 case Qt::Key_Minus:
  if (m_nspeed <= 10 && m_nspeed >= 0)
  {
   m_nspeed = m_nspeed - 1;
   m_snakecontrol->setspeed(m_nspeed);
   m_nTimerId = startTimer((11 - m_nspeed) * 100);
  }
  break;
  }
}

void MainWindow::foodshow()
{
 QPainter pa(this);
 pa.setBrush(Qt::darkBlue);
 pa.setPen(QPen(QColor(Qt::black), 2));
 m_food->drawfood(pa);
}

void MainWindow::inifood()//食物不能出现在蛇身上
{
 m_food = new food;
 SNAKE* pa = m_snake->m_header;
 while (pa->next != NULL)
 {
  pa = pa->next;
  if (m_food->Food->node == pa->node)
  {
   delete m_food;
   inifood();
  }
 }
}

void MainWindow::drawrect()
{
 QPainter pa(this);
 pa.setBrush(Qt::green);
 pa.setPen(QPen(QColor(Qt::black), 2));
 for (int i = 0; i < RECT_COLUMES; i++)
 {
  for (int j = 0; j < RECT_ROWS; j++)
  {
   if (i == 0 || i == RECT_COLUMES - 1 || j == 0 || j == RECT_ROWS - 1)
   {
    pa.drawRect(i*RECT_WIDTH, j*RECT_HEIGHT, RECT_WIDTH, RECT_HEIGHT);
   }
  }
 }
}

snake.h

#ifndef SNAKE_H
#define SNAKE_H
#include 
#include 
typedef struct _food
{
    QPoint node;
    bool flag;
}FOOD;

typedef enum direction
{
    right =1,
    left = 2,
    up = 3,
    down = 4
}DIR;

ypedef struct _snake
{
    QPoint node;
    _snake* next;
    DIR dir;
}SNAKE;
class snake
{
public:
    snake();
 snake(int n);
 ~snake();
    void eatfood();
    void snakemove();
    public:
    SNAKE* m_header;
};

class food
 {
 public:
  food();
  ~food();
  void drawfood(QPainter& painter);
  void nextfood(SNAKE* Snake);
  public:
  FOOD* Food;
 };
 
#endif // SNAKE_H

snake.cpp

#include "snake.h"
#include 
#define RECT_WIDTH  40
#define RECT_HEIGHT  40
#define RECT_COLUMES 35
#define RECT_ROWS  20
snake::snake()
{
 m_header = new SNAKE;
 m_header->node.setX(RECT_WIDTH);
 m_header->node.setY(RECT_WIDTH);
 m_header->next = NULL;
 m_header->dir = right;
}

snake::snake(int n)
{
 m_header = new SNAKE;
 m_header->node.setX(RECT_WIDTH);
 m_header->node.setY(RECT_WIDTH);
 m_header->next = NULL;
 m_header->dir = right;
 for (int i = 2; i < n ; i++)
 {
  SNAKE* pa = new SNAKE;
  pa->node.setX(i * RECT_WIDTH);
  pa->node.setY(RECT_WIDTH);
  pa->dir = right;
  pa->next = m_header;
  m_header = pa;
 }
 }
snake::~snake()
{
 for ( ; m_header!= NULL;)
 {
  SNAKE* pa = m_header;
  m_header = m_header->next;
  delete pa;
 }
}
void snake::eatfood()
{
}

void snake::snakemove()
{
SNAKE* pt = new SNAKE;
switch (m_header->dir) {
  case right:
   pt->node.setX(m_header->node.x() + RECT_WIDTH);
   pt->node.setY(m_header->node.y());
   pt->dir = right;
   pt->next = m_header;
   break;
  case left:
   pt->node.setX(m_header->node.x() - RECT_WIDTH);
   pt->node.setY(m_header->node.y());
   pt->dir = left;
   pt->next = m_header;
   break;
   case up:
   pt->node.setX(m_header->node.x());
   pt->node.setY(m_header->node.y() - RECT_HEIGHT);
   pt->dir = up;
   pt->next = m_header;
   break;
  case down:
   pt->node.setX(m_header->node.x());
   pt->node.setY(m_header->node.y() + RECT_HEIGHT);
   pt->dir = down;
   pt->next = m_header;
   break;
   }
   m_header = pt;
  SNAKE* saved = m_header;
  while (true)
  {
   saved = saved->next;
   if (saved->next->next == NULL)
   {
    saved->next = NULL;
    delete saved->next;
    break;
   }
   //saved = saved->next;
  }
}
food::food()
{
 Food = new FOOD;
 qsrand(QTime::currentTime().msec());
 int columes =1 + qrand() % (RECT_COLUMES -2);
 int rowss =1 + qrand() % (RECT_ROWS -2);
 Food->node.setX(columes*RECT_WIDTH);
 Food->node.setY(rowss*RECT_WIDTH);
 Food->flag = false;
}	
food::~food()
{
 if (Food != NULL)
 {
  delete Food;
 }
}
void food::drawfood(QPainter& mpainter)
{
mpainter.drawRect(Food->node.x(), Food->node.y(), RECT_WIDTH, RECT_HEIGHT);
}
void food::nextfood(SNAKE* Snake)
{
if (Food->flag == true)
{
delete Food;
  Food = new FOOD;
  qsrand(QTime::currentTime().msec());
  int columes = 1 + qrand() % (RECT_COLUMES - 2);
  int rowss = 1 + qrand() % (RECT_ROWS - 2);
  Food->node.setX(columes*RECT_WIDTH);
  Food->node.setY(rowss*RECT_WIDTH);
  SNAKE* pa = Snake;
  while (pa->next != NULL)
  {
   pa = pa->next;
   if (Food->node == pa->node)
   {
    delete Food;
    nextfood(Snake);
   }
  }
  Food->flag = false;
}
}
snakecontrol.h

#ifndef SNAKECONTROL_H
#define SNAKECONTROL_H
include
#include
class snakecontrol : public QWidget
{
Q_OBJECT
public:
explicit snakecontrol(QWidget parent = 0);
public:
void setscores(int n);
void setspeed(int n);
void setnode(int n);
private:
QLabel
scores;
QLabel* m_pspeed;
QLabel* m_pnode;
};
#endif // SNAKECONTROL_H

snakecontrol.cpp

#include "snakecontrol.h"
#include 
snakecontrol::snakecontrol(QWidget *parent) : QWidget(parent)
{
QFont font;
 font.setPointSize(20);//设置字高
 font.setFamily(("msyh"));//设置字体
 QLabel* text = new QLabel(QStringLiteral("得分:"), this);
 text->setGeometry(50, 80, 200, 40);
 text->setFont(font);
 scores = new QLabel(QStringLiteral("0"), this);
 scores->setGeometry(150, 80, 200, 40);
 scores->setFont(font);
QLabel* text2 = new QLabel(QStringLiteral("速度:"), this);
 text2->setGeometry(50, 200, 200, 40);
 text2->setFont(font);
m_pspeed = new QLabel(QStringLiteral("1"), this);
 m_pspeed->setGeometry(150, 200, 200, 40);
 m_pspeed->setFont(font);

}

void snakecontrol::setscores(int n)
{
 scores->setText(QString("%1").arg(n));
}

void snakecontrol::setspeed(int n)
{
 m_pspeed->setText(QString("%1").arg(n));
}
void snakecontrol::setnode(int n)
{
 m_pnode->setText(QString("%1").arg(n));
}


main.cpp

#include "mainwindow.h"
#include 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
    MainWindow w;
    w.show();
return a.exec();
}















你可能感兴趣的:(学习)