zoukankan      html  css  js  c++  java
  • MMORPG programming in Silverlight Tutorial (7)Perfect animation

        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:

    image

       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

  • 相关阅读:
    4412--PWM驱动部分
    Linux中进程与线程
    Linux 进程间通信 --信号量
    Linux 进程间通信 --消息队列
    Linux 进程间通信 --共享内存
    QByteArray转成十六进制的QString
    网易C++设计模式笔记(二)面向设计对象的原则
    网易C++设计模式笔记(一)
    windows安装系统记录
    设计模式解析第二版 课后习题自我解答
  • 原文地址:https://www.cnblogs.com/Jax/p/1674467.html
Copyright © 2011-2022 走看看