前言
做完俄罗斯方块后,突然不知道干嘛。索性一鼓作气,把贪吃蛇也撸出来。
简介
贪吃蛇,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