Qt 小游戏之简化版贪吃蛇

本文分享了使用QT编写的贪吃蛇游戏源码及实现细节。通过自定义Meadow类,实现了小蛇吃蛋变大、得分及计时等功能。游戏界面由小方块构成,蛇和蛋分别用不同样式label显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QT贪吃蛇

由于课程需要,写一个贪吃蛇。我跟着老师的步伐,一步一步写。
界面做的很丑,基本是拖几个label,窗口也没怎么修饰,只是简单的实现了小蛇吃蛋变大,得分,以及计时的功能。

蛇和蛋以及蛇的运动和吃蛋,都是在"meadow.h"这个类里面实现

代码里面,将界面全部用小方块填充,然后隐藏。一切操作都是在label上操作,小蛇也是用label显示,蛋也是用label显示,只是小蛇用了5个label显示最初的模样,而蛋只用一个label。
M,N是一个常量,表示我们活动区域需要的长和宽

#define M 35
#define N 24
void Meadow::initGame(){
    int s = 36;
    for(int x = 0; x < M; x++){
        for(int y = 0; y < N; y++){
            QLabel *label = new QLabel(this);
            int x0 = x * s;
            int y0 = y * s;
            label->setGeometry(x0, y0, s - 2, s - 2);
            label->setStyleSheet("background:#e88; border-radius:8px;");
            label->hide();

            labels[x][y] = label;
        }
    }


}

接下来是画边框,我们要规定一个边框,蛇和蛋只能在这个区域内。

void Meadow::drawBorder(){
    for(int x = 0; x < M; x++){
        for(int y = 0; y < N; y++){            
            QLabel *label = labels[x][y];
            if(x == 0 || y == 0 || x == M - 1 || y == N - 1)
                label->show();
            else
                lableList.append(QPoint(x,y));
        }
    }
}

这里蛇的运动我用定时器来解决,定时一段时间,我们将蛇头前面label显示,隐藏蛇尾的label,这样在视觉上可以形成蛇在移动的错觉,其实只是label一个隐藏,一个显示了。

void Meadow::startGame(){
    drawBorder();
    initSnake();
    timer.start(300);
}
void Meadow::moveStep(int dx,int dy){
    emit countime();
    QPoint oldHead = snake.first();
    QPoint newHead = QPoint(oldHead.x() + dx, oldHead.y() + dy);
    QPoint tail = snake.last();
    //判断蛇是否撞到自己、墙壁
    if (snake.contains(newHead)||newHead.x()==0 || newHead.y()==0 || newHead.x()==M - 1 || newHead.y() == N - 1)
    {
        emit gameover();
        timer.stop();

        return;
    }
    if (newHead==egg){

        labels[newHead.x()][newHead.y()]->setStyleSheet("background:#e88; border-radius:8px;");
        snake.prepend(newHead);

        lableList.removeOne(newHead);
        generateEgg();

        emit SendCount(++count);

    }else{
        labels[newHead.x()][newHead.y()]->show();

        lableList.removeOne(newHead);

        labels[tail.x()][tail.y()]->hide();
        snake.prepend(newHead);
        snake.removeLast();
        lableList.append(tail);
    }


}

其中labelList这个list里面装的是除了蛇,蛋和墙,其余隐藏的label,而snake这个list就装的是蛇的label了,而label里面这个是所有的label。之所以定义这个多list,完全是为了代码的方便,逻辑清晰。下面随机生成的蛋,也就几行代码,看着就很舒服。之前想过随机生成的蛋有可能落在蛇圣商,或者周围的墙上,如果发生了这样的情况还要重新生成。所以很纠结,还好多定义几个list,这样就方便多了。

void Meadow::generateEgg(){


       int n =  qrand()%lableList.size();

       egg =  lableList.takeAt(n);
       labels[egg.x()][egg.y()]->setStyleSheet("background:#384; border-radius:8px;");
       labels[egg.x()][egg.y()]->show();
}

界面几乎就是原始界面,因为刚学,不会画,之前了解过,Qt有画的类,但是无奈花在Qt上的时间总是很少。所以只能简单的用颜色和方块来表示了。

Qt的弹球游戏、舒码特方格也做过,但是代码之前交完作业也就不见了,只有小蛇的代码刚交完,所以我这里上传一份,作为笔记。
这是全部代码的github链接地址,如果需要参考可以前往下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值