个人主页:咸鱼弟
激励话语:在你想要放弃的那一刻, 想想为什么当初走到了这里。
系列专栏:单片机设计
1、设计内容
利用51单片机设计了一个贪吃蛇游戏,并通过keil+protues进行仿真
游戏设计规则:
①当没有改变方向时,贪吃蛇沿原来路径一直前进;
②贪吃蛇无法回头,只能异于当前方向改变行动;
③蛇头碰到蛇身时死亡,游戏结束;
④贪吃蛇吃到豆子则蛇身增加;
⑤蛇头碰到墙壁时死亡,游戏结束;
⑥当蛇长达到17及以上时出现山洞出口,进入则游戏胜利
2、protues仿真电路
电路很简单,由单片机最小系统+12864液晶屏+按键组成;单片机负责程序的执行和调度,液晶屏显示游戏画面,按键负责控制上下左右移动。
3、典型算法
3.1、采用循环队列存储蛇头的转向信息
存储蛇头转向的信息使用了step记录,即每走一步使step+1,初始化蛇头step>蛇尾step,当按下按键时代表蛇头发生转向,用循环队列记录此时蛇头step坐标入队,同时使队尾指针+1,当不停前进蛇尾到达此step时,代表之前蛇头在此发生转向,则可不用具体xy坐标记录信息,从而节省存储空间。
void Key_Scan(void){
if (KEY0 == 0)
pause();
else if (KEY1 == 0) {
if (direction != 2) { //蛇不能直接掉头
direction = 1;
tailtrun_step[rear] = head_step;
tailtrun_direction[rear] = 1;
rear = (rear + 1) % 20;
}
}
else if (KEY2 == 0) {
if (direction != 1) {
direction = 2;
tailtrun_step[rear] = head_step;
tailtrun_direction[rear] = 2;
rear = (rear + 1) % 20;
}
}
else if (KEY3 == 0) {
if (direction != 4) {
direction = 3;
tailtrun_step[rear] = head_step;
tailtrun_direction[rear] = 3;
rear = (rear + 1) % 20;
}
}
else if (KEY4 == 0) {
if (direction != 3) {
direction = 4;
tailtrun_step[rear] = head_step;
tailtrun_direction[rear] = 4;
rear = (rear + 1) % 20;
}
}
}
3.2、根据行列具体点亮或熄灭LCD-12864某一个点
由于LCD-12864的点阵点亮是八位DB0~DB7一次性操作一个page,代表一次只能八位一起操作,无法根据某一点的line,column点亮一个点,这里采用了位与或的思想,即根据某一点的line算出此坐标点对应的page中所在的位,后读取这点所在整列的数据与此位进行位或,即可在不改变原始数据的情况下点亮此点,熄灭相似,先对位信息进行取反,后与所在整列的数据与此位进行位与,即可熄灭某一具体点。
// 位转16进制
int bitTo16(uint8 wei){
switch (wei){
case 0:return 0x01;break;
case 1:return 0x02;break;
case 2:return 0x04;break;
case 3:return 0x08;break;
case 4:return 0x10;break;
case 5:return 0x20;break;
case 6:return 0x40;break;
case 7:return 0x80;break;
//default:return 0x00;break;
}
}
// 点亮一个点,行列
void show_p(uint8 screen, uint8 line, uint8 column) {
SelectScreen(screen);
dat = read_LCD_data(line / 8, column);
write_LCD_data(dat | bitTo16(line % 8));
}
// 熄灭一个点,行列
void out_p(uint8 screen, uint8 line, uint8 column) {
SelectScreen(screen);
dat = read_LCD_data(line / 8, column);
write_LCD_data(dat & ~(bitTo16(line % 8)));
}
3.3、碰撞检测
同样采取位与的思想,函数传入具体点的line,column坐标,读取此列的信息,后进行位与操作,若结果不为零,则代表此点已被点亮,表示发生碰撞(蛇身,墙壁)。
// 碰撞检测
void hit_block(uint8 line, uint8 column) {
dat = read_LCD_data(line / 8, column);
if ((dat & bitTo16(line % 8)) != 0)
over();
}
4、测试结果
1.游戏开始,按下中键继续
2.进入游戏,初始得分为03(蛇身长度),按下“上下左右”按键控制方向,按下中键可以暂停游戏,吃到豆子得分+1,且蛇身长度+1。
本文介绍了在设计的过程的关键点,供大家参考学习,如果有错误或者不明白的可以直接私信者,或者添加微信biyezhan007。
3.当贪吃蛇撞墙或者碰撞蛇身时,游戏结束。
4.当贪吃蛇长度大于17时,山洞出现出口,进入则获得游戏胜利。
本文介绍了在设计的过程的关键点,供大家参考学习,如需获取实物、或者下载链接失效、对其他单片机硬件设计感兴趣、有不明白的或者错误的,可以添加徽信biyezhan007
郑重声明,此文章提供给大家做参考模板,杜绝一切不良学术不良行为。