00:00
好,那我们这个小蛇呢,还有一点的问题啊,我们给它处理完了啊,最后一点了什么问题呢?第一个问题就是刚才我们看到的蛇现在跟这个身体分家了。所以接下来呢,我们要处理一下,哎,让这个蛇的身体可以跟着蛇去移动,那这个时候我们要改哪个类,还是那个原则,就是你看一下,如果我们这件事儿只和蛇自己相关。只和某个对象自己相关,那一定是只改那个对象啊,就是自己的事找自己,你说老师我这写到game controlrl里行不行,行,但是如果你那么写完了以后的话,它这个分工不明确,以后我们维护起来就会很很别扭,所以我们设计设计模式里边有叫单一职责原则,就是我们一个类只做一件事儿,就是你一定要把这个任务给他分清楚,他负责哪,负责干什么事儿,负责做什么工作,然后好处就是我们以后维护起来会很简单,不然你这写一固,那写1GOOD,你你这你蛇的事儿,你写到这个食物里,食物的事写到这个panel里就很别扭,所以这个时候分工一定注意,就是谁的事儿谁去谁去做,那好,那么这里边的话,我们既然是蛇的事儿的话,我们就直接找到我们这个蛇是snake个就是TS蛇的话,我们需要它这个移动身体,所以呢,我们再给蛇添加一个方法,哎,添加一个什么呢?添加一个蛇身体移动的方法。
01:27
我们叫做一个move body吧,哎,Move body移动这个身体。那这个方法里边我们要怎么写呢?这个问题啊,其实不难,但是呢,你需要把这个整个这个流程啊,我需要帮你去诶捋顺一下,那怎么捋顺呢?我们来看一下这个蛇的一个移动,我们这样啊,我画一个画一个小图来把这个事说明一下,打开一个PPT画一个图。画一个图呢,我们把这个这种情况呀,给它模拟出来啊,模拟出来这什么玩意儿。
02:04
来在这儿呢,我把它去掉,我们因为那个蛇的身体呢,是一节一节的啊,蛇的身体是一节一节的,所以我就画几个方块啊,来表示这个蛇的身体。哎,说的身体好四个方块吧,意思意思。那现在呢,假如说这个就是我们那条贪食蛇啊,它现在要移动了,它是怎么移动的,首先要动的话,肯定蛇头动对吧,头往右走,头往右走一格,然后呢,哎,我第二节是不是往接着往右走,第三节是不是接着往右走,第四节也是接着往右走,那这个是我们正常情况下,就是没有拐弯的情况下,但是我如果拐弯了,比如说我蛇现在往下走了,往下走了应该怎么办?往下走另怎么办?我第二节是不是应该走到这儿来呀,然后第三节是不是走到这儿来,哎,然后第四节要走到这个位置,也就是说白了,其实规则很简单,就是我们的这个,哎,后边的这个身体要走到前边身体的位置,哎,比如说我舌头。
03:06
往下移了,那我的第二节身体就要移到舌头的位置,第三节身体就要移到第二节身体刚才的位置,那第四节身体就要移到第三节身体之间的位置,也就是一个顶一个的,就是我后边的身体要去到的是前边这个身体的之前那个位置,那这样我们这个功能是不是就给它就给它完成了,哎,就是这样一个效果,所以实际上它很简单啊,很简单,那接下来的问题就是我们要怎么去移动,那就是一个盯一个是吧?哎,第第二节去舌头的位置,哎,就是舌头去心位置啊,第二节去舌头的位置,第三节去第二节的位置,第四节去第三节的位置,第五节去第四节的位置,以此类推,一节一节的往前去移动,那这里边我们要怎么移动,其实移动起来好很简单,就是修改它的位置,但是怎么移动,那你说老师我是先改第二节,第三节,第四节还是先从后边改呢?注意了,我们这个改的时候一定注意我们要从后往前改。
04:06
为什么呢?因为我要让第二节,第三节的位置是不是要等于第二节的位置,那如果我先改第二节的位置,那这个时候第二节的位置对我来说就已经没了,没了以后的话,我在第三节再找第二节原来的位置是不是就找不到了,所以这个时候注意改的时候一定是从后往前改,干嘛呢?先改第四节的位置,再改第三节的位置,然后再改第二节的位置,最后才改第一这个舌头的这个位置,这样才能避免出现我们这个这个蛇啊头啊,这个身体合合到一块儿这么一个情况,所以。在这里边我们要做的事就是什么呢?就是将将我们这个后边的身体。哎,设置为什么呢?设置为前边身体的一个位置,就是一节一节的往前移啊,往前移一定注意要从后往前改,哎,那这句话你要听不明白啊,把它说的细点,哎举例子,举例子,那就是什么呢?我们第四节。
05:08
哎,等于什么呢?等于第三节的位置。第三节干嘛呢?第三节等于第二节的位置。第二节。哎,等于D,诶诶等于舌头的位置,舌头的位置就是一一个一个往前传,就跟那个舌似的,咕啷咕啷的是吧,往前往往前往前箍上,所以这里边我们要做的事儿的话,其实很简单,那就是我要一节一节的去修改这个身体的一个位置,那既然一节一节修改了,那在这儿我们就要便利什么呢?便利获取我这个所有的身体,但是注意了,这个时候我们是要从后往前改的,所以这个时候便利的时候,我们应该是从后往前变历,所以我们这直接来一个light,一个I,它的初始值应该等于什么呢?应该等于我们身体已经有了Z,点一个body,点一个Les减一等于什么呢?等于我们这个最后最大索引类Les减一呢,不就是最大索引嘛,然后呢,我们这个停止条件,我们也是I小于零,诶也就是说当你小于零的时候,我就停止了,然后是一个I,诶别加加了就减减了,也就是效果就是从后往前去取这个元素啊。
06:23
从后往前去取这个元素,那这里边注意啊,这边注意我们这是I小于零,没有写等于零,为什么没有写等于零,因为零不就是那个舌头了吗,舌头的位置我们这不需要改,因为舌头的位置我们是不是在sat这里面去设置啊,所以舌头的位置我们这是不需要去动的,所以等小于零不要写等于零,等于零你就改舌头位置,改舌头位置就该出问题了啊,然后的话,在这我们来先获取获取我们前边身体的一个位置啊,前面身体的位置直接来一个light一个。Let一个let一个这个X,哎,前面是你的位置,我们写一个吧,写一个这个,嗯,就直接写一个X法,X等于一个前边身体,当前身体是z body,一个I,它前边谁呀?诶当前是五,那前边是不是就是四啊,所以前边的话我们这是I减一,前面是你点一个我们叫做一个off set off set一个这个left,然后再来一个let,一个Y等于一个Z,点一个bodies,然后中号一个这个I减1.1个offet,一个top,这个就是我们前边这个蛇的身体的一个坐标,我们就获取到了,这又给我们出什么错了,我们来看一下告诉你了,诶offet大,诶不存在,在这个element当中,这什么问题呢?这个就是我们说的一个类型问题,因为我们这个它是一个这个跟我们上面的问题一样,是一个这个它里边的类型是element。而我。
07:58
们这个实际类型的话是HTM2ELEMENT实际上是一个接口,Htm element是它这个子接口或叫子类,所以这里边的话,我们明确到知道它里边有,所以我们在这儿给他做一个什么呢。
08:10
哎,做一个这个类型的一个断言,告诉你这就是HTML element,哎,做一个类型断言,那这样就没有问题了,哎就告诉你这类型我没错是吧,你自己不知道,我确定它就是n element,那这样我们是不是就取到它这个X值和Y值了,获取到了然后干嘛呢?然后将这个值。哎,将这个值设置到我们这个,哎设置到我们这个当前的这个身体上,当前身体那就是Z点一个body一个这个,哎点一个这个style,点一个这个什么呢?哎点一个叫做left等于一个X加上一个PX。加上一个PX,这也有这个问题,还得给它断言htm element,那这个里边呢,你可以理解成这个是我们这个TX的一个缺点,但是它也是一个优点,就是避免你在这儿出错误啊,避免你在这出错误,然后下边也是一样style点一个这个top等于一个y.PX那加上一个PX,那这样我们等于在这个哎木body里边是不是把每一个身体都改了,哎,身体都改了,但是只有这个头呢没改,那所以这儿改完了以后,那就等于我们什么时候去掉它,什么时候去吊它,是不是在我这个头移动的时候,我就要去移动身体啊,哎,同时移动身体,所以这个调的时候也是在这个set X和set y里边去调,我直接在这儿调吧,在这儿调来干嘛呢?移动我们这个身体,移动身体,我们直接调一个Z,再次点一个木body顶下边也是一样。
09:49
塞外这我们也是一样,这点一个木body去移动这个身体,其实这两个方法呀,设计的有点啊,有点重复了,他们两个逻辑呢,大体上都是一样的啊,你我就不再改了,你们自己写的时候,你可以思考一下,哎,我能不能把这两个方法给它整合一下啊,整合一下好改完了,那如果逻辑没问题的话,现在蛇的身体就应该跟蛇哎去一起移动了啊,一起移动了,我们来看看效果吧。
10:16
走。走走走走走。诶诶诶诶,完了完了完了完了完了完了完了完了没用是不是哎没用,而且我这设置完了,我这身体是不是压根儿就压根儿就没有动啊,哎没有动,哎这是为什么呀,我这设计的挺完美,但是身体就没有动来,关键还不包错啊,我们来看一下我简单,我给他重新这个重新刷新一下,我们再看看效果,这里边呢,我们来调这个move,这点move body move body的话也掉了呀。也掉了。这样吧。我觉得应该是没编译上,我让他重新编译一下,我们再看看效果啊,看看吧。
11:00
不知道,这我也看不出来,应该是我可能是哪写错了。果然不动啊,果然不动,果然不动啊,我猜测的问题可能是这个这次bodies的问题,就是这个什么玩意儿,就是我们的这个这个东西,这个bodies我可能没获取到,我打印一下这个bodies应该是的问题。打印一下啊,诶这次点一个,诶别在这儿啊,在哪呢?在这个。在这吧,打印一下,这是点一个bodies,点一个Les,点一个log,看一下它。刷新一下。哎,这种错误很正常是吧,弄你们出错的时候也别着急,出错的我们就找一下,就是我们因为我们这写一点的是改一点,所以你看一下你刚才那个错误在哪一,一没问题,我吃一个应该变成二了,二也没问题,那证明我们这个身体的长度是是是是是没有问题的,对吧,身体的长度是没有问题的哦,那我就知道问题在哪了,我们来看一下这块。
12:05
我们来看一下啊,那现在我这个长度是没问题的,那所以证明我这个是没问题的啊,就加一节以后,它确实是多了出问题的点的话,应该是在我的这个设置这块来看一下,嗯,这一块我们是z.body在这儿我们是设置它style点一个left,嗯,我看看什么问题呢?问题是不是有可能,我看一下我们的样式有没有问题。大概排一下吧,这我也只能大概猜一下我们这个div有没有开启定位,哎,这个是蛇snake里面div OK snake里边我这开启了绝对定位了,开定位,那这个的这个蛇的这个定位这块没有问题,不看它了,那应该就是我刚才这样式没设置上,我看一下样式吧。恩,移动一下。吃到这个身体了,我们看一下这个身体的样式,Div。
13:04
呀呀呀呀。你看我这蛇头的这个样式一直在改变,但是我们这个蛇的身体,你看这个div它是不是一直都没有动啊,哎,这个div一直都没有动,那证明我们这个样式的话,它其实并没有设置上,并没有设置上,那就是我们个样式设置代码这块的问题,样式设置代码的话,就在我们刚才的这个东西点,点一个点一个,然后我这一个一个。这一块值没有设置上,那应该是我打印一下这个X还有Y的值。X逗号来一个Y。哎呀,这是什么玩意儿,Cancel,点一个log,打印一下X还有Y的值,然后呢,我再打印一下我们这个z.body一个I。这点包个打印一下,分别我来看一下这两个东西有没有正确的值,刷新一下。
14:09
哎呀哎呀哎呀。编译出错了。重新交代一下。来我们这编译它出问题了啊,出问题了,我们来看一下option to node这什么log啊,重新启动一下。因为刚才我那块有一块代码写错了,我写错了,他在编译过程当中呢,他他他给编进去了,编进去出错了,出错了以后我们就得重新启动一下服务器啊。来看一下。调bug这一块的话,我们其实现在主要的话,也就是凭一个经验,你们遇到bug的话,如果你第一次写这个东西,你可能对于你来说,你排的时候会有一点那个有点痛苦,但是呢,就是别着急啊,慢慢排就OK了,慢慢排怎么跑这儿来了。
15:08
错误还挺严重是吧,重新启动一下再。这打印的是XY。这打印的是我们这个当前的那个z bodies,也就是我想看看我这个z bodies,我到底能不能获取到啊,I减1A减减A小于零,A减一没问题。这个代码写的是我自己看着,哎呀哎呀呀哎呀,这怎么有错啊。我自己看着是挺完美的,但是他这给我报了一个错,这错搁哪呢,在这上边呢。啊,刚才我写错了一个代码啊,它给我自动给我加了一个imp impose的,哎,这个挨千刀的是吧,缺德了。来,再来一次啊,再来一次。
16:03
是吧,你还出错是吧,你还出错,你还出错还出错我也没辙了,是吧,啊,就这东西就是心平气和的是吧,你们调的时候可能会更慢一点,但是我觉得尤其是在我们这个学习阶段,哭爸爸的话,他对于我们来说是一个进步的机会啊,老是顺风顺水的,这东西很没意思,就是在调这个bug过程当中,我们才会进步啊,才会进步。检查打开我这个控制台。看。往下走吃一个食物啊,现在是打印的是这个这个一,这个一是是是是是谁呀,是我们这个长度吗?吃完了以后变成二了。哎哎哎,你这啥意思呀。你这啥意思呀,代码怎么还是旧的呀,我这改了一个,打印的是谁呀,打印了。和这个cancel log.xy,刚才那个123是这个打印的,这个我给它注掉,那刚才我这两个打印的话,它都没有出来,都没有出来的话,就证明了一件事儿啊,都没有出来这么一件事儿,证明什么呢?证明我们这个循环压根儿就没有进来啊,负循环压根儿就没有没有执行啊,没有执行,没有执行,哎呀。
17:18
我这个大嘴巴我应该抽我自己脸上,谁写的这是,哎呀,我都不敢相信,我写了一个I小于零,我是不是在倒着便利啊,倒着变利,当然我这个I应该是大于零,因为它是减减嘛,从大到小的,你小于零,小于零它不永远都不执行了吗?哎呀。还好我看到了是吧,还好我看到了这种东西就很很恶心是吧,当然也就是我啊,能这么快把这个错误找到,要不你们可能你们还找的还要慢一点,但是呢,还是这句话,写的时候要细心一点,千万不要像我这种啊,自己把这东西设计挺好,写完写错了,这种错误其实还不太好找啊,不太好找来整完了,这回你还不动是吧,你再不动啊,我就只能,我就只能吃电脑了是吧,就只能吃电脑了,来吧,走。
18:08
刚才是刷新过来了啊,重新加载过来了,走你诶诶诶诶,现在是不是就很完美了,哎,很完美了啊,稍微有点小波折啊,稍微有点小波折,但是还好这波折不大,我们这个蛇是不是就可以正常去移动了,诶正常去移动了啊。来,再吃一个啊,再吃一个。哎,挺好玩的是吧,哎,待会儿的话可能就就要就要就要这个就要升级了是吧,就要升级了,好那看到这儿的话,我们这个大体上这个整个的一个大体上的就完成了,咱们呀,我也就不停了,我们就直接把这剩下的东西都给他说完。什么问题呢?两个问题,第一个问题呢,就是我们看啊,咱这蛇呀,特别高级,我这蛇能干嘛呢,看着啊。走,你。看到了吗?这是一个3D的蛇,什么叫3D蛇?你看它自己啊,能穿过自己的身体,看到了吗?诶说它可以自己去撞自己的身体,这个蛇很有意思,那这个当然在我们游戏里肯定是。
19:13
不行的,那蛇一旦撞到自己,那这肯定是要去要去报错了,对吧,所以在这里边我们要去验证一下蛇有没有撞到自己,这是第一个问题,第二一个问题就是我们蛇还有一个问题,你看咱这蛇啊,咱这蛇很高级,干嘛呢,你看。我这蛇能掉头,你看我现在蛇啊,往上走呢啊往上走呢,往上走,现在我摁下。哎,你看它是不是还会继续的往下走啊,现在我要蛇往右走,往右走呢,我摁左,我摁左舌是不是可以往左走啊,哎,就说蛇整个可以掉头,这跟那个穿那个身体那个东西啊有点像,哎,也就是这个蛇的它会发生这种诶这种叫做一个蛇这个掉头的一个灵异事件,那现在的话我们要做一件事儿,就是我要去禁止这个蛇的一个掉头啊,不让蛇掉头,那我要怎么去处理这个蛇掉头问题,我们来看一下代码。
20:07
好,那蛇掉头的问题呢,也很好理解,哎,这撞墙了,我们先不管它了,蛇掉头的问题的话就是这样,比如说现在我的舌呢,它是往往右走的,往右走的走走。走蛇在往右走的时候,你不能往左走,你往左走这个就是掉头,对吧?同理我舌在往上走的时候,往上走的时候,这个时候你不能按下,你按下了这就算掉头,掉头是不是就不行了,哎,掉头就不行,所以这个验证呢,很显然我们应该也是在我们这个set X set y里边去验证,那我们来看一下我们set X,当我们去调用这个set X的时候,我们是修改的这个水平方向坐标,哎,也就是说在这我写个注释吧,啊写个注释,写个注释,哎,我们修改这个X时。
21:04
诶是在干嘛呀,诶X是是是是是是在修改我们这个水平坐标,也就是我们这个蛇在什么呢?在左右移动啊,蛇在左右移动,那蛇在什么呢?蛇在向左移动时。向左移动时,他不能什么呢?不能往右走。不能往右走,不能掉头啊,不能往右走。哎,不能向右掉头。简单写了啊,反之亦然,也就是我这个蛇在向这个右走的时候,我向右走的时候,它不能向左掉头,蛇是禁止掉头的,那我怎么判断呢?首先我们在这儿,当你去set X的时候,我们这就已经明确了,哎,这个时候是在修改X值,修改X值我们就知道已经已经知道蛇要么是在向左走,要么就是在向右走,这种情况我们是禁止发生的,那怎么就知道它掉头了?
22:07
怎么我们就知道我们的这个值是在掉头?我们想一下。那掉头实际上是什么?为什么不能掉头?当我蛇往上走的时候,如果它想往下走,它下边是不是有第二个元,有这个有这个第二个元素啊,诶有第二个元素,那你这是不是就发生掉头了?换句话说,你舌头的坐标如果和你第二节的这个身体的坐标一样了,那是不是就证明你这个蛇发生掉头了,哎,就证明这个蛇发生掉头了,所以我们要做的事儿就是判断什么呢?判断蛇头的X坐标和这个第二节身体的X坐标是否一样,如果是一样,那就是掉头了,不一样那就没掉头对不对?所以在这我们要做一个判断,判断蛇头的X轴坐标和第二节身体的X坐标是不是一样,如果一样,那么就是,哎,就是掉头。那这里边还有一点我们需要注意的是,第二节身体它不一定有,一上来只有一个舌头,是不是没有第二节身体啊,所以我们在判断的时候,还应该先判断到底有没有第二节身体。所以这里。
23:14
那我们要做的判断是什么呢?If z次点一个bodies,中号一个一,先检查有没有第二级身体,然后同时再检查这点一个bodies,点一个off set off set一个什么呀,X坐标嘛,Off set left,哎,这还有这个问题,还有这个问题就是什么呀,我们要做这个断言啊,As,一个HTML element。中号一个,哎,啊做这个断言,哎,如果。Body存在,然后呢,第二节身体的off left还等等于你这个Y6 Y6是谁啊?Y6是不是我们要设置的这个值啊,哎,我们要设置的这个新值。那这个时候就说明发生水平方向掉头了,所以我们直接来一个cancel点落了什么呢?水平方向发生了掉头,发生了掉头。
24:10
哎,那这样就是不是给他判断出来了,我们这么改完了啊,我们试一下看看对不对啊,看看对不对。在这啊确定一下。重新加载,OK,完事,加载完了,现在注意啊,我只有一个头的时候,你爱怎么掉怎么掉,这无所谓,掉不了头,但是现在看着。你看啊,控制台没有打印,打印提示,现在我有两节身体。还是我往右走,是不是水平方向发生掉头了,往左走,诶这往右走啊,现在往右走,往左走是不是又掉头了,哎,你看我后边前边打印啊,前边打印每一次掉头它都给我有这个提示,我不掉头可以正常去走,掉头的时候就会发生这个提示,水平方向我们这儿就判断出来了,但是你判断完了,你要怎么处理啊,怎么处理啊,两种方式我们可以做一种逻辑,就是掉头的时候我直接让游戏结束,游戏结束,但是这样的话它不太好,对吧,不太好,因为你掉个头啊,它是错了,但是你也不至于游戏结束,你就别让它掉就完事了,是吧,你应该是禁止这个功能,所以这个时候的话,我们再回到这儿来,如果发生了掉头。
25:20
哎,如果发生了我们这个掉头,那这个时候我们应该干嘛,我们应该让这个蛇向什么呢?向反方向继续移动。反方向继续移动啥意思,你这是掉头了,掉头了,本来我这是向向向向向右走的,向右走的我我然后摁了一下向左,向左掉头了,不让你掉,不让你掉怎么办?不让你掉那你就应该继续干嘛,继续向右走是不是这个意思,哎,让你继续向右走,诶那问题来了,我怎么判断我们这个蛇的移动方向啊,哎,蛇的移动方向,那我们说了,向右走我们的life的值应该是增大的,对吧?向左走我的life应该是减小的,所以这个时候我们要判断的话,我们直接判断一下if什么的。
26:15
If,我们这个Y6 Y6大于我们这个Z点一个X。如果Y6大于z.X那证明我们这个life的值我是改大了,改大了那是不是就向右走啊,哎,向右走,所以如果我们这个心。Value。大于我们这个就值X,则说明我们这个蛇干嘛呢?诶蛇在向在哪啊,诶向右走向右走,但是向右走是向右走,向右走是不是发生掉头啊,哎,此时发生掉头。我们应该干嘛发生这个掉头,哎,我们应该使这个蛇。
27:01
继续干嘛呢,诶向左走。向东走,因为像现在我这个蛇是这么走嘛,它是比如说啊,这样我蛇本来是往左走呢,我摁了一下方向键,向右,向右,它是不是想掉头啊,想掉头,但是这个时候我们是不是不能让它掉头啊,哎,一掉头就出问题了,所以我们应该让蛇干嘛,让蛇是不是继续向左走,哎,继续向左走,所以这个时候如果是向右走,我们就直接来一个Y6,我让它继续向左走,所以我就让Y6等于一个z.X干啥呢?向左走我们减十,然后else else是不是证明我向。左走向向不走时掉头啊,所以这个时候我们就直接来一个Y6等于一个z.X加十加十,也就是我在这儿去修正它的一个方向,你在向,你这是向右走,我就让你减时,继续让你向左走,你这儿是向左走,向左走,但是呢,你这时候发生掉头了,我不能让你走,所以我给你加时,让你继续向右走,那这个时候再发生水平方向掉头的话,你会发现什么效果呢?就是我们摁这个方向键,你就跟没用一样啊,就跟没用一样,我们看看效果。
28:11
现在没事,只有一个舌头,你随便掉啊随便掉,然后我们这吃一个。现在身体变成两截了啊,看这我往右走,你看啊,我现在往右走摁左没用啊,没用来,我现在往左走摁右是不是也没用啊,哎,掉头就给它禁止了,那同样上下,你看上下是不是还能掉啊,所以这套逻辑我们还得在这个,哎这个外轴这再写一遍,但是好还好,我们直接给它复制一下,稍微改吧改吧就能用了,改不改吧,我放到这个移动身体的前面,还是判断这个掉头,掉头的话我们这修改这个外置。修改这个Y时,哎修改这个Y时呢,我们是修改的是什么呀?是这个垂直坐标,垂直坐标,哎舌上什么呢?舌上下移动,上下移动,那舌在向上移动时,哎不能向向下掉头,反之一然这么一个套路都是一样的,所以这里边我们检查的就是什么呢?Y6是不变的,检查的是我们这个off side的一个top,检查的是top值,然后呢,这儿也是就不是X了,就是检查这个Y了啊Y了这个注释我就不改了啊,注释我就给给他,给他给它删了,跟上边一样,你把它参考一下,这东西不难啊,这东西不难,你自己看一下,因为我讲的时候可能会让你感觉到有一点有点乱,呃,主要是你自己得把这个逻辑给他整明白,把这图给他自己的,哎自己去画一下啊,画一下来看效果啊。
29:36
这个时候我们的上下左右的掉头就都没了啊,就都没了。看看效果啊,走一个吃到掉头掉头掉头掉不了了,来往下往上掉掉不了了,往上走往下掉也掉不了了啊,这样的话,我们就成功的解决了这个掉头的问题啊,掉头的问题解决了,我们再看什么呢?再看最后一个,我们就是蛇撞自己的问题,这个我得多吃两截。
30:08
哎呀,这个移动速度实在是太慢了。OK,现在比如说就这种,这是几节了,这是这个好几节了是吧,我们移动现在我是不是可以去撞自己了,哎,可以撞自己,你看撞自己的时候,它可以穿到自己的身体,这个走过去,那这里面我们实际的游戏的话,如果是贪食蛇的话,撞到自己,我们这个游戏是不是应该就结束了,这个也就简单了,非常简单啊,来我们来看一下代码。还是我们先考虑我们这个功能撞自己是在哪,判断我们什么时候有可能撞到自己,是不是就是在我们这个蛇的身体,就是蛇在移动的时候,什么移动是我们这个舌头。以及身体在移动的时候,是不是就可能会发生这个蛇撞到这个自己的情况啊,装到自己情况,所以我们要做的事也是很简单,检查这个蛇有没有撞到自己,我们就是检查什么呢?就是检查这个蛇头的坐标,蛇头的坐标和我们这个什么呢,和我们这个每一个身体的坐标有没有发生这个什么呀,发生这个这个重复,如果身体坐标和舌的这个坐和舌头的坐标发生的这个重复了,那这个时候是不是就证明撞到自己了,哎,就是撞到这个撞到自己了,所以这里边我们要做的事儿就是什么呢?就是要去检查我们这个,我们这儿是不是有一个这个X坐标,还有一个Y坐标,我们要检查什么,就是检查这个舌头的坐标跟这个身体的坐标有没有这个发生这个,哎,发生这个发生这个重复啊发生重复,那这里边我们要检查的话,就会需要涉及到一个问题,那这样的话我们就需要知道舌头。
31:55
头的一个最新的坐标,但是问题是现在蛇头的最新坐标的话,只有在什么呢?只有在我们这个蛇的这个位置改完了我们才知道,也就是像我们这种情况,我这儿把舌头的位置给它改完了,这儿也是把舌头的位置给它改完了,我们在这儿是不是才能知道这个蛇的最新坐标啊,所以我们检查这个身体有没有头,有没有撞到身体的时候,我们应该是在干嘛,在修改完我们这个坐标以后,我们再去检查,所以呢,在这里面我们加一个这个方法。
32:27
加一个方法,加一个方法什么呢?嗯,加一个方法我们叫做一个check,哎,Check这个这个hi head head的这个body,就是检查我们这个头跟这个身体有没有相撞,检查头和身体有没有相撞,我们要做的事儿也是你检查我们身体有很多节,它可能跟任意一节身体相撞是吧?当然第二节不太可能,第三节不太可能,第四节也撞不上,应该是从第五节往后就有可能撞上了,但是我们不管那个不差那几节,我们都检查一遍,所以在这儿我们要获取什么呢?获取所有的这个身体,然后检查是否什么呢?
33:03
检查。哎,起起起起是否和我们这个舌头的这个坐标发生什么呢?发生这个重叠,如果重叠了就证明撞没重叠,是不是就没事儿啊,哎,所以在这儿,哎一样的变利呗,负循环light一个I等于零,这就别零了,我们一我们从一开始变利,因为舌头的坐标我们已经有了啊从一开始变利一,然后我们来一个I小于一个,这个叫做一个Z点一个body点一个Li,然后来一个哀加加添加,从第二节身子开始取,那这里边我们就直接判断了啊直接判断if if什么呀,If z.X等等于我们叫做一个Z点一个中号,哎,还是啊,不要忘了我们这块要给它加上一个这个诶类型的一个断言,这里边这个类型断言啊加吧,现在我们只能用这种处理方式,我这儿我看看我上边我能不能给它指定一个泛型,如果这个H。
34:06
Collection,我能给他指定一个泛型,我看看HT element。看看这啊。这儿给我们报错了,我看一下。啊。H,前面不支持泛型,不支持泛型我没辙了,没辙了,我们只能在这儿去做这个,做这个断言了,啊,做这个断言了。有泛型我们就省事,有泛型我们给指定一下,那边统一转一下行了,但是这儿的话没有泛型,我们就只能是这样手动去处理。好,那这里边我加这个断言,叫做一个S,一个这个HTML element,等等于什么呢?等等于它的一个offet left,哎呀,这样写感觉好麻烦啊,我前面统一做一下吧,Light,我们叫做一个这个BD等于一个它,哎,我整一个变量啊,我给它存起来,存起来那下边我就省事一点,省事一点干嘛呢?我直接写一个BD点一个off set left,然后and这点一个Y,等等于BD点一个off top,也就是我舌头的这个X坐标和我当前这个身体的这个这个左侧偏移量和垂直偏移量发生冲突了,也就是说进入判断说明什么?说明我们这个,诶,说明我们这个舌头它撞到了什么呢?撞到了身体。
35:28
撞到身体怎么办?哎,撞到了身体,撞到了身体我们这个游戏就结束了,游戏结束,游戏结束怎么办?我们还是那个套路,直接死肉一个,这个拗一个error啊拗一个error,抛出一个新的异常干嘛呢?撞到自己了,这个时候啊,我们在那个game game CR这个类里面,我们都不用处理,因为我们那里边直接已经掉过try edge了,它实际上就统一处理了啊装到自己了,然后呢,什么时候检查呢?我先写个注释啊,这个是用来检查舌头是否撞到这个身体的方法,身体的方法什么时候检查,我们在啊X轴坐标,像这个,我们这是不是一个SY呀,哎,Y的坐标发生变化了,在最后我们这掉一个检查有没有撞自己。
36:19
检查有没有撞到自己,直接来一个Z,点一个check head and body。然后呢,SX,那我们也得检查一下子,也得检查一下有没有撞到自己啊,我们来停,这样齐活了,这样齐活了,这个我们再看效果就OK了。感觉这一块的话,整个这块讲的稍微的有点,这个有点有点有点快了是吧,感觉有点快了,所以你们看的时候啊,你可以放慢一点,多看几遍吧,啊我因为他其实逻辑是比较简单的,你自己写的时候,把这整个逻辑自己去串一下去看看啊,我们先看效果,看看还能不能撞自己了,就是看到看看撞自己的时候游戏会不会结束。
37:10
诶,现在可以撞了,诶你看是不是撞到自己了,诶gameover游戏就结束了啊,游戏结束了,停到什么呀?停,而且还停到了他最后那个撞到自己那个状态,那这样的话,我们整个这个游戏就给他完成了,但是我们还没有测试到他那个等级的感觉,就是当我升到十级的时候,这个速度会不会加快,那因为我们现在是十分升一级,十分升一级我得吃半天吃100个才能到十级,所以呢,这里边我想把这个升级的速度啊变快一点,我们能看到效果更更更好一点,这个会改谁呢?我们之前已经设计好了,我们说了,我们在这个创建我们这个score p的时候,它里面是不是可以传两个参数啊,一个是等最高等级,还有一个是每级升级的一个分数,所以我们在game control里边,我们之前调的候,我没有给它传参数,这回我传一个参数十,最高等级是十,然后呢,我让他每两分就升一级,每两分升一级,加快我们这个游戏的节奏,我们来看一下他这个级别高了以。
38:10
会不会有什么问题啊,会不会有什么问题好直接执行。看一下两分就升一级啊,再吃一个应该就升级了。还还是好卖,我应该做一个一分就升一级了,诶你看现在变成二级了,速度呢,稍微的有一些,这个有一些增加啊,有些增加。哎,再吃一个,哎呀,不知不觉突然诶三级了对吧。诶,这是五分了,再吃一个就六级了,我把这给它关掉了啊,我们可以把包那个滚动条给它进了,进了以后就没有那滚动条的问题了,现在呢是四级了,又加快了来再吃一个,再吃一个应该就五级了。哎呀,好无聊啊。来,慢慢吃。所以你们在做这个练习的时候,这个练习整体来说难度并不大,就是尤其是就我们这个代码来讲,你只要把这个这个整个一个逻辑,你需要自己去摸索一下啊,自己摸索一下这个逻辑。
39:12
哎。现在是11级了,11级了,赶紧的赶紧的,赶紧的赶紧的。不是11级啊,11分啊,七级了,再吃两个就八级了。诶八级了,来来来来来,赶紧赶紧,哎呀游戏好刺激,你看这个速度明显就加快了,但是我这个现在的话,因为我是哎呀九级了。哎呀,十级了,哎呀呀呀呀,十级有点太快了。完了死了,他也不是故意想死的是吧,实在是太快了,所以这样的话,我们整个这个贪食蛇这个游戏的话,我们就算是给他完成了,最后这个视频我其实应该分两个的,等于录在一起了,录在一起稍微有点长,尤其是后边我们那个撞身体,还有那个这个这个这个掉头这块讲的可能稍微有点快啊,但是呢,这个代码并不难啊,重点是你自己呢,需要把这个逻辑的整理一下,你可以自己呢去画一下图,最好你可以直接在这个纸啊纸纸啊本笔上画,用笔画一个,可能你会理解的更透彻一点。
40:21
但是整体来说的话,代码的话,哎,并不难啊,并不难,你会能第一次,如果你第一次用类去写这个东西的话,你会觉得有点有点这个有点麻烦,但是其实我们面向对象确实是,呃,写代码的时候思路上会确实是会稍微有点麻烦,但是一旦把你你把这个项目搭建完了以后,我们维护起来就会比较容易,为什么呢?因为我们的所有的代码都是以这个模块,以这个类去区分的,每一个类都有它不同的作用,我们在维护的时候,我们只需要找到这个对应的类去对这个代码进行修改就OK了,再加上我们有了这个TS,他帮我们做这个类型检查,所以这个东西的话,前期开发起来可能会慢一点,但是你熟悉了以后,其实这个慢的话,我们是可以忽略不计的,但是当我们去做一些大型项目,当我们去想去维护这些项目的时候,提高这个项目的可维护性的时候,这种模式一定会让我们的项目更易于维护,但是并不是说你用类项目就易于维护,而是你这个。
41:22
这类要设计的比较的好才可以,但是呢,话又说回来,类的这个设计的话,它不是说一朝一夕就积累出来的,我们需要通过实际开发,通过这个经验的积累来扩充这块知识,但是还是那句话,诶,慢慢来,不着急诶,代码没有那么难敲的,多了自然就会了,好,我们这个项目就说这么多。
我来说两句