.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QKeyEvent>
#include <QTimer>
#include<QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
typedef enum Direct{
left,
right,
down,
up,
}dir;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void keyPressEvent(QKeyEvent *event);//按键处理
void paintEvent(QPaintEvent *event);
void addtop();
void adddown();
void addright();
void addleft();
void deletelast();
void addfood();
bool check();
protected slots:
void timeout();//超时处理函数
private:
Ui::Widget *ui;
int direct=up;
bool gamestart=false;
QTimer *timer;
int t=125;// 超时时间间隔 ms
QList <QRectF> snake;
int Width=20;
int Height=20;
QRectF food;
};
#endif // WIDGET_H
.cpp
#include "widget.h"
#include "./ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("贪吃蛇");
//定时器,定时器又一个超时信号timeout
timer= new QTimer();
//信号槽
connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));
resize(1000,600);
//初始化蛇
QRect rect(500,300,Width,Height);
snake.append(rect);
addtop();
//初始化奖品
addfood();
}
Widget::~Widget()
{
delete ui;
}
void Widget::keyPressEvent(QKeyEvent *event){
switch(event->key()){
case Qt::Key_Up:
if(direct!=down){
direct=up;
}
break;
case Qt::Key_Down:
if(direct!=up){
direct=down;
}
break;
case Qt::Key_Left:
if(direct!=right){
direct=left;
}
break;
case Qt::Key_Right:
if(direct!=left){
direct=right;
}
break;
case Qt::Key_Backspace:
if(gamestart==false){
gamestart=true;
timer->start(t);
}else{
gamestart=false;
timer->stop();
}
break;
default:
break;
}
}
void Widget::timeout(){
//判断有没有吃到食物
int cout=1;
while(cout--){
switch(direct){
case up:
addtop();
break;
case down:
adddown();
break;
case right:
addright();
break;
case left:
addleft();
break;
default:
break;
}
if(snake[0].intersects(food)){
cout++;
addfood();
}
}
deletelast();
update();
}
void Widget::addtop(){
QPointF lefttop; //表示坐标的一个点
QPointF rightbotton;
if(snake[0].y()-Height<0){
lefttop=QPointF(snake[0].x(),this->height()-Height);
rightbotton=QPointF(snake[0].x()+Width,this->height());
}else{
lefttop=QPointF(snake[0].x() , snake[0].y()-Height);
rightbotton=snake[0].topRight();
}
snake.insert(0,QRectF(lefttop,rightbotton));
}
void Widget::adddown(){
QPointF lefttop;
QPointF rightbotton;
if(snake[0].y()-Height*2>this->height()){
lefttop=QPointF(snake[0].x() , 0);
rightbotton=QPointF(snake[0].x()+Width,Height);
}else{
lefttop=snake[0].bottomLeft();
rightbotton=snake[0].bottomRight()+QPointF(0,Height);
}
snake.insert(0,QRectF(lefttop,rightbotton));
}
void Widget::addleft(){
QPointF lefttop;
QPointF rightbotton;
if(snake[0].x()-Width<0){
lefttop=QPointF(this->width()-Width , snake[0].y());
}else{
lefttop=snake[0].topLeft()-QPointF(Width,0);
}
rightbotton = lefttop + QPointF(Width,Height);
snake.insert(0,QRectF(lefttop,rightbotton));
}
void Widget::addright(){
QPointF lefttop;
QPointF rightbotton;
if(snake[0].x()-Width*2>this->width()){
lefttop=QPointF(0 , snake[0].y());
}else{
lefttop=snake[0].topRight();
}
rightbotton = lefttop + QPointF(Width,Height);
snake.insert(0,QRectF(lefttop,rightbotton));
}
void Widget::deletelast(){
snake.removeLast();
}
bool Widget::check(){
for (int i=0;i<snake.length();i++)
for(int j=i+1;j<snake.length();j++){
if(snake[i]==snake[j]){
return true;
}
}
return false;
}
void Widget::addfood(){
food = QRectF(
rand()%(this->width()/20)*20,
rand()%(this->height()/20)*20,
Width,
Height
);
}
void Widget::paintEvent(QPaintEvent *event){
QPainter painter(this);
QPen pen;
QBrush brush;
QPixmap p;
painter.drawPixmap(0,0,1000,600,p);
pen.setColor(Qt::black);
brush.setColor(Qt::gray);
brush.setStyle(Qt::SolidPattern);
painter.setPen(pen);
painter.setBrush(brush);
for(int i=0;i<snake.length();i++){
painter.drawRect(snake[i]);
}
//画食物
pen.setColor(Qt::black);
brush.setColor(Qt::black);
brush.setStyle(Qt::SolidPattern);
painter.setPen(pen);
painter.setBrush(brush);
painter.drawEllipse(food);
QFont font("华文宋体",20,QFont::ExtraLight,false);
pen.setColor(Qt::black);
painter.setPen(pen);
painter.setFont(font);
painter.drawText(20,20,QString("当前得分:")+QString("%1").arg(snake.length()-2));
if(check()){
QFont font("微软雅黑",30,QFont::ExtraLight,false);
painter.setFont(font);
painter.drawText((this->width()-300)/2,
(this->height()-30)/2,
QString("游戏结束")
);
timer->stop();
}
QWidget::paintEvent(event);
}