自学内容网 自学内容网

基于QT实现贪吃蛇

0.项目展示 

 

1.游戏大厅界面搭建

1.1 效果展示

1.2 背景添加

  •  通过重写paintEvent事件来绘画界面

部分窗口大小,标题,图标的优化 

1.3 开始按钮 

  • 使用CSS机制,添加样式,去掉边框

1.4 跳转游戏界面 

1.5 问题:如何实现2个界面直接的跳转

  •  创建一个新的类,作为新界面
  • 使用信号与槽机制进行跳转,其中类名.show表示展示界面

1.6 问题:为什么包含不了QSound头文件

  • 在项目源文件中,添加multimedia模块,之后才能继续添加QSound头文件

 2. 渲染游戏关卡界面

2.1 返回按钮 

2.2 三种模式按钮 && 历史查询

2.3 跳转游戏界面

 2.4 渲染游戏房间

3.游戏逻辑 

3.1 相关变量设计

  • 将贪吃蛇看成一个一个小矩形连接而成的链表(QList),链表中存储的是矩形(QRectF) 

3.2 moveUP

void GameRoom::moveUp()
{
    QPointF leftTop;//左上角
    QPointF rightBottom;// 右下角坐标

    QRectF snakeNode = snakeList.front();//头节点
    int headX = snakeNode.x();
    int headY = snakeNode.y();

    //考虑穿墙问题
    if(headY < 0){//穿墙了
        leftTop = QPointF(headX,this->height()-kSnakeNodeHeight);
    }
    else{
        leftTop = QPointF(headX,headY-kSnakeNodeHeight);
    }
    rightBottom = leftTop + QPointF(kSnakeNodeWidth,kSnakeNodeHeight);

    snakeList.push_front(QRectF(leftTop,rightBottom));
}
  • 一个矩形(QRectF)由左上角右下角2个点(QPointF)构成 
  • 这里穿墙的处理方法是从一侧穿过,另一侧穿出

3.3 moveDown

3.4 moveLeft

3.5 moveRight 

3.6 checkFail 

3.7 渲染贪吃蛇 && 食物

 3.8 初始化贪吃蛇

GameRoom::GameRoom(QWidget *parent) : QWidget(parent)
{
    this->setWindowIcon(QIcon(":res/ico.png"));
    this->setWindowTitle("游戏房间");

    //初始化
    snakeList.push_back(QRectF(this->width()*0.9,this->height()*0.5,\
                               kSnakeNodeWidth,kSnakeNodeHeight));
    moveUp();
    moveUp();

    //创建食物
    creatNewFood();
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,[=](){
        int cnt = 1;
        if(snakeList.front().intersects(foodRect)){
            creatNewFood();
            cnt++;
        }
        //蛇吃豆子,豆子占一个,移动占一格,一共走2格
        while(cnt--){
            switch (moveDirect) {
            case SnackDirect::UP:
                moveUp();
                break;
            case SnackDirect::DOWN:
                moveDown();
                break;
            case SnackDirect::LEFT:
                moveLeft();
                break;
            case SnackDirect::RIGHT:
                moveRight();
                break;
            }
        }
        snakeList.pop_back();//删除尾部
        upDate();
    });
}
  •  蛇吃豆子,豆子占一个,移动占一格,一共走2格
  • QRectF中的intersects方法表示判断2个矩形是否重叠

3.9 游戏开始 && 暂停

 

3.10 方向控制 

// 方向控制
    QPushButton* up = new QPushButton(this);
    QPushButton* down = new QPushButton(this);
    QPushButton* left = new QPushButton(this);
    QPushButton* right = new QPushButton(this);
    up->move(865,395);
    down->move(865,485);
    left->move(800,440);
    right->move(930,440);
    up->setText("↑");
    down->setText("↓");
    left->setText("←");
    right->setText("→");

    //去掉边框
    up->setStyleSheet("QPushButton{border:0px;}");
    down->setStyleSheet("QPushButton{border:0px;}");
    left->setStyleSheet("QPushButton{border:0px;}");
    right->setStyleSheet("QPushButton{border:0px;}");

    QFont ft("宋体",30);
    up->setFont(ft);
    down->setFont(ft);
    left->setFont(ft);
    right->setFont(ft);

    connect(up,&QPushButton::clicked,this,[=](){
        if(moveDirect!=SnackDirect::DOWN){
            moveDirect = SnackDirect::UP;
        }
    });
    connect(down,&QPushButton::clicked,this,[=](){
        if(moveDirect!=SnackDirect::UP){
            moveDirect = SnackDirect::DOWN;
        }
    });
    connect(right,&QPushButton::clicked,this,[=](){
        if(moveDirect!=SnackDirect::LEFT){
            moveDirect = SnackDirect::RIGHT;
        }
    });
    connect(left,&QPushButton::clicked,this,[=](){
        if(moveDirect!=SnackDirect::RIGHT){
            moveDirect = SnackDirect::LEFT;
        }
    });

3.11 游戏退出

  • 使用了QMessageBox盒子 

3.12 渲染积分

  • 可变参数传参

3.13  渲染游戏结束

3.14 实现3种游戏模式

 

3.15 历史战绩

connect(history_button,&QPushButton::clicked,this,[=](){
       QWidget* widget = new QWidget;
       widget->setWindowTitle("历史战绩");
       widget->setFixedSize(500,300);

       QTextEdit* edit = new QTextEdit(widget);
       edit->setFont(font);
       edit->setFixedSize(500,300);

       QFile file("C:/Users/46285/Desktop/Greedy_Snake/Snake/1.txt");
       file.open(QIODevice::ReadOnly);
       QTextStream in(&file);//文本流
       int data = in.readLine().toInt();//toInt将字符转换成整数


       edit->append("得分:"+QString::number(data));
       widget->show();
    });

4.优化

该项目还有很多需要优化的地方,但我时间有限,暂不优化

 4.1 退出优化

  • 还有一个小bug,记得设置每个窗口的大小 

5.完整项目链接 

GitHub - 1LYC/projects: 一些实战项目

6.项目面经 

6.1 请简单介绍一下你的项目

  •  开发环境是windows下qt creater的环境

  • 项目所使用的技术有,QList链表,QTimer定时器,qrand()产生随机数,update函数,QFile文件操作,QMessageBox消息盒子等

6.2 项目实现的功能

  • 实现的功能有,游戏开始界面,游戏关卡选择界面,游戏房间界面,
  • 完成了贪吃蛇的主逻辑:上下左右,吃食物,增加分数,以及查看历史界面的逻辑

6.3 从项目中学习到了什么

  • 学习到了在qt中如何使用各种控件属性,搭建一个简单的小游戏,
  • 理解到了游戏搭建的过程

原文地址:https://blog.csdn.net/LYC_462857656/article/details/144009513

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!