In the last 6 chapters, we cover many techniques, including the object moving from one place to another one, and the sprite’s own animation. This chapter I will merge both of them, to implement sprite’s animation perfectly.
Let’s merge the code from Chapter 1 and Chapter 4, as follows:
public partial class MainPage : UserControl { private int count = 1; private Image sprite; private Storyboard storyboard; public MainPage() { InitializeComponent(); sprite = new Image() { Width = 150, Height = 150 }; Carrier.Children.Add(sprite); Canvas.SetLeft(sprite, 0); Canvas.SetTop(sprite, 0); DispatcherTimer dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Tick += dispatcherTimer_Tick; dispatcherTimer.Interval = TimeSpan.FromMilliseconds(200); dispatcherTimer.Start(); } void dispatcherTimer_Tick(object sender, EventArgs e) { sprite.Source = new BitmapImage((new Uri(@"/Images/Role/" + count + ".png", UriKind.Relative))); count = count == 7 ? 0 : count + 1; } private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Point p = e.GetPosition(Carrier); Move(p); } private void Move(Point p) { storyboard = new Storyboard(); //create animation in X coordinate DoubleAnimation doubleAnimation = new DoubleAnimation() { From = Canvas.GetLeft(sprite), To = p.X, Duration = new Duration(TimeSpan.FromSeconds(1)) }; Storyboard.SetTarget(doubleAnimation, sprite); Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)")); storyboard.Children.Add(doubleAnimation); //create animation in Y coordinate doubleAnimation = new DoubleAnimation() { From = Canvas.GetTop(sprite), To = p.Y, Duration = new Duration(TimeSpan.FromSeconds(1)) }; Storyboard.SetTarget(doubleAnimation, sprite); Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)")); storyboard.Children.Add(doubleAnimation); if (!Resources.Contains("rectAnimation")) { Resources.Add("rectAnimation", storyboard); } //play the animation storyboard.Begin(); } }
Press Ctrl+F5, we can see the sprite is running when we click on somewhere in the canvas. But there is still a flaw, When the sprite arrived the distinction, the sprite’s own animation doesn’t stop. So does the init of the game. We must modify dispatcherTimer_Tick method to prevent these 2 scenarios, as follows:
void dispatcherTimer_Tick(object sender, EventArgs e) { if (storyboard == null || storyboard.GetCurrentTime() == TimeSpan.FromSeconds(1)) { sprite.Source = new BitmapImage((new Uri(@"/Images/Role/1.png", UriKind.Relative))); } else { sprite.Source = new BitmapImage((new Uri(@"/Images/Role/" + count + ".png", UriKind.Relative))); } count = count == 7 ? 0 : count + 1; }
In the first condition, we judge if it is the init of the game. In this stage, the storyboard is null.
if (storyboard == null ||
In the second condition, we judge if the sprite arrive the distinction. We compare the interval of the animation in the method Move, if it is equal to 1 second, it means the animation stopped.
(storyboard != null && storyboard.GetCurrentTime() == TimeSpan.FromSeconds(1)))
In both of these 2 scenarios above, we set the sprite’s image to 1.png. It is the sprite’s standing state in all the 8 pictures:
OK, let’s press Ctrl+F5 again, this time the effect is better than before, but still exists 2 problems.
1. When we click on the canvas, supposed the point is (300, 200), we find the sprite doesn’t arrive this point, actually we set the top left corner of the picture to the point(300, 200). There is still a distance from the root of the sprite. How to position accurately in the game? I will resolve it in the following chapters.
2. Now the animation is only suitable for the sprite to move from left to right. If the sprite to move from right to left, the animation is the same, it looks like unreasonable, so does the scenario in other directions. So we must add more pictures in 8 directions to simulate all the case. I will introduce how to design this effect.
Summary: This chapter introduce a perfect animation by merging 2 sub animation.
Next chapter, I will introduce A* algorithm to find the shortest path in the RPG game. Please focus on it.
Chinese friend, you can also visit this Chinese blog if you feel difficult to read English, http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505346.html, part of my article is base on it.
Demo download: http://silverlightrpg.codeplex.com/releases/view/40978