基于QT的贪吃蛇设计

  • 非常简单的一个贪吃蛇程序设计,程序最终效果如图所示:
    在这里插入图片描述
  • 首先设计好UI界面,并设置各个按键的功能。
  • 设置贪吃蛇速度的两个控件:滑动器和微调框是相互关联的,程序实现代码如下:
//关联速度的两个控件
    void(QSpinBox:: *spsignal)(int)=&QSpinBox::valueChanged;
    connect(ui->spinBox,spsignal,ui->horizontalSlider,&QSlider::setValue);
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
    connect(ui->horizontalSlider,&QSlider::valueChanged,[=](){
        speed=ui->spinBox->value();
    });//关联速度调节
  • 选择颜色按键的设计代码:
//按下颜色按钮选择颜色
    QColorDialog *colordig=new QColorDialog;
    connect(ui->pushButton_color,&QPushButton::clicked,this,[=](){
        colordig->show();
    });
    //点击了颜色全局的颜色就会改变
    connect(colordig,&QColorDialog::currentColorChanged,this,[=](){
        QBrush brush(col,Qt::SolidPattern);
        col=colordig->currentColor();
        QString text = QString("RGB: %1, %2, %3").arg(col.red()).arg(col.green()).arg(col.blue());
        //qDebug() << text;
        update();
    });
  • 用STL的随机数生成函数生成食物
 food_x=ui->frame_3->x()+((rand()%(ui->frame_3->width()))/12)*12;
 food_y=ui->frame_3->y()+((rand()%(ui->frame_3->height()))/12)*12;
  • 蛇即是一连串的存储在一个deque容器的坐标点,这种容器可以非常方便的在头部和尾部插入和删除数据,坐标点经x*1000+y运算后转换为一个数存入容器中,每次定时器溢出时,根据方向变量在容器头部插入下一个点的坐标,并删除掉尾部的数据,以此模拟移动,蛇死亡时会弹出设定好的另一个ui,弹出结束时的ui及定时器溢出时的代码:
gameoverform *over_dialog=new gameoverform;
    over_dialog->setWindowTitle("game over");//设置游戏结束弹窗的标题
    //设置游戏结束窗口下,两个按键的功能
    connect(over_dialog->ui->pushButton_restart,&QPushButton::clicked,[=](){
        over_dialog->close();
        snake=snake_init;
        direction=4;
    });
    connect(over_dialog->ui->pushButton_over,&QPushButton::clicked,this,[=](){
        over_dialog->close();
        this->close();
    });


connect(timerid,&QTimer::timeout,[=](){
        last_food_x=snake.front()/1000;
        last_food_y=snake.front()%1000;
        last_snake_back=snake.back();
        switch (direction) {
        case 1:{snake.pop_back();snake.push_front(last_food_x*1000+last_food_y-12);break;}
        case 2:{snake.pop_back();snake.push_front(last_food_x*1000+last_food_y+12);break;}
        case 3:{snake.pop_back();snake.push_front((last_food_x-12)*1000+last_food_y);break;}
        case 4:{snake.pop_back();snake.push_front((last_food_x+12)*1000+last_food_y);break;}
        }//蛇移动
        //qDebug()<<"坐标x"<<food_x<<"坐标y"<<food_y;
        if(snake.front()==(food_x*1000)+food_y)
        {
            food_x=ui->frame_3->x()+12+((rand()%(ui->frame_3->width()-12))/12)*12;
            food_y=ui->frame_3->y()+12+((rand()%(ui->frame_3->height()-12))/12)*12;
            snake.push_back(last_snake_back);
        }//判断蛇吃到了食物
        if((((snake.front()/1000)<(ui->frame_3->x()))||((snake.front()/1000)>=(ui->frame_3->x()+ui->frame_3->width()))||
             ((snake.front()%1000)<(ui->frame_3->y()))||((snake.front()%1000)>=(ui->frame_3->y()+ui->frame_3->height()))))
        {
            timerid->stop();
            over_dialog->show();
        }//判断蛇撞墙
        for (unsigned long long k=snake.size();k>1;k--) {
            if(snake.front()==snake[k])
            {
                timerid->stop();
                over_dialog->show();
            }
        }//判断蛇是否咬到自己
        update();//更新画面
    });

  • 在绘图事件中定义一个QPainterPath用于画蛇,以容器中的每一个坐标点为圆心按固定半径画圆并添加的定义的QPainterPath对象中,在定时器溢出时更新绘图;绘图事件代码:
//画图事件
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter_color(this);
    QPen pen(col);
    pen.setWidth(5);
    pen.setStyle(Qt::DotLine);
    painter_color.setPen(pen);
    //设置画刷
    QBrush brush(col,Qt::SolidPattern);
    painter_color.setBrush(brush);
    painter_color.fillRect(ui->label_color->x(),ui->label_color->y(),ui->label_color->height(),ui->label_color->width(),col);
    //在颜色按钮右边的方框内显示颜色指示
    QPainterPath food_path;
    food_path.addEllipse(food_x,food_y,12,12);//画食物
    painter_color.fillPath(food_path,col);
    //画蛇,按蛇的每一个坐标点画r=6的圆
    QPainterPath snake_path;
    for(unsigned long i=0;i<snake.size();i++)
    {
        snake_path.addEllipse(snake[i]/1000,snake[i]%1000,12,12);
    }
    painter_color.fillPath(snake_path,col);
}

键盘事件代码:

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if((event->key()==Qt::Key_Up)&&(direction!=2)) direction=1;
    if((event->key()==Qt::Key_Down)&&(direction!=1)) direction=2;
    if((event->key()==Qt::Key_Left)&&(direction!=4)) direction=3;
    if((event->key()==Qt::Key_Right)&&(direction!=3)) direction=4;

    qDebug()<<"方向键值"<<direction;
}

源代码下载链接:https://download.csdn.net/download/qq_41831273/11966724

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值