一种基于QT实现的贪吃蛇游戏

一、实验环境

QT

语言:C++

二、实验目的

1)实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子。玩家能利用上下左右键控制“蛇”的移动,“蛇”吃到“豆子”后“蛇”身体加长一节,得分增加,“蛇”碰到边界或蛇头与蛇身相撞,“蛇”死亡,游戏结束。

2)进行交互界面的设计,要有开始键、暂停键和停止退出的选项,能够控制游戏进程。对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。

三、代码实现

    首先,游戏实现的最基本的条件是能用键盘操控蛇的移动。这就需要使用keyEvent的头函数。有一点要注意的是,当蛇向上(下)或左(右)移动的时候,蛇不能向下(上)或右(左)移动。这里只要一个if条件句判断即可。

void Widget::keyPressEvent(QKeyEvent *event) {
    switch(event->key()) {
    case Qt::Key_Up:
        if(moveFlag != DIR_DOWN){
            moveFlag = DIR_UP;
        }
        break;
    case Qt::Key_Down:
        if (moveFlag != DIR_UP) {
            moveFlag = DIR_DOWN;
        }
        break;
    case Qt::Key_Right:
        if (moveFlag != DIR_LEFT) {
            moveFlag = DIR_RIGHT;
        }
        break;
    case Qt::Key_Left:
        if (moveFlag != DIR_RIGHT) {
            moveFlag = DIR_LEFT;
        }
        break;
    case Qt::Key_Space:
        if (gameStart == false) {
            gameStart = true;
            timer->start(time);
        } else {
            gameStart = false;
            timer->stop();
        }
        break;
 default:
        break;
    }
}

接下来的移动速度只要一个计时器来操控。

 蛇身可以用QPainter画出。蛇的移动可以想象成方块的增加和删减。比如,蛇向上移动的时候,蛇身堆栈顶部添加一个方块,蛇的尾部删除一个方块。

pen.setColor(QColorConstants::Svg::lightblue);
    brush.setColor(QColorConstants::Svg::blue);
    brush.setStyle(Qt::SolidPattern);
    painter.setPen(pen);
    painter.setBrush(brush);

    for(int i=0; i<snake.length(); i++) {
        painter.drawRect(snake[i]);
    }

食物的生成操作和蛇身一样。

当蛇头碰到食物的时候,判断为吃到食物,蛇身加一。其中要注意的是蛇原本移动的方向,蛇身要加在原方向上。这就要再写四个函数。以向上为例。

void Widget::addTop() {
    QPointF leftTop;
    QPointF rightBotom;

    if (snake[0].y() - nodeHeight < 0) {
        leftTop = QPoint(snake[0].x(), this->height() - nodeHeight);
        rightBotom = QPointF(snake[0].x() + nodeWidth, this->height());
    } else {
        leftTop = QPointF(snake[0].x(), snake[0].y()-nodeHeight);
        rightBotom = snake[0].topRight();
    }

    snake.insert(0, QRectF(leftTop, rightBotom));
    c++;
}

还有游戏结束的判断。游戏结束有两种可能:一是蛇头碰到蛇身,二是蛇头撞向边界。其中第二个我已将蛇设置为可以穿过边界。具体操作就是当蛇碰到边界的时候在同等高度(宽度)生成蛇头。

接下来蛇头碰到蛇身的判断就只需要从堆栈入手。写一个判断循环即可。

bool Widget::checkContact() {
   for (int i=0; i<snake.length(); i++)
       for (int j=i+1; j<snake.length(); j++) {
           if(snake[i] == snake[j]) {
               return true;
           }
       }

再使用QPainter画出失败界面,计时器停止,游戏就结束了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值