我是靠谱客的博主 傻傻小蚂蚁,这篇文章主要介绍QT实现贪吃蛇游戏代码详解,现在分享给大家,希望可以做个参考。

一、新建一个Qt项目

新建Qt Widgets Application,项目名称为HappySnake,基类选择QWidget,类名默认

二、添加要用到的头文件

复制代码
1
2
3
4
5
6
7
8
#include <QKeyEvent> #include <QRectF> #include <QPainter> #include <QPen> #include <QBrush> #include <QDebug> #include <QTimer> #include <QTime>

三、写类声明信息

  • 贪吃蛇的本体使用小方框来代替
  • 使用QList类来保存贪吃蛇的本体
  • 使用定时器来设定刷新的时间
  • 使用随机函数生成奖励的节点
  • 使用paintEvent来进行绘图
  • keyPressEvent来监测按键的按下,控制贪吃蛇的移动
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); protected: void paintEvent(QPaintEvent *); void keyPressEvent(QKeyEvent *); private: void addTopRectF(); void addDownRectF(); void addLeftRectF(); void addRightRectF(); void deleteLastRectF(); bool snakeStrike(); enum Move{Left,Right,Up,Down}; protected slots: void timeOut(); void rewardTimeOut(); private: Ui::Widget *ui; QList<QRectF> snake;//贪吃蛇本体 int snakeNodeWidth = 10; int snakeNodeHeight = 10; QTimer *timer; QTimer *rewardTimer; int time = 100; int moveFlage = Up; bool gameOver = false; bool gameStart = false; QList<QRectF> rewardNode;//奖励节点 };

四、对类函数的实现

构造函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); resize(480,500); //设置窗体背景色为黑色 setStyleSheet("QWidget{background:black}"); setWindowOpacity(0.8);//设置窗口的透明度 snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight)); addTopRectF(); addTopRectF(); //首先生成一个奖励节点 rewardNode.append(QRectF(100,100,snakeNodeWidth,snakeNodeWidth)); timer = new QTimer; connect(timer, SIGNAL(timeout()),this,SLOT(timeOut())); //timer->start(time); rewardTimer = new QTimer; connect(rewardTimer,SIGNAL(timeout()),this,SLOT(rewardTimeOut())); //rewardTimer->start(time*30); } Widget::~Widget() { delete ui; }

界面刷新

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void Widget::timeOut() { int flage = 1; for(int i=0; i<rewardNode.length(); i++){ if(rewardNode.at(i).contains(snake.at(0).topLeft()+QPointF(snakeNodeWidth/2,snakeNodeHeight/2))){ //if(snake.at(0).contains(rewardNode.at(i).x()+rewardNode.at(i).width()/2,rewardNode.at(i).y()+rewardNode.at(i).height()/2)){ if(rewardNode.at(i).width()>snakeNodeWidth){//额外奖励 flage += 2; } flage++;//正常奖励 rewardNode.removeAt(i); break; } } while(flage--){ switch (moveFlage) { case Up: addTopRectF(); break; case Down: addDownRectF(); break; case Right: addRightRectF(); break; case Left: addLeftRectF(); break; default: break; } } deleteLastRectF(); update(); }

随机奖励的生成

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
//随机奖励 void Widget::rewardTimeOut() { qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); if(rewardNode.length() > 5){ rewardNode.removeAt(qrand()%5); } rewardNode.append(QRectF(qrand()%(this->width()/20)*20,qrand()%(this->height()/20)*20,snakeNodeWidth,snakeNodeWidth)); if(qrand()%5 == 3){ rewardNode.append(QRectF(qrand()%(this->width()/20)*20-5,qrand()%(this->height()/20)*20-5,snakeNodeWidth*2,snakeNodeWidth*2)); } }

移动

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//向上移动 void Widget::addTopRectF() { if(snake.at(0).y()-snakeNodeHeight < 0){ snake.insert(0,QRectF(QPointF(snake.at(0).x(),this->height()-snakeNodeHeight), QPointF(snake.at(0).x()+snakeNodeWidth,this->height()))); }else{ snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(0,-snakeNodeHeight),snake.at(0).topRight())); } } //向下移动 void Widget::addDownRectF() { if(snake.at(0).y()+snakeNodeHeight*2 > this->height()){ snake.insert(0,QRectF(QPointF(snake.at(0).x(),snakeNodeHeight), QPointF(snake.at(0).x()+snakeNodeWidth,0))); }else{ snake.insert(0,QRectF(snake.at(0).bottomLeft(),snake.at(0).bottomRight()+QPointF(0,snakeNodeHeight))); } } //向左移动 void Widget::addLeftRectF() { if(snake.at(0).x()-snakeNodeWidth < 0){ snake.insert(0,QRectF(QPointF(this->width()-snakeNodeWidth,snake.at(0).y()), QPointF(this->width(),snake.at(0).y()+snakeNodeHeight))); }else{ snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(-snakeNodeWidth,0),snake.at(0).bottomLeft())); } } //向右移动 void Widget::addRightRectF() { if(snake.at(0).x()+snakeNodeWidth*2 > this->width()){ snake.insert(0,QRectF(QPointF(0,snake.at(0).y()), QPointF(snakeNodeWidth,snake.at(0).y()+snakeNodeHeight))); }else{ snake.insert(0,QRectF(snake.at(0).topRight(),snake.at(0).bottomRight()+QPointF(snakeNodeWidth,0))); } } //删除结尾数据 void Widget::deleteLastRectF() { snake.removeLast(); }

绘图

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//绘图 void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); QPen pen; QBrush brush; QFont font("方正舒体",12,QFont::ExtraLight,false); //反锯齿 painter.setRenderHint(QPainter::Antialiasing); pen.setColor(Qt::black); brush.setColor(Qt::green); brush.setStyle(Qt::SolidPattern); painter.setPen(pen); painter.setBrush(brush); for(int i=0; i<snake.length(); i++){ painter.drawRect(snake.at(i)); } brush.setColor(Qt::red); painter.setBrush(brush); for(int i=0; i<rewardNode.length(); i++){ painter.drawEllipse(rewardNode.at(i)); } pen.setColor(Qt::white); painter.setPen(pen); painter.setFont(font); painter.drawText(20,20,QString("当前得分:")+QString("%1").arg(snake.length())); if(snakeStrike()){ QFont font("方正舒体",30,QFont::ExtraLight,false); painter.setFont(font); painter.drawText((this->width()-300)/2,(this->height()-30)/2,QString("GAME OVER!")); timer->stop(); rewardTimer->stop(); gameOver = true; } QWidget::paintEvent(event); }

按键事件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void Widget::keyPressEvent(QKeyEvent *event) { switch(event->key()){ case Qt::Key_Up: if(moveFlage != Down){ moveFlage = Up; } break; case Qt::Key_Down: if(moveFlage != Up){ moveFlage = Down; } break; case Qt::Key_Right: if(moveFlage != Left){ moveFlage = Right; } break; case Qt::Key_Left: if(moveFlage != Right){ moveFlage = Left; } break; case Qt::Key_Enter: case Qt::Key_Return: if(gameOver){ snake.clear(); rewardNode.clear(); moveFlage = Up; snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight)); addTopRectF(); addTopRectF(); //首先生成一个奖励节点 rewardNode.append(QRectF(100,100,snakeNodeWidth,snakeNodeWidth)); timer->start(time); rewardTimer->start(time*30); gameOver = false; } break; case Qt::Key_Space: if(gameStart && !gameOver){ timer->start(time); rewardTimer->start(time*30); gameStart = false; }else if(!gameStart && !gameOver){ timer->stop(); rewardTimer->stop(); gameStart = true; } break; default: break; } }

判断蛇身是否相撞

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
//判断蛇头是否和蛇身相撞 bool Widget::snakeStrike() { for(int i=0; i<snake.length(); i++){ for(int j=i+1; j<snake.length(); j++){ if(snake.at(i) == snake.at(j)){ return true; } } } return false; }

五、结束

实现的效果:


总结:

只是简单的使用了paintevent进行绘图,基本都是简单的对Qt的一些常用类的使用,对面向对象的编程应用的不是很好,更偏向于面向过程,所以完全可以改成C语言在Linux下实现,思路都是相同的。

到此这篇关于QT实现贪吃蛇游戏代码详解的文章就介绍到这了,更多相关QT内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!

最后

以上就是傻傻小蚂蚁最近收集整理的关于QT实现贪吃蛇游戏代码详解的全部内容,更多相关QT实现贪吃蛇游戏代码详解内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(143)

评论列表共有 0 条评论

立即
投稿
返回
顶部