前端练手小项目——贪吃蛇
前端练手小项目——贪吃蛇
虽然不难 但是可以说 从头到尾都是自己想的!开心
下面说一下js方面的详细思路以及遇到的问题,独立写下来还是收获比较大
这里我的规则就是简化的版本,也就是随机出现食物,每次蛇吃到长度就加一。
〇、html css布局中需要注意的几个小点
-
game游戏框宽高必须设置为蛇小块宽高的整数倍,这样才能准确判断蛇是否会碰到边框;
-
其实这个游戏布局比较简单,主要在宽高的设置时要注意border之类的会影响盒子的实际宽高的情况,用
box-sizing=border-box;
也可以,自己算也可以; -
这里列一下盒子基本模型以及对应的jQuery方法
- width() - 设置或返回元素的宽度
- height() - 设置或返回元素的高度
- innerWidth() - 返回元素的宽度(包含 padding)
- innerHeight() - 返回元素的高度(包含 padding)
- outerWidth() - 返回元素的宽度(包含 padding + border)
- outerWidth(true) - 返回元素的宽度(包含 padding + border + margin)
-
这里蛇小块的定位都采用相对定位,在设置位置变化的时候直接用css的left top修改,一开始我用的offset().left来判断,但用这个修改有一个极大的问题,也就是它未定为就还在文档流中,删掉一个元素会使下面元素向上跑,页面重构;
-
自己可以根据个人喜欢将背景设置为喜欢的图片,是给content盒子(最外面的)设置背景图片,然后用一个mask盒子设置index=-1来形成灰蒙蒙的样子,让图片不至于太亮影响游戏显示。
一、初始化事件监听
这个项目还比较简单,因此事件需要绑定的就三个:
1)按键按钮
给document全局绑定,这里采用keyup而不是keydown,这样可以减少由于按着不松而导致的多次触发事件
- 利用event.key得到按下的键名,再赋给type(用来判断往哪个方向走的全局变量);
- 这里需要注意一下,当按下与运动方向相反的键时视为无效操作。
2)开始按钮
开始界面退出,游戏界面显示,并且定时器开始工作。
3)重新开始按钮
结束页面退出,游戏界面显示,并且要初始化游戏盒子(不然就是接着上次游戏结束时的蛇继续了)
二、蛇的移动 move()
基本思想是,设置一个定时器,速度由一个全局变量speed控制,每次根据type(按下的方向键)来判断运动方向,蛇的最后一块到蛇将要将要到的方向去,实现蛇的移动。
蛇的方向控制 moveDirection()
四种情况,分别对应了event.key值为ArrowUp、ArrowDown、ArrowLeft和ArrowRight的时候。
- 按下的键正确的时候:先判断蛇头位置的下一个(运动方向的下一个)位置是否符合规范——不碰壁(规则一),若不符合则直接调用gameOver函数,本轮游戏结束,且该函数要返回false,一会调用回到move函数用来判断是否继续执行后面的语句;
- 若符合规范,则用removeElement函数来实现蛇的向前进,基本思路为:
- 创建一个和蛇身相同的结点,若当前flag(后面会说 用于判断蛇是否吃到了食物)不为1,则删除当前尾节点;
- 在头结点的后面将创建的结点添加进去,改变头结点与尾节点的位置(这里要想想怎么改比较正确与方便);
- 不能在removeElement函数里直接设置加入结点的位置,因为这个函数不知道当前移动的方向,所以要将这个新创建的结点return回来(也可以通过callback回调函数实现),再在四种情况下分别设置结点的位置。
三、食物的出现 randomFood()
- 先进行判断,若当前游戏里无食物,才添加一个食物;
- 一开始设置游戏框大小的时候就设置好了,框宽高是蛇小块的倍数,因此可以将游戏框看成假象的坐标纸
- 这里游戏框 500*800 蛇小块20*20;
- 每次随机生成其x,y坐标,x∈(0,1,2,...,39),y∈(0,1,2,...,24),再将x y分别*20即得到食物的位置;
- 为了增强游戏(个人哈哈哈)趣味性,可将游戏的背景变成自己喜欢的几张图,再随机抽就可以啦。
四、吃食物 自身长度的变化
这里利用了一个全局标志量flag
-
蛇每移动一次,就将蛇当前头结点与食物的位置进行比较,若相等则将flag置为1,暂时还未实现长度变化;
-
到下一次蛇移动的时候(flag===1):
- 不删除当前尾节点,但去掉标识当前尾节点的snake-tail类,也就是将其变为一个普通蛇结点;
- flag恢复为0。
-
这样为什么实现了长度变化?因为,不管flag为什么值,在蛇头的前进方向都会增加一个结点:
- 若flag为0,也就是没有吃到食物时,那就去掉尾节点实现蛇移动;
- 若flag为1,也就是吃到食物时,不去掉尾节点将其变为普通结点实现蛇长度增加。
五、自身相撞的判断(规则二)
这里相撞要能想到,撞的时候肯定是头结点撞到其他的结点,因此可以有以下思路:
- 遍历头结点的所有兄弟节点siblings(“.snake”)注意不要遍历到食物上面去了,因为food也是头结点的兄弟节点;
- 看每个结点的position的left和top值是否分别与头结点的这两个值相等,若相等则游戏结束。
GitHub源码链接 https://github.com/TRY0929/try.github.io-/tree/master/前端小项目/贪吃蛇 (19.12.24