C # development Wpf/silverlight animation and games series Tutorials (Game Course): (20) The first part expands the summary article
Wrote 20 verses, all the way to chasing the devil did not stop, simply also want to take a break to tidy up and finish the second part of the more exciting content: such as follow-map mobile mode, NPC & Monster and protagonist interaction, object AI, Attack and magic, various types of damage calculation, The perfect RPG game interface ... Wait, wait, are you excited? To tell the truth: I am very excited!
Reader's voice: it's starting to get excited before it's written, typical of a fool.
^_^|| To get to the point, this section first to a connecting link of the summary bar, I intend to divide 4 parts of the first 20 section of the content to expand:
A perfect and improved a * seek the way to move the mode
Develop Wpf/silverlight animation and game tutorials in C # (Game Course): (19) The slick of the Perfect Elf (WPF only) ③, although we realize the full direction of the wizard and action, but careful friends will find that the elves in the walk always use a *; This will result in two problems: 1, the loss of performance, each move regardless of whether there are obstacles in the middle to start the search algorithm, resulting in the waste of resources; 2. Develop Wpf/silverlight animation and game series tutorials in C # (Game Course): (12) Magic Copy Map At the end I have understated how to implement the improved A *, although the simple implementation of a copy map, but temporarily not perfect. So, here's what I'm going to tell you about the improved, perfect * Move mode through the way it's done.
What is an improved, perfect * mobile mode? That is, each time the protagonist moves, the first is not to start a A * to find a road, but directly to establish a straight line between two points, then the obstacles to judge the time, if there is no collision to any obstacles or objects will be moved to the end of the line;
The principle is simple, the key technology is how to detect collisions?
There are two kinds of traditional methods:
The first one I called the coordinate reduction method: that is, always record the elves did not collide when the coordinates (OLD_X,OLD_Y), when the wizard moved when the wizard was detected at this point on the obstacle, the elves at this point in the coordinates to restore (x=old_x,y= old_y), and then start a * Seek road. The advantage of this method is that it is simple to use, there is no need for complex judgment logic; The disadvantage is that the effect is not good, in the screen will cause the elves to be bounced off the moment, although the moment is very short and small distance, but for the sprite movement smoothness of the impact is serious, so we had better not adopt this method.
The second is heuristic prediction method: The principle of this method is always in front of the wizard to predict the region, once found in front of obstacles, then immediately start a * find a way to the destination. This method can be said to be absolute royal blood, a word "positive", set all the advantages of the big one, the advantages of more relative to achieve more difficult. How to achieve in the wpf/silverlight? Let's look at the picture below:
The above figure has given a very detailed description, that is, in the line moving process, the wizard always determines whether the cell facing the front is an obstruction, if it is to start a * seek to pass it. After fully understanding the principle, we can return to the wizard to see if the obstacle is going to be encountered:
To determine whether to bump into obstacles (obstacle prediction method)
private bool Willcollide () {
switch ((int) spirit.direction) {
Case 0:
return matrix[(int) (spirit.x/gridsize), (int) (spirit.y/gridsize)-1] = = 0? True:false;
Case 1:
return matrix[(int) (spirit.x/gridsize) + 1, (int) (spirit.y/gridsize)-1] = = 0? True:false;
Case 2:
return matrix[(int) (spirit.x/gridsize) + 1, (int) (spirit.y/gridsize)] = = 0? True:false;
Case 3:
return matrix[(int) (spirit.x/gridsize) + 1, (int) (spirit.y/gridsize) + 1] = = 0? True:false;
Case 4:
return matrix[(int) (spirit.x/gridsize), (int) (spirit.y/gridsize) + 1] = = 0? True:false;
Case 5:
return matrix[(int) (spirit.x/gridsize)-1, (int) (spirit.y/gridsize) + 1] = = 0? True:false;
Case 6:
return matrix[(int) (spirit.x/gridsize)-1, (int) (spirit.y/gridsize)] = = 0? True:false;
Case 7:
return matrix[(int) (spirit.x/gridsize)-1, (int) (spirit.y/gridsize)-1] = = 0? True:false;
Default
return true;
}
}