所有文章搬运自我的个人主页:sheilasun.me

去年风靡微信朋友圈的小游戏“围住神经猫”,我也试着做了一下,可以戳这里试玩→围住神经猫。游戏是用Egret引擎开发的,因为Egret是用Typescript语言构建的,因此这里游戏也是用Typescript来开发的。

完整的代码可以戳我的Github→sheila1227/HTML5-GAME-shenjingcat

游戏规则:

点击画面上的灰色格子,慢慢将神经猫围起来抓住。如果猫到达游戏区边缘则游戏失败。

准备素材

在网上搜索“围住神经猫”游戏,打开一个,并打开调试界面,从network中或者resource中把猫、灰色圆圈、橙色圆圈等图片扒下来保存到本地。

需要注意的是,Egret新的MovieCilp架构设计以及MovieClip数据格式标准都与早期有些不同,我从网上扒下来的已经不适用了,根据新的数据格式标准做修改后mc的json文件如下:

  1. {"mc":{
  2. "stay":{
  3. "frameRate":20,
  4. "labels":[],
  5. "frames":[
  6. {"res":"stay0000","x":0,"y":0},
  7. {"res":"stay0001","x":0,"y":0},
  8. {"res":"stay0002","x":0,"y":0},
  9. {"res":"stay0003","x":0,"y":0},
  10. {"res":"stay0004","x":0,"y":0},
  11. {"res":"stay0005","x":0,"y":0},
  12. {"res":"stay0006","x":0,"y":0},
  13. {"res":"stay0007","x":0,"y":0},
  14. {"res":"stay0008","x":0,"y":0},
  15. {"res":"stay0009","x":0,"y":0},
  16. {"res":"stay0010","x":0,"y":0},
  17. {"res":"stay0011","x":0,"y":0},
  18. {"res":"stay0012","x":0,"y":0},
  19. {"res":"stay0013","x":0,"y":0},
  20. {"res":"stay0014","x":0,"y":0},
  21. {"res":"stay0015","x":0,"y":0}
  22. ]
  23. }},
  24. "res":{
  25. "stay0000": {"x":0,"y":0,"w":61,"h":93},
  26. "stay0001": {"x":61,"y":0,"w":61,"h":93},
  27. "stay0002": {"x":122,"y":0,"w":61,"h":93},
  28. "stay0003": {"x":183,"y":0,"w":61,"h":93},
  29. "stay0004": {"x":0,"y":93,"w":61,"h":93},
  30. "stay0005": {"x":61,"y":93,"w":61,"h":93},
  31. "stay0006": {"x":122,"y":93,"w":61,"h":93},
  32. "stay0007": {"x":183,"y":93,"w":61,"h":93},
  33. "stay0008": {"x":0,"y":186,"w":61,"h":93},
  34. "stay0009": {"x":61,"y":186,"w":61,"h":93},
  35. "stay0010": {"x":122,"y":186,"w":61,"h":93},
  36. "stay0011": {"x":183,"y":186,"w":61,"h":93},
  37. "stay0012": {"x":0,"y":279,"w":61,"h":93},
  38. "stay0013": {"x":61,"y":279,"w":61,"h":93},
  39. "stay0014": {"x":122,"y":279,"w":61,"h":93},
  40. "stay0015": {"x":183,"y":279,"w":61,"h":93}
  41. }}

编写代码

主要总结下我在开发过程中遇到的主要的两个难题。

问题一,猫该如何逃跑?

在这个游戏中,每个圆圈都可能有三种状态

  • 可通行,灰色圆圈表示
  • 有路障,不可行,橙色圆圈表示
  • 被猫占领,灰色圆圈,猫的动画叠置于其上

每当点击了灰色圆圈,就会将其变成橙色圆圈即路障状态,同时猫会紧跟着点击的动作也向周边走一步。

行走方向

游戏区由9*9个圆圈组成,偶数行缩进圆圈半径大小的宽度,这样的布局导致,猫理论上可以有6个行走方向(每次只能走一步),分别是左,左上,右上,右,右下,左下,如这些位置上的圆圈为路障状态,则相应方向不可通行。

如果这六个方向的邻居有五个都为路障,那当然很好选择线路,剩下的那个就是唯一的出路了,但是显然情况不可能如此简单。我们遇到的更多的情况是,六个方向的邻居上,有直接为路障状态的(那自然绝对不走这一步),有是可通行状态的,但是彼此向边缘的可达性不同。

![此处输入图片的描述][2]

比如上图中,目前,猫的左方向走三步即可到达边缘,右上、右下向走四步可达,左上、右方向上可走一步但即遇路障,左下方向走三步遇路障。这时候我们当然应该为这六个方向的优先级排个序。

优先级

我是这样设定优先级顺序的:

  • 一路通行的方向>会出现路障的方向,如此图中左、右上、右下>左上、右、左下
  • 一路通行的方向中,离边缘越近优先级越高,如此图中左>右上、右下
  • 会出现路障的方向中,可走的步数越多优先级越高,如此图中左下>右、左上

下面将这些约定的可达性用数值来体现以便比较,设这个值为accessibility,值越大优先级越高。

  • 一路通行的方向

    1. accessibility = 1/stepToEdge; //stepToEdge表示离边缘还有几步
  • 会出现路障的方向

    1. accessibility = (-1)/stepToBlock;//stepToBlock表示离路障的距离

接下来考虑分母如果为0怎么办,在第一种情况中,分母为0,表示猫当前已经在边缘了,那么也不用判断优先级了,游戏已经失败了。第二种情况中,分母为0表示出门即遇路障,这个方向不用考虑了是绝对走不通的,那么它的优先级就定为-1。

这样一轮算下来,六个方向上的accessibility值分别为:

  • 左:1/3
  • 左上:-1
  • 右上:1/4
  • 右:-1
  • 右下:1/4
  • 左下:-1/3

这样比较下来优先级应该是左>右上>右下>左下>左上>右。

为什么左上与右,右上与右下,这两组内部的值明明一样,我们依然是排出了顺序呢?只是因为我们计算是从左方向开始顺时针旋转的。如果值一样,那就看出现的顺序了。

所以在上图中这种情况下,猫会向左走一步。

问题二,如何判断猫被围住了?

在网上玩这个游戏的时候,我发现当猫被围住的时候会换成一种“被围住”的动作,那么该如何判断猫被围住了,然后改变它的动作动画?

“被围住”与“被抓住”不一样,它早于“被抓住”的状态。当猫无路可走的时候,它就“被抓住”了,游戏获胜。而“被围住”指的是猫暂时还有路可走,但是已经被包围住了,垂死挣扎而已,如下图。

![此处输入图片的描述][3]

我的思路是这样的:

从猫当前的位置找六个方向中可通行的邻居,然后从这些邻居出发,再找它们各自的可通行邻居,一直这样找下去,一边找的过程中,一边判断当前已经找到的邻居中有没有处在游戏区边缘的,如果有,那么寻找过程提前结束,判断结果是:猫没有被围住。如果直到所有的可通行邻居都找到了,里面都没有处在游戏区边缘的,那么判断结果是:猫被围住了。

接下来用代码实现这个判断过程。

首先,需要准备一个方法,判断圆圈是否已经处在圆圈边缘了,假设这个方法名及参数如下,内部实现比较简单这里就不贴了。

  1. /*
  2. 判断传入的circle是否在边界上
  3. */
  4. private isCircleAtEdge(circle:Circle):boolean {
  5. ...
  6. }

再准备一个方法,获取某圆圈周围某方向的邻居。

  1. private getCircleNeighbor(circle:Circle,direction:Direction):Circle{
  2. ...
  3. }

最后,是判断的核心方法。

  1. /*
  2. 能否在circle位置出发找到路线到达边缘
  3. */
  4. private canExitAt(circle:Circle):boolean{
  5. var ignoreArr=[];//不用再处理的circle集合
  6. var toDealWithArr=[circle];//还需进行判断的circle集合
  7. while(true){
  8. if(toDealWithArr.length<1){
  9. return false;
  10. }else{
  11. var _first=toDealWithArr.shift();
  12. ignoreArr.push(_first);
  13. if(_first.getStatus()!==CircleStatus.Blocked&&this.isCircleAtEdge(_first)){
  14. return true;
  15. }else{
  16. for(var i=Direction.LEFT;i<=Direction.BOTTOM_LEFT;i++){
  17. var nbr=this.getCircleNeighbor(_first,i);
  18. if(!(ignoreArr.indexOf(nbr)>-1||toDealWithArr.indexOf(nbr)>-1))
  19. if(nbr.getStatus()!==CircleStatus.Available){
  20. ignoreArr.push(nbr);
  21. }else{
  22. toDealWithArr.push(nbr);
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }

在方法体的最开始,准备好两个数组,一个用来存储不用再处理的圆圈集合ignoreArr,另一个用来存储还需要进行判断的圆圈集合toDealWithArr。每找到一个可通行的邻居,首先要判断它是不是第一次出现(因为几个圆圈可能会有共同的邻居,所以一个圆圈可能因为它是多个圆圈的邻居而被找到多次),判断的标准就是它有没有出现在ignoreArr或toDealWithArr里,如果没有那么就是第一次出现,如果它是路障,那么塞到ignoreArr,如果不是路障,那么推入toDealWithArr尾部等待判断。

每次循环开始时,我们会从toDealWithArr头部弹出一个圆圈对象,对它是否在边缘做判断,如果是,那么返回true跳出循环,猫没有被围住,它可以通过某条路线到达边缘。如果toDealWithArr全部判断完了都不在边缘,那么返回false,猫被围住了,它的直接邻居及众多间接邻居中没有一个是在边缘的。

完整的代码可以戳我的Github→sheila1227/HTML5-GAME-shenjingcat

在线试玩可以戳→围住神经猫

有任何不妥之处或错误欢迎各位指出,不胜感激~

HTML5游戏 围住神经猫 开发的更多相关文章

  1. [转载]HTML5游戏前端开发秘籍

    http://isux.tencent.com/html5-game-development-cheats.html 转载至腾讯ISUX HTML5游戏前端开发秘籍 本文由米随随编写 QQ空间Andr ...

  2. 论文的构思!姚小白的html5游戏设计开发与构思----给审核我论文的导师看的

    此处只为笔记 游戏么基本上确定是用canvas做个能一只手玩的游戏!基本打飞机之类的.毕竟手机也就上下班玩玩的.上下班么基本就是一只手拉着扶手一只手撸啊撸! 当然啦,如果能搞出超级牛逼的游戏,比如刺客 ...

  3. HTML5游戏2D开发引擎

    1.PixiJS(基于webGl和canvas) 官网:http://www.pixijs.com/ github(star:20672):https://github.com/pixijs/pixi ...

  4. 自动化的基于TypeScript的HTML5游戏开发

    自动化的开发流程 在HTML5游戏开发或者说在Web客户端开发中,对项目代码进行修改之后,一般来说,需要手动刷新浏览器来查看代码修改后运行结果.这种手动的方式费时费力,降低了开发效率.另外,如果我们使 ...

  5. 开源免费的HTML5游戏引擎

    青瓷引擎的成长 青瓷引擎自2015年4月项目启动开始,7月首次亮相2015年ChinaJoy,便得到业界的极大关注,随后开启限量测试,收到数百个开发者团队的试用申请及反馈,期间经历了18个内测版本,完 ...

  6. 开源免费的HTML5游戏引擎——青瓷引擎(QICI Engine) 1.0正式版发布了!

    青瓷引擎的成长 青瓷引擎自2015年4月项目启动开始,7月首次亮相2015年ChinaJoy,便得到业界的极大关注,随后开启限量测试,收到数百个开发者团队的试用申请及反馈,期间经历了18个内测版本,完 ...

  7. 20款最受欢迎的HTML5游戏引擎收集

    在“最火HTML5 JavaScript游戏引擎”系列文章国外篇(一)中,我们盘点了当下备受开发者推崇的非国产HTML5和JavaScript游戏引擎.在各种2D小游戏逆袭的今天,用HTML5和Jav ...

  8. TypeScript的HTML5游戏

    wildfirecode 自动化的基于TypeScript的HTML5游戏开发 自动化的开发流程 在HTML5游戏开发或者说在Web客户端开发中,对项目代码进行修改之后,一般来说,需要手动刷新浏览器来 ...

  9. JS开发HTML5游戏《神奇的六边形》(一)

    近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...

随机推荐

  1. spring web.xml 难点配置总结【转】

    web.xml web.xml是所有web项目的根源,没有它,任何web项目都启动不了,所以有必要了解相关的配置. ContextLoderListener,ContextLoaderServlet, ...

  2. spring boot(十一):Spring boot中mongodb的使用

    mongodb简介 传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成, MongoDB是由数据库(database).集合(collection ...

  3. VS复制文件到输出目录

    1.选中项目文件 2. 3.编译时就会自动创建目录,并复制文件

  4. ICS Hack Tools

    参考链接:http://icstraining.org/en/security-tools/configurations ICS-Security-Tool: https://github.com/I ...

  5. js 将很长的内容进行页面分页显示

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 用代码生成UINavigationController 与UITabBarController相结合的简单QQ框架(部分)

    首先我们需要搭建一个空的项目,当然xcode6.0以后不支持直接创建空项目,所以我们需要在系统生成项目之后,删除xcode自动给你生成的控制器和storyboard,另外需要在Main Interfa ...

  7. linux 命令格式

    1.命令  选项   参数 选项——短选项: - 多个选项可以合在一起书写 ——长选项:-- 选项是一个word 参数:命令的作用对象   ls -la  /etc   /opt 2.su  swit ...

  8. Latex 公式颜色

    如何给这个公式加上颜色? 解决方法: \usepackage{xcolor} \begin{align}   \textcolor{red}{\int_a^b}\textcolor{blue}{f(x ...

  9. latex对齐问题

    数学公式居中:可以在公式前后各加两个$$,就可以了 一行对齐:左对齐\leftline{内容} 居中\centerline{内容} 右对齐\rightline{内容} 多行或者段落对齐: 左对齐 \b ...

  10. keras例子-matchnet

    2015CVPR:MatchNet_ Unifying Feature and Metric Learning for Patch-Based Matching 主要是基于patch的图像特征匹配,基 ...