C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(六)完美移动

经过前面的介绍和学习,我们分别掌握了如何点击鼠标让对象移动,并且实现2D人物的动作动画。那么,如何将两者完美的进行融合呢?这一节的内容将涉及到很多重要的技术及技巧,很关键哦。

   那么同样的,前台xaml还是保持不变,接下来看后台C#第一部分:

        int count = 0;
        Image Spirit;
        Storyboard storyboard;
        public Window6() {
            InitializeComponent();
            Spirit = new Image();
            Spirit.Width = 150;
            Spirit.Height = 150;
            Carrier.Children.Add(Spirit);
            Canvas.SetLeft(Spirit, 0);
            Canvas.SetTop(Spirit, 0);
            DispatcherTimer dispatcherTimer = new DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = TimeSpan.FromMilliseconds(150);
            dispatcherTimer.Start();
        }
        private void dispatcherTimer_Tick(object sender, EventArgs e) {
           Spirit.Source = new BitmapImage((new Uri(@"Player" + count + ".png", UriKind.Relative)));
            count = count == 7 ? 0 : count + 1;
        }

上面代码基本上相对于前面几节没有太多改变,只是结合了第一节和第四节的内容。

   那么再看C#第二部分:

   private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            Point p = e.GetPosition(Carrier);
            Move(p);
   }
   private void Move(Point p) {
            //创建移动动画
            storyboard = new Storyboard();
            //创建X轴方向动画
            DoubleAnimation doubleAnimation = new DoubleAnimation(
              Canvas.GetLeft(Spirit),
              p.X,
              new Duration(TimeSpan.FromSeconds(1))
            );
            Storyboard.SetTarget(doubleAnimation, Spirit);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
            storyboard.Children.Add(doubleAnimation);
            //创建Y轴方向动画
            doubleAnimation = new DoubleAnimation(
              Canvas.GetTop(Spirit),
              p.Y,
              new Duration(TimeSpan.FromSeconds(1))
            );
            Storyboard.SetTarget(doubleAnimation, Spirit);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
            storyboard.Children.Add(doubleAnimation);
            //将动画动态加载进资源内
            if (!Resources.Contains("rectAnimation")) {
                Resources.Add("rectAnimation", storyboard);
            }
            //动画播放
            storyboard.Begin();
   }

不难看出鼠标左键点击事件中Move()方法,该方法大家如果熟悉第一节的话将非常好理解,通过将这两段代码进行合成,即可以实现鼠标点哪主角就向哪移动,同时主角的动画始终保持为跑步状态。

   那么该动画并非完美,存在以下3个问题:

   一、主角始终为跑步状态,那么能否当主角移动到目的地后即变成站立状态呢?

   of course,方法不要太多,这里我给大家一个小提示,例如我们可以dispatcherTimer_Tick事件中进行如下判断:

   if (storyboard != null && storyboard.GetCurrentTime() == TimeSpan.FromSeconds(1)) {

   TODO... 

   //主角的图片源切换成站立系列帧图片即可。

   }

   当然此方法只是N多方法之一。

    二、主角定位的坐标始终处于图片的左上角,能否定位到主角的脚底,例如我鼠标点哪,主角移动到该处后脚的位置站在此点上,实现精确定位?

   这其实并不难,涉及到一个图片定位算法问题,您需要设置一个Point Spirit_Position{get;set}属性来存储主角的坐标。并且该坐标的Spirit_Position.X,Spirit_Position.Y值分别定位到主角的脚底,如下图:

   然后在以后的调用中都使用该坐标来取代Canvas.getLeft(),Canvas.getTop()。

   三、主角朝向如何实现8个方向,即往哪边跑就朝向哪边?

   这就是典型的算法问题了,其实也很简单,根据主角移动的目标Target.X和Target.Y分别与主角初始位置的Old.X和Old.Y进行一个角度计算,然后根据判断返回0-7(int),8个数字分别代表8个朝向,这样在Spirit.Source设置时就调用相应角度的图片源系列帧即可。

 

   到此,我们已经能够完美的实现角色的移动与停止等动画,接下来的章节我将就地图结构与主角在地图中的处理进行详细讲解,敬请关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值