查看: 4991|回复: 2

【UP-Board试用】+基于Qt的贪吃蛇小游戏设计

[复制链接]
  • TA的每日心情
    奋斗
    2022-10-13 10:27
  • 签到天数: 216 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2017-2-20 17:45:31 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 windworld-1898442 于 2017-2-20 18:10 编辑

       前面再系统上搭建了Qt的开发环境,所以这里和大家一个分享一个关于贪吃蛇的Qt小游戏。
    运行硬件:Upboard
    运行环境:Ubuntu+Qt
    这里界面部分比较简单,主要通过代码实现,UI如下
    1.jpg

      思路是用画矩形的方式绘制网格 用黑色正方形方块表示蛇,蛇长度,初始为3。通过二维数组表示对应的蛇头蛇身,对应的xy坐标。蛇的移动主要是吃食后的移动 即为蛇头向前移动一格后蛇头坐标变了原蛇头的坐标为第一节身体的坐标 原第一节身体坐标为现在第二节的坐标即所有坐标向前移动一格代码如下:
    1. #include "snake.h"
    2. #include "ui_snake.h"
    3. #include <QPainter>
    4. #include <QMessageBox>
    5. #include <QTime>
    6. #include<QDebug>
    7. Snake::Snake(QWidget *parent) :
    8.     QWidget(parent),
    9.     ui(new Ui::Snake)
    10. {
    11.     ui->setupUi(this);

    12.     SnakeNum=3;        //蛇长度,初始为3
    13.     SnakeFX=3;        //蛇头方向
    14.     Block=20;
    15.     level=1;
    16.     temp=0;
    17.     this->setWindowTitle(tr("贪吃蛇-->[关卡:%1-分数:%2]").arg(level).arg(Score));
    18.     //初始化蛇
    19.     for(int i=0;i<SnakeNum;i++)
    20.     {
    21.         xSnake[i].X=400;xSnake[i].Y=200+i*Block;xSnake[i].Snake_fx=SnakeFX;
    22.     }

    23.     creFOOD(); //随机生成食物
    24.     Score=0;

    25.     timer.start(timeoutTime(), this);
    26. }

    27. Snake::~Snake()
    28. {
    29.     delete ui;
    30.     timer.stop();
    31. }

    32. void Snake::keyPressEvent(QKeyEvent *e)
    33. {
    34.     switch(e->key())
    35.     {
    36.     case Qt::Key_Left:
    37.         SnakeFX = 1;
    38.         break;
    39.     case Qt::Key_Right:
    40.         SnakeFX = 2;
    41.         break;
    42.     case Qt::Key_Up:
    43.         SnakeFX = 3;
    44.         break;
    45.     case Qt::Key_Down:
    46.         SnakeFX = 4;
    47.         break;
    48.     }
    49. }

    50. void Snake::paintEvent(QPaintEvent *e)
    51. {
    52.     int i;
    53.     QPainter painter(this);
    54.     QPen pen;
    55.     pen.setColor(QColor(255,0,0));  //设置画笔为红色
    56.     painter.setPen(pen);  //选择画笔
    57.     //画网格地图
    58.     for(i=0;i<=this->height();i=i+Block)
    59.     {
    60.         painter.drawLine(0,i,this->width(),i);
    61.     }
    62.     for(i=0;i<=this->width();i=i+Block)
    63.     {
    64.         painter.drawLine(i,0,i,this->height());
    65.     }
    66.     for(i=0;i<SnakeNum;i++)
    67.     {
    68.         painter.fillRect(QRect(xSnake[i].X,xSnake[i].Y,Block,Block),QColor(0,0,0));
    69.     }

    70.     painter.fillRect(QRect(Food.x()*Block,Food.y()*Block,Block,Block),QColor(0,0,0));

    71.     painter.end();
    72. }
    73. bool Snake::isCONFINE(int x,int y)
    74. {
    75.     if((x<0 || x>this->width()) || (y<0 || y>this->height()))
    76.         return true;
    77.     return false;
    78. }

    79. bool Snake::isFOOD(int x,int y)
    80. {
    81.     if(Food.x()*Block==x && Food.y()*Block==y)
    82.         return true;
    83.     return false;
    84. }
    85. bool Snake::isOWN(int x,int y)
    86. {
    87.     int i;
    88.     for(i=0;i<SnakeNum;i++)
    89.     {
    90.         if(xSnake[i].X==x && xSnake[i].Y==y)
    91.             return true;
    92.     }
    93.     return false;
    94. }
    95. void Snake::eatFOOD()
    96. {
    97.     SnakeNum++;
    98.     switch(xSnake[SnakeNum-2].Snake_fx)
    99.     {
    100.         case 1:
    101.             xSnake[SnakeNum-1].X=xSnake[SnakeNum-2].X+Block;
    102.             xSnake[SnakeNum-1].Y=xSnake[SnakeNum-2].Y;
    103.             xSnake[SnakeNum-1].Snake_fx=xSnake[SnakeNum-2].Snake_fx;
    104.             break;
    105.         case 2:
    106.             xSnake[SnakeNum-1].X=xSnake[SnakeNum-2].X-Block;
    107.             xSnake[SnakeNum-1].Y=xSnake[SnakeNum-2].Y;
    108.             xSnake[SnakeNum-1].Snake_fx=xSnake[SnakeNum-2].Snake_fx;
    109.             break;
    110.         case 3:
    111.             xSnake[SnakeNum-1].X=xSnake[SnakeNum-2].X;
    112.             xSnake[SnakeNum-1].Y=xSnake[SnakeNum-2].Y+Block;
    113.             xSnake[SnakeNum-1].Snake_fx=xSnake[SnakeNum-2].Snake_fx;
    114.             break;
    115.         case 4:
    116.             xSnake[SnakeNum-1].X=xSnake[SnakeNum-2].X;
    117.             xSnake[SnakeNum-1].Y=xSnake[SnakeNum-2].Y-Block;
    118.             xSnake[SnakeNum-1].Snake_fx=xSnake[SnakeNum-2].Snake_fx;
    119.             break;
    120.     }

    121.     Score+=10;
    122.     temp+=10;
    123.     if(temp==50)
    124.     {
    125.         level++;
    126.         temp=0;
    127.     }
    128.     if(level<20)
    129.     {
    130.         timer.start(timeoutTime(), this);
    131.     }
    132.     this->setWindowTitle(tr("贪吃蛇-->[关卡:%1-分数:%2]").arg(level).arg(Score));

    133.     creFOOD();//吃完食物后再随机生成食物

    134. }

    135. bool Snake::isOver(int x,int y)
    136. {
    137.     if((isCONFINE(x,y)) || (isOWN(x,y)))
    138.     {
    139.         timer.stop();
    140.         QMessageBox::information(this,tr("提示"),tr("游戏结束!!!"));
    141.         return true;
    142.     }

    143.     return false;
    144. }

    145. void Snake::creFOOD()
    146. {
    147. FOOD:
    148.     Food.setX(qrand()%(this->width()/Block));
    149.     Food.setY(qrand()%(this->height()/Block));
    150.     for(int i=0;i<SnakeNum;i++)
    151.     {
    152.         if(xSnake[i].X==Food.x() && xSnake[i].Y==Food.y())
    153.         {
    154.             goto FOOD;
    155.         }
    156.     }
    157. }

    158. void Snake::timerEvent(QTimerEvent *e)
    159. {
    160.     int i,TempFX1,TempFX2;

    161.     if((SnakeFX==1 && xSnake[0].Snake_fx==2) || (SnakeFX==2 && xSnake[0].Snake_fx==1)) goto xx;
    162.     if((SnakeFX==3 && xSnake[0].Snake_fx==4) || (SnakeFX==4 && xSnake[0].Snake_fx==3)) goto xx;

    163.     switch(SnakeFX)
    164.     {
    165.     case 1:
    166.         if(isOver(xSnake[0].X-Block,xSnake[0].Y)) break;

    167.         if(isFOOD(xSnake[0].X-Block,xSnake[0].Y))
    168.         {
    169.             eatFOOD();
    170.         }
    171.         xSnake[0].Snake_fx=1;
    172.         break;
    173.     case 2:
    174.         if(isOver(xSnake[0].X+Block,xSnake[0].Y)) break;

    175.         if(isFOOD(xSnake[0].X+Block,xSnake[0].Y))
    176.         {
    177.             eatFOOD();
    178.         }
    179.         xSnake[0].Snake_fx=2;
    180.         break;
    181.     case 3:
    182.         if(isOver(xSnake[0].X,xSnake[0].Y-Block)) break;

    183.         if(isFOOD(xSnake[0].X,xSnake[0].Y-Block))
    184.         {
    185.             eatFOOD();
    186.         }
    187.         xSnake[0].Snake_fx=3;
    188.         break;
    189.     case 4:
    190.         if(isOver(xSnake[0].X,xSnake[0].Y+Block)) break;

    191.         if(isFOOD(xSnake[0].X,xSnake[0].Y+Block))
    192.         {
    193.             eatFOOD();
    194.         }
    195.         xSnake[0].Snake_fx=4;
    196.         break;
    197.     }

    198.     //蛇前进
    199. xx:
    200.     for(i=0;i<SnakeNum;i++)
    201.     {
    202.         switch(xSnake[i].Snake_fx)
    203.         {
    204.         case 1:
    205.             xSnake[i].X=xSnake[i].X-Block;
    206.             break;
    207.         case 2:
    208.             xSnake[i].X=xSnake[i].X+Block;
    209.             break;
    210.         case 3:
    211.             xSnake[i].Y=xSnake[i].Y-Block;
    212.             break;
    213.         case 4:
    214.             xSnake[i].Y=xSnake[i].Y+Block;
    215.             break;
    216.         }

    217.     }
    218.     TempFX1=xSnake[0].Snake_fx;
    219.     for(i=1;i<SnakeNum;i++)
    220.     {
    221.         TempFX2=xSnake[i].Snake_fx;
    222.         xSnake[i].Snake_fx=TempFX1;
    223.         TempFX1=TempFX2;
    224.     }
    225.     update();
    226. }
    复制代码
    运行实现的效果如下图所示
    QQ截图20170220154800.jpg

    QQ截图20170220155428.jpg

    简单视频如下
    VID_20170220_172805 00_00_00-00_00_31.zip (1.75 MB, 下载次数: 9)
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2017-10-15 13:21
  • 签到天数: 183 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2017-2-21 09:04:23 | 显示全部楼层
    谢谢分享                     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-9-19 11:01
  • 签到天数: 30 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2018-7-17 10:48:25 | 显示全部楼层
    感谢LZ分享
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-3-28 21:23 , Processed in 0.149786 second(s), 22 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.