Home  >  Article  >  Web Front-end  >  Pure HTML5 production of the Nervous Cat Game - with source code download_javascript skills

Pure HTML5 production of the Nervous Cat Game - with source code download_javascript skills

WBOY
WBOYOriginal
2016-05-16 15:43:302421browse

The web version of the HTML5 Surround the Nervous Cat game is a game based on HTML5, jquery, Typescript and other technologies.

Attached to you is the demo and source code download, click here View the demo Download the source code

I also tried to play the mini-game "Surround Nervous Cat" which was popular in WeChat Moments last year. The game is developed using the Egret engine, and since Egret is built using the Typescript language, the game here is also developed using Typescript.

Game rules:

Click on the gray grid on the screen to slowly surround the nervous cat and catch it. The game is lost if the cat reaches the edge of the play area.

Prepare materials

Search the Internet for the "Surround the Nervous Cat" game, open one, and open the debugging interface. Remove the pictures of cats, gray circles, orange circles, etc. from the network or resources and save them locally.

It should be noted that Egret’s new MovieCilp architecture design and MovieClip data format standard are somewhat different from the earlier ones. What I picked up from the Internet is no longer applicable. The json file of mc after modification according to the new data format standard is as follows :

{"mc":{
 "stay":{
 "frameRate":20,
 "labels":[],
 "frames":[
   {"res":"stay0000","x":0,"y":0},
   {"res":"stay0001","x":0,"y":0},
   {"res":"stay0002","x":0,"y":0},
   {"res":"stay0003","x":0,"y":0},
   {"res":"stay0004","x":0,"y":0},
   {"res":"stay0005","x":0,"y":0},
   {"res":"stay0006","x":0,"y":0},
   {"res":"stay0007","x":0,"y":0},
   {"res":"stay0008","x":0,"y":0},
   {"res":"stay0009","x":0,"y":0},
   {"res":"stay0010","x":0,"y":0},
   {"res":"stay0011","x":0,"y":0},
   {"res":"stay0012","x":0,"y":0},
   {"res":"stay0013","x":0,"y":0},
   {"res":"stay0014","x":0,"y":0},
   {"res":"stay0015","x":0,"y":0}
 ]
 }},
 "res":{
  "stay0000": {"x":0,"y":0,"w":61,"h":93},
  "stay0001": {"x":61,"y":0,"w":61,"h":93},
  "stay0002": {"x":122,"y":0,"w":61,"h":93},
  "stay0003": {"x":183,"y":0,"w":61,"h":93},
  "stay0004": {"x":0,"y":93,"w":61,"h":93},
  "stay0005": {"x":61,"y":93,"w":61,"h":93},
  "stay0006": {"x":122,"y":93,"w":61,"h":93},
  "stay0007": {"x":183,"y":93,"w":61,"h":93},
  "stay0008": {"x":0,"y":186,"w":61,"h":93},
  "stay0009": {"x":61,"y":186,"w":61,"h":93},
  "stay0010": {"x":122,"y":186,"w":61,"h":93},
  "stay0011": {"x":183,"y":186,"w":61,"h":93},
  "stay0012": {"x":0,"y":279,"w":61,"h":93},
  "stay0013": {"x":61,"y":279,"w":61,"h":93},
  "stay0014": {"x":122,"y":279,"w":61,"h":93},
  "stay0015": {"x":183,"y":279,"w":61,"h":93}
 }}

Write code

Mainly summarize the two main problems I encountered during the development process.

Question 1, how should a cat escape?

In this game, each circle may have three states

is passable, gray circle indicates

There is a roadblock and it is not feasible, indicated by an orange circle

Occupied by a cat, gray circle with cat animation superimposed on it

Whenever you click on the gray circle, it will turn into an orange circle, which is the roadblock state. At the same time, the cat will follow the click and take a step to the surrounding area.

Walking direction

The game area is composed of 9*9 circles, and the even-numbered lines are indented by the width of the radius of the circle. This layout results in that the cat can theoretically have 6 walking directions (only one step at a time), namely left, Upper left, upper right, right, lower right, lower left. If the circles at these positions are roadblocks, the corresponding directions are impassable.

If five of the six neighbors in the six directions are roadblocks, then of course it is easy to choose a route, and the remaining one is the only way out, but obviously the situation cannot be that simple. The more common situations we encounter are that among the neighbors in the six directions, some are directly in the roadblock state (naturally, we will never take this step), and some are in the passable state, but the accessibility to the edges of each other is different.

For example, in the picture above, currently, the cat can reach the edge by taking three steps in the left direction, four steps in the upper right and lower right directions, it can reach the edge by taking one step in the upper left and right directions but encounters a roadblock, and it can reach the edge by walking three steps in the lower left direction. Hitting a roadblock. At this time, of course we should rank the priorities of these six directions.

Priority

This is how I set my priorities:

The direction of traffic> will show the direction of the roadblock, as shown in the picture: left, upper right, lower right> left upper, right, lower left

In the direction of traffic, the closer to the edge, the higher the priority, as shown in the picture: left > right, upper right, lower right

In the direction where roadblocks will appear, the more steps you can take, the higher the priority, as shown in the picture below left > right, upper left

The accessibility of these agreements is expressed as a numerical value for comparison. Let this value be accessibility. The larger the value, the higher the priority.

Direction of travel

accessibility = 1/stepToEdge; //stepToEdge indicates how many steps are left from the edge

The direction where the roadblock will appear

accessibility = (-1)/stepToBlock;//stepToBlock represents the distance from the roadblock

Next, consider what to do if the denominator is 0. In the first case, the denominator is 0, which means that the cat is currently on the edge, so there is no need to judge the priority, and the game has failed. In the second case, a denominator of 0 means that you will encounter a roadblock when you go out. This direction is absolutely unreachable without considering it, so its priority is set to -1.

After this calculation, the accessibility values ​​in the six directions are:

Left: 1/3

Top left: -1

Top right: 1/4

Right: -1

Bottom right: 1/4

Bottom left: -1/3

In this comparison, the priority should be left > upper right > lower right > lower left > upper left > right.

Why are the values ​​inside the upper left and right, upper right and lower right groups clearly the same, but we still arrange them in order? Just because our calculation starts from the left direction and rotates clockwise. If the values ​​are the same, then it depends on the order in which they appear.

So in this situation in the picture above, the cat will take a step to the left.

Question 2, how to tell if a cat is surrounded?

While playing this game online, I found that when a cat is surrounded, it will change to a "surrounded" action. So how to judge that the cat is surrounded and then change its action animation?

"Besieged" is not the same as "caught", it precedes the state of "caught". When the cat has nowhere to go, it is "caught" and the game is won. "Surrounded" means that the cat still has a way to go, but it is surrounded and is struggling to its death, as shown in the picture below.

My idea is this:

Find the passable neighbors in the six directions from the cat’s current position, and then start from these neighbors to find their respective passable neighbors. Keep searching in this way, and while searching, judge the ones that have been found so far. Are there any neighbors on the edge of the play area? If so, the search process ends early, and the judgment result is: the cat is not surrounded. If all passable neighbors are found and none of them are at the edge of the game area, then the judgment result is: the cat is surrounded.
Next, use code to implement this judgment process.

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

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

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

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

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

/*
能否在circle位置出发找到路线到达边缘
*/
private canExitAt(circle:Circle):boolean{
 var ignoreArr=[];//不用再处理的circle集合
 var toDealWithArr=[circle];//还需进行判断的circle集合
 while(true){
  if(toDealWithArr.length<1){
   return false;
  }else{
   var _first=toDealWithArr.shift();
   ignoreArr.push(_first);
   if(_first.getStatus()!==CircleStatus.Blocked&&this.isCircleAtEdge(_first)){
    return true;
   }else{
    for(var i=Direction.LEFT;i<=Direction.BOTTOM_LEFT;i++){
     var nbr=this.getCircleNeighbor(_first,i);
     if(!(ignoreArr.indexOf(nbr)>-1||toDealWithArr.indexOf(nbr)>-1))
     if(nbr.getStatus()!==CircleStatus.Available){
      ignoreArr.push(nbr);
     }else{
      toDealWithArr.push(nbr);
     }
    }
   }
  }
 }
}

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

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

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn