51单片机上实现贪吃蛇小游戏
单片机LED阵列一共8x8, unsigned char map[8]
记录地图数据,unsigned char
数据类型8 bits,map[i]
中第j
个bit 代表 第i
行第j
列是否被点亮
- 单片机主函数中,不断刷新LED点阵,更新蛇的位置和食物的位置
while(1)
{
if (is_game_over()) {
light_all();
} else {
show_map(); // 根据蛇位置和食物的位置,点亮矩阵屏
k = keyboard(); // 尝试获取用户输入(蛇前进方向的改变)
dir_scan(k);
}
}
- 使用
snake_body_x[64]
和snake_body_y[64]
数组存储蛇的身体,i = 0
位置为蛇头,单片机定时器中断函数中,每500ms移动蛇的位置,蛇头根据按键输入向前后左右其中一个方向移动,蛇后一节躯体向前一节躯体的位置移动,即
snake_body_x[0] = ? // 根据按键输入方向移动
snake_body_y[0] = ? // 根据按键输入方向移动
for (int i = 1; i < snake_len; i++) {
snake_body_x[i] = snake_body_x[i-1];
snake_body_y[i] = snake_body_y[i-1];
}
- 如果蛇吃到食物,长度增加(蛇尾增加一节),刷新下一次食物的位置
// 如果吃到食物
if (snake_body_y[0] == food_y && snake_body_x[0] == food_x) {
snake_body_x[snake_len] = tail_x;
snake_body_y[snake_len] = tail_y;
snake_len++;
update_food();
}
- 食物的位置刷新方法:获取当前未点亮的LED序号,如 [0, 3, 5, 7, 9, 14] 6栈未点亮,在 [0, 5]中取随机数,点亮其中一盏作为食物
unsigned char pos = rand() % (64 - snake_len);
// 找到第 pos 个未被点亮的LED作为食物的位置
- 游戏结束判定,蛇碰到墙壁或者蛇头碰到自己的身体,游戏结束
unsigned int is_game_over() {
unsigned int i = 0;
// 如果碰到墙
if (snake_body_x[0] >= 8 || snake_body_x[0] < 0 || snake_body_y[0] >= 8 || snake_body_y[0] < 0) {
return 1;
}
// 如果蛇头碰到自己的身体
for (i = 1; i < snake_len; i++) {
if (snake_body_x[0] == snake_body_x[i] && snake_body_y[0] == snake_body_y[i]) {
return 1;
}
}
return 0;
}