前端练手小项目——贪吃蛇

前端练手小项目——贪吃蛇

虽然不难 但是可以说 从头到尾都是自己想的!开心

下面说一下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/%E5%89%8D%E7%AB%AF%E5%B0%8F%E9%A1%B9%E7%9B%AE/%E8%B4%AA%E5%90%83%E8%9B%87%20%EF%BC%8819.12.24

猜你喜欢

转载自www.cnblogs.com/TRY0929/p/12094491.html