C++贪吃蛇

前言

做完俄罗斯方块后,突然不知道干嘛。索性一鼓作气,把贪吃蛇也撸出来。


简介

贪吃蛇,c++,qt。
基本的贪吃蛇功能,没什么特殊的。蛇的速度与蛇的长度成正比。同时实现了记分以及暂停的功能。


效果图


游戏过程效果图

这里写图片描述


实现思路


相比俄罗斯方块,实贪吃蛇的实现容易了许多,主要就是一个蛇的移动问题。
想到蛇的曲折的行进路径,正常第一反应就是去想把那么转向的位置纪录下来。
但仔细想想完全不用这样。
用一个数据记录蛇身每个节点的坐标。那么每次蛇移动,都是当前节点移动到上一个节点的位置。
这样以来,我们只需要控制蛇头去转向即可。蛇身自然会跟随蛇头的路径去前进。


代码构成

全部代码仍然是三个类

1. Snake 蛇信息及操作

class Snake
{
public:
    int len;//蛇的长度
    int s[10000][2];//保存蛇身
    int dx, dy;//蛇当前方向
    Board *board;

    Snake(Board *);
    void eat();//吃食
    int detect();//碰撞检测
    void toNext();//前往当前方向下一步
    void turnUp();//蛇转向
    void turnDown();
    void turnLeft();
    void turnRight();
};

2. Board 游戏地图信息

class Board
{
public:
    int score;//当前分数
    int maxScore;//最高分
    int atime;//每次下落的间隔时间
    int length;//地图边长
    int foodX;//食物所在坐标
    int foodY;
    Snake *snake;//蛇
    int map[100][100];//保存地图信息

    Board(int);
    void makeFood();//随机生成食物
    bool isEnd();//进行蛇的前进,并判断前进后是否游戏结束
};

3. mainWindow 游戏界面部分

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    bool flag;//判断是否暂停状态
    bool isPress;//控制按键频率
    QTimer *timer;//定时器
    Board *board;//游戏所用地图类

    MainWindow(QWidget *parent = 0);
    void paintEvent(QPaintEvent *event);//绘制界面
    void keyPressEvent(QKeyEvent *);//键盘事件处理

signals:

public slots:
    void timerEvent();//定时事件

private:
};

遇到的问题及解决方法

和俄罗斯方块的一个小区别是,俄罗斯方块每次完成一个小块的操作后,会产生一个新的小块,进行新的操作。
而贪吃蛇不同,蛇一直都在动,并且从游戏开始到结束都只有这一条蛇。
所以这里必须要保证每次移动一个单位长度,都必须只能前进一次。
因为玩家按键的速度远超过计算机的timeout。所以会出现界面上蛇身还没转向,但逻辑上方向已经发生了变化。
因此,使用一个isPress变量来实现对按键频率的控制,即:
蛇体的每次移动,只能转向一次。
这样就可以避免出现上述的问题。


感触

写完俄罗斯后,几个小时就完成了贪吃蛇,在理解的基础上,唯手熟耳。要坚持!

完整代码

我的github链接:
https://github.com/shiyi1996/game

如果本文对你有用,可以请作者喝杯茶~
0%