之前文章Processing笔记05—贪吃蛇小游戏分享过如何使用Processing来实现贪吃蛇游戏,很多小伙伴问可不可以来个Arduino版本的,那么本篇就通过Arduino,配合摇杆按键和OLED显示屏来实现贪吃蛇游戏。
OLED屏的VCC、GND分别连接开发板的3.3V、GND,OLED屏的SDA和SCL分别连接开发板的A4和A5。双轴按键摇杆模块的VCC、GND分别连接开发板的5V、GND,模块的X轴输出、Y轴输出分别连接开发板的模拟引脚A0、A1。
实验原理图如下图所示:
实物连接图如下图所示:
...
void snake_move(void)
{
switch (snake_dir) {
case RIGHT:
snake_head_x += 4;
break;
case UP:
snake_head_y -= 4;
break;
case LEFT:
snake_head_x -= 4;
break;
case DOWN:
snake_head_y += 4;
break;
}
if ((snake_head_x == food_x) && (snake_head_y == food_y))
{
food_eaten = true; //可重新生成食物
snake_len++;
score++;
level = score / 5 + 1;
snake_speed -= level;
}
for (i = snake_len - 1; i > 0; i--)
{
x[i] = x[i - 1];
y[i] = y[i - 1];
}
x[0] = snake_head_x;
y[0] = snake_head_y;
check_snake_die();
}
...
贪吃蛇中最主要的部分就是绘制蛇身,实验中使用数组来保存蛇身每个方块的坐标值,使用drawBitmap()函数来绘制一个4X4的矩形表示蛇身方块。
void draw_snake(int x, int y)
{
oled.drawBitmap(x, y, block, 4, 4, 1);
}
每当蛇头位置发生变化,从蛇尾往前遍历整个坐标数组,将每个方块位置往前移动,蛇头坐标为新位置的坐标,然后重新绘制整个蛇身。
在这里使用了随机函数产生规定区域内的食物坐标。首先在setup()中初始化随机种子:
randomSeed(analogRead(3));//初始化随机种子
然后就可以使用random()生成坐标数据,这里除了需要指定区域外,还需要考虑排除掉生成在蛇身中的食物。
void draw_food(void)
{
int food_out = 0; //判断食物是否在蛇体内
if (food_eaten)
{
while (food_out == 0)
{
food_out = 1;
food_x = (uint8_t)(random(4, 100) / 4) * 4;
food_y = (uint8_t)(random(4, 60) / 4) * 4;
for (int i = snake_len - 1; i > 0; i--) //遍历整个蛇身方块,若食物在蛇身内则重新生成
{
if (food_x == x[i] && food_y == y[i])
{
food_out = 0;
}
}
}
}
food_eaten = false;
}
本篇使用的是摇杆模块,通过采集到的模拟量来识别出上下左右的不同操作,然后对应改变蛇头的坐标,当重新对蛇身进行绘制的时候,整个蛇就进行了一次移动。
当蛇头坐标超过显示区域,即蛇撞墙,或蛇头位置坐标与蛇身其他方块坐标相同,即自己吃了自己,都会导致游戏结束。
void check_snake_die(void)
{
//撞墙
if (snake_head_x < 4 || snake_head_x > 96 || snake_head_y < 1 || snake_head_y > 56)
{
game_over = true;
}
//自己吃自己
if (snake_len > 4)
{
for (int i = 1; i < snake_len; i++)
{
if (snake_head_x == x[i] && snake_head_y == y[i])
{
game_over = true;
}
}
}
}
由于按键的判断和屏幕的刷新都放在了loop()中,游戏的速度通过改变delay()函数即改变延时时间来实现,所以当游戏速度过慢时,按键操作就变得不灵敏。可以试着使用定时器来刷新屏幕,通过改变定时时间来改变游戏速度。
另外在撞墙的条件判断中,边界值需要实际调试,没有移动到边界或者移动超出边界都不应结束游戏。
陆陆续续分享了很多Arduino的教程,包括基础版33篇和提高版26篇,在这个过程中也帮助到了一些小伙伴,其实笔者玩Arduino都是业余兴趣,教程中的很多东西也是通过网络不断学习汇总的。
由于教程配套了实物套件,不得不与套件中的器件进行配套,其实这并不是件容易的事情,需要从一开始就要考虑后面的好几篇内容,完全不能随心所欲的分享。终于,Arduino系列教程到此就结束了,后面分享Arduino会多一些创客DIY之类的。
兴趣是最好的老师,希望小伙伴们除了应对课程设计之类的,也能喜欢上Arduino。愿你所有的坚持,都来自心中的那份热爱。
关注公众号「TonyCode」,后台回复“提高”,获取文中代码。
个人博客