c/c++语言开发共享QT实现贪吃蛇游戏

为了熟悉qt的相关知识,我用了大约8个小时的时间用qt再次写了一遍贪吃蛇。因为qt的机制和平时写的程序流程不同,所以程序中可能没有遵守代码规范。运行效果:程序内除了实现贪吃蛇的基本功能外,还添加了记录

为了熟悉qt的相关知识,我用了大约8个小时的时间用qt再次写了一遍贪吃蛇。

因为qt的机制和平时写的程序流程不同,所以程序中可能没有遵守代码规范。

运行效果:

QT实现贪吃蛇游戏

程序内除了实现贪吃蛇的基本功能外,还添加了记录得分、调节游戏速度、重新开始游戏等功能。

游戏内容使用qpainter类进行绘制。

编译环境:

windows qt 5.9.0 qt creator 4.3.0

思路:

数组存储蛇节点坐标的贪吃蛇游戏思路。

因为编写过程中使用了分文件编写,且qt框架的其他部分较多,这里仅展示程序实现主要代码。

代码:

mainwindow.h 主窗口类头文件

  #ifndef widget_h  #define widget_h    #include <qwidget>  #include <qpainter>     //画家类  #include "snake.h"      //蛇类  #include <qkeyevent>    //键盘事件  #include "food.h"       //食物类  #include <qtimer>       //定时器类    namespace ui {  class widget;  }    class widget : public qwidget  {      q_object    public:      explicit widget(qwidget *parent = 0);      ~widget();        //绘图事件      void paintevent(qpaintevent *);        //游戏结束的情况      void gameover();    private:      ui::widget *ui;        snake snake;        //蛇对象      char key = 'd';     //接收键值,初始向右      food food;          //食物对象      //创建定时器      qtimer *timer = new qtimer(this);      bool gameflag = false;//游戏结束标记      int score = 0;      //记录得分      int timerspeed = 200; //定时器速度      bool bugflag = false; //用于解决操控过快导致撞死自己的bug的标志        //键盘事件,改变键值      void keypressevent(qkeyevent *ev);  };    #endif // widget_h

mainwindow.cpp函数实现

  #include "mainwindow.h"  #include "ui_widget.h"  #include <qlabel>  #include <qpushbutton>    //主窗口构造函数  widget::widget(qwidget *parent) : qwidget(parent), ui(new ui::widget)  {      ui->setupui(this);      //初始化出.ui界面        //一个格子宽高25像素,地图宽高600像素,每行有24个格子        //设置固定窗口大小      setfixedsize(1000,600);        //设置得分标签控件的属性      ui->label->setfont(qfont("黑体", 20, qfont::bold, false));        //设置游戏速度标签内容      ui->label_2->setfont(qfont("楷体", 16, qfont::bold, false));      ui->label_2->settext("游戏速度:");        //滑动条控件,这里将数值按一定比例放大缩小      ui->horizontalslider->setvalue(200 >> 2);        //监听滑动条控件滑动时,改变定时器速度为滑动条的值      connect(ui->horizontalslider,qslider::valuechanged,[=]()      {          timerspeed = ui->horizontalslider->value() << 2;      });        //设置重新开始按钮属性和内容      ui->pushbutton_3->setfont(qfont("黑体",12));      ui->pushbutton_3->settext("重新开始");        //监听重新开始按钮      connect(ui->pushbutton_3,qpushbutton::clicked,[=]()      {          snake.reset();      //重置蛇          score = 0;          //得分清0          key = 'd';          //key值向右          timerspeed = 200 << 2;//重置游戏速度          timer->start(timerspeed);//重置定时器          ui->horizontalslider->setvalue(200 >> 2);//重置滑动条          gameflag = false;   //重置游戏结束标志      });        //开启定时器      timer->start(timerspeed);        //监听定时器的信号,执行表达式内容      connect(timer,&qtimer::timeout,[=]()      {          timer->start(timerspeed); //调整定时器的速度            snake.move(key);    //蛇移动函数            //吃到食物的情况          (food.getfoodx() == snake.snakevec.at(0).x && food.getfoody() == snake.snakevec.at(0).y) ?          score++, food.randfood():    //得分+1,随机产生一个食物坐标          snake.snakevec.pop_back();   //删除蛇尾            gameover();    //游戏失败的情况            update();      //调用绘图函数            //更新标签控件的文本内容          ui->label->settext(qstring("得分:%1").arg(score));      });  }    //游戏失败情况  void widget::gameover()  {      //撞墙失败      if(snake.snakevec.at(0).x >= 24 * 25 || snake.snakevec.at(0).x < 0 ||         snake.snakevec.at(0).y < 0 || snake.snakevec.at(0).y >= 24 * 25)      {          gameflag = true;          timer->stop();      //暂停定时器          return;      }        //撞自己失败      for(int i = 1; i < snake.snakevec.size(); i++)      {          if(snake.snakevec.at(0).x == snake.snakevec.at(i).x &&             snake.snakevec.at(0).y == snake.snakevec.at(i).y)              gameflag = true, timer->stop();      }  }      //绘图事件  void widget::paintevent(qpaintevent *)  {      //创建画家对象,指定绘图设备为this主窗口      qpainter painter(this);        //设置画刷为红色      qbrush brush1(qt::red);      //让画家使用画刷      painter.setbrush(brush1);      //画食物      painter.drawrect(qrect(food.getfoodx(),food.getfoody(),25,25));        //设置画刷为黑色      qbrush brush2(qt::blue);      painter.setbrush(brush2);        //遍历蛇坐标容器,画出代表蛇身的矩形      for(auto snakenodei : snake.snakevec)          //蛇头画圆形          (snakenodei.x == snake.snakevec.at(0).x &&           snakenodei.y == snake.snakevec.at(0).y) ?          //蛇头画圆形          painter.setrenderhint(qpainter::antialiasing),  //用抗锯齿画圆          painter.drawellipse(qpoint(snakenodei.x + 12,snakenodei.y + 12),12,12):          //蛇身画矩形          painter.drawrect(qrect(snakenodei.x,snakenodei.y,25,25));        bugflag = false;    //在画出蛇之后将标志设为假        //设置画刷为黑色      qbrush brush3(qcolor(128, 64, 0));      painter.setbrush(brush3);        //画出墙壁      for(int i = 0; i < 24; i++)            painter.drawrect(qrect(25 * 25, i * 25, 25, 25));        //游戏结束时的绘图      if(gameflag)      {   //设置文字属性          qfont font("楷体", 80, qfont::bold, false);          painter.setfont(font);      //使用字体          painter.drawtext(qrect(240, 200, 1000, 500), "游戏结束");   //画出游戏结束文字      }  }    //键盘事件,改变贪吃蛇移动方向  void widget::keypressevent(qkeyevent *ev)  {      if(bugflag)     //bug标志为真直接返回          return;        switch (ev->key())      {      case qt::key_w:          if(key == 's') break;   //按下与当前方向相反按键时break          key = 'w';          bugflag = true; break;        //按键之后将标志设为真      case qt::key_s:          if(key == 'w') break;          key = 's';          bugflag = true; break;      case qt::key_a:          if(key == 'd') break;          key = 'a';          bugflag = true; break;      case qt::key_d:          if(key == 'a') break;          key = 'd';          bugflag = true; break;      case qt::key_space:     //空格键暂停,这里有点问题          timer->stop(); break;      default:                //其他键重启定时器          timer->start(timerspeed);      }  }    //析构  widget::~widget()  {      delete ui;  }

snake.h 蛇类头文件

  #ifndef snake_h  #define snake_h    #include <qwidget>  #include <qvector>      //qt动态数组类    class snake : public qwidget  {      q_object  private:      //蛇坐标结构      struct  snakecoor      {          int x;          int y;      };    public:      explicit snake(qwidget *parent = nullptr);        //蛇坐标容器      qvector<snakecoor> snakevec;        //蛇移动主要函数      void move(char key);        //根据key值确定蛇的移动方向      void detedirmove(char key, snakecoor &nexthead);        //重置蛇      void reset();    signals:    public slots:  };    #endif // snake_h

snake.cpp 蛇类函数实现

  #include "snake.h"    //构造函数初始化一条蛇  snake::snake(qwidget *parent) : qwidget(parent)  {      snakecoor snakenode;            //临时结构变量用于创建蛇      for (int i = 5; i >= 0; i--) //从右向左创建5节蛇身,容器的第一个元素为蛇头      {          snakenode.x = 25 * 8 + i * 25;//每个格子宽25像素          snakenode.y = 25 * 8;          snakevec.push_back(snakenode);//将蛇节点插入到数组中      }  }    //确定蛇的移动方向,确定新蛇头的坐标位置  inline void snake::detedirmove(char key, snakecoor &nexthead)  {      switch (key)      {      case 'w':          //新蛇头坐标根据旧蛇头坐标改变          nexthead.x = snakevec.front().x;          nexthead.y = snakevec.front().y - 25;          break;      case 's':          nexthead.x = snakevec.front().x;          nexthead.y = snakevec.front().y + 25;          break;      case 'a':          nexthead.x = snakevec.front().x - 25;          nexthead.y = snakevec.front().y;          break;      case 'd':          nexthead.x = snakevec.front().x + 25;          nexthead.y = snakevec.front().y;      }  }    //蛇移动主要函数  void snake::move(char key)  {      snakecoor nexthead;  //创建一个新的蛇头        detedirmove(key, nexthead);  //确定新蛇头的位置        snakevec.insert(snakevec.begin(), nexthead);    //将新蛇头插入到容器头部  }    //重置蛇函数  void snake::reset()  {      snakevec.clear();   //清空容器        //初始化蛇      snakecoor snakenode;      for (int i = 5; i >= 0; i--)      {          snakenode.x = 25 * 8 + i * 25;          snakenode.y = 25 * 8;          snakevec.push_back(snakenode);      }  }

food.h 食物类头文件

  #ifndef food_h  #define food_h    #include <qwidget>    class food : public qwidget  {      q_object  public :      int food_x = 0;     //食物坐标      int food_y = 0;    public:      explicit food(qwidget *parent = nullptr);        void randfood();    //随机产生食物坐标      int getfoodx();     //返回食物坐标      int getfoody();    signals:    public slots:  };    #endif // food_h

food.cpp 食物类函数实现

  #include "food.h"  #include <ctime>    food::food(qwidget *parent) : qwidget(parent)  {      randfood();     //创建对象时产生就一个随机坐标    }    //随机产生食物坐标  void food::randfood()  {      srand((unsigned)time(null));      food_x = (rand() % 24) * 25;      food_y = (rand() % 24 )* 25;  }    //获取食物的坐标  int food::getfoodx()  {      return food_x;  }    int food::getfoody()  {      return food_y;  }

以上就是c/c++开发分享QT实现贪吃蛇游戏的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网(www.ctvol.com)!!>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/609348.html

(0)
上一篇 2021年5月17日
下一篇 2021年5月17日

精彩推荐