初次学习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();
}