在游戏的过程中,根据选择难度不同蛇身移动速度也不相同,在蛇生长初期每吃掉一个食物蛇身增长1节,蛇身会上、下、左、右移动......这些变化是怎么实现的呢?
接下来将所有关于蛇的控制都集中到这篇进行讲解。
蛇身速度控制
蛇身速度控制可以用一个计数器实现,计数器计满的这个值代表蛇身移动的时间间隔,每次计数器满则蛇身进行移动。
间隔越短,蛇运动速度越快,游戏难度越难。当难度选择界面出现的时候,可通过SW[2:0]三个开关进行速度的选择:
速度分三个档,0.5s移动一次、0.25s移动一次和0.125s移动一次:
蛇身增长
cube_x,cube_y表示一整条蛇身体各节的节坐标。第一节代表蛇头。
获取蛇头坐标:
蛇和食物的初始位置的代码:
当蛇头和食物(苹果)重合时,代表蛇吃掉了一个食物,并生成一个增加身长的信号add_cube(这个在apple_generate.v模块中有讲解)。每吃下一个食物蛇长度增加1,相应exist位置变为1。is_exist有16位,即蛇体最长为16*1格,每一位对应一个格,is_exist的值为1为该格显示,为0则不显示(图中虚框)。
每次add_cube信号被拉高,显示体长的变量cube_num增加1位,"is_exixt[cube_num]<=1"代表让第cube_num位"被显示出来":
蛇撞墙或咬自身
蛇撞墙
将蛇头的坐标跟墙壁的坐标进行比较,重合则说明撞墙。
蛇咬到自己
当蛇头的坐标跟身体的某一节坐标重合,代表蛇咬到了自己。
蛇身的整体移动路径
蛇身和蛇头一起移动。蛇头根据按下的按钮来判断是撞到了墙,还是咬到自身,还是移动到了下一个位置。
蛇身每次移动,后一位的身子会移动到前一位的位置(比如第0个块的坐标赋给第1块,第1块的坐标赋给第2块......)。
对应的代码如下:
蛇头方向控制
KEY0~KEY3控制着蛇的上、下、左、右方向。DE2-115、DE1-SOC、DE10-Standard这三个板子的按键都有硬件去抖动, 所以设计里面不需要额外添加去抖动电路,而是直接将key 的值拿来使用。
蛇头方向控制的具体内容参考上一篇基于FPGA的贪吃蛇游戏设计(八)——状态机设计的描述。
蛇色块显示
当像素坐标pos_x[9:4]和pos_y[9:4]与蛇的坐标吻合时,VGA显示器显示蛇身,蛇头等。
墙壁显示也是同理。
上面代码显示的蛇身是一整块的,蛇的每一节没有分开,不好分辨当前蛇到底长到多少节, 所以接下来,我们来做个记号,让蛇的每一节第一列前3个像素显示黑色,这样就会看起来有个缺口:
效果对比如下:
snake.v代码较多,感兴趣的读者可以下载工程进行查看。
贪吃蛇系列连载文章:
1. 基于FPGA的贪吃蛇游戏设计(一)
2. 基于FPGA的贪吃蛇游戏设计(二)——数码管驱动模块
3. 基于FPGA的贪吃蛇游戏设计(三)——计分模块
4. 基于FPGA的贪吃蛇游戏设计(四)——VGA驱动模块色块显示
5. 基于FPGA的贪吃蛇游戏设计(五)——VGA驱动模块字符显示
6. 基于FPGA的贪吃蛇游戏设计(六)——VGA驱动模块图片显示
7. 基于FPGA的贪吃蛇游戏设计(七)——食物(苹果)的产生
8. 基于FPGA的贪吃蛇游戏设计(八)——状态机设计
9. 基于FPGA的贪吃蛇游戏设计(九)——蛇身控制
关注
“友晶Terasic”公众号可获取源码下载地址。
移植到DE1-SOC、DE2-115时代码无需改变,只需修改引脚分配即可。