Silverlight MMORPG网页游戏开发课程[一期] 第一课:控制对象移动

Silverlight MMORPG网页游戏开发课程[一期] 第一课:控制对象移动,第1张

概述引言   游戏中的主角是精灵,我们可以把游戏中的一切对象均视作精灵;玩家大部分时间都在 *** 控着游戏中对象进行移动。因而本节我们要实现的功能只有一个:通过鼠标控制对象移动。   1.1通过Storyboard创建对象移动动画(交叉参考: 让物体动起来①)   在序言中我们讲解了如何通过VisualStudio2010创建一个Silverlight4项目,那么我们首先打开这个项目,并将MainPage.

引言

  游戏中的主角是精灵,我们可以把游戏中的一切对象均视作精灵;玩家大部分时间都在 *** 控着游戏中对象进行移动。因而本节我们要实现的功能只有一个:通过鼠标控制对象移动。

  1.1通过Storyboard创建对象移动动画(交叉参考: 让物体动起来①)

  在序言中我们讲解了如何通过VisualStudio2010创建一个Silverlight4项目,那么我们首先打开这个项目,并将MainPage.xaml中名为LayoutRoot的GrID换成Canvas。

  Canvas顾名思义是画布的意思,它是游戏开发中性能最高且最易于用做对象布局及移动的容器控件。

  接下来打开MainPage.xaml后台代码MainPage.xaml.cs,创建一个名为rectangle的矩形对象:

双击代码全选
1 2 3 4 5 6 7 8 /// <summary> /// 填充色为绿色,宽、高各50的矩形 /// </summary> Rectangle rectangle =  new  Rectangle() {     Fill =   SolID@R_403_6004@Brush(@R_403_6004@s.Green),     WIDth = 50,     Height = 50 };

  然后在MainPage初始化后将该矩形对象(rectangle)作为子控件添加到LayoutRoot画布中,并为LayoutRoot注册(订阅)鼠标左键点击事件:

7
public  MainPage() {     InitializeComponent();      //将矩形添加进画布容器中     LayoutRoot.Children.Add(rectangle); //注册画布容器的鼠标左键点击事件     LayoutRoot.MouseleftbuttonDown +=   MousebuttonEventHandler(LayoutRoot_MouseleftbuttonDown); }

  最后,要实现通过鼠标左键点击来控制对象移动,我们还得在LayoutRoot_MouseleftbuttonDown方法体中编写相应的移动动画实现逻辑(在整个画布任意位置点击左键时,矩形对象rectangle即向该点移动):

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
private   voID  LayoutRoot_MouseleftbuttonDown( object  sender, MousebuttonEventArgs e) { //获取点击处相对于容器的坐标位置     Point p = e.Get@R_301_4612@(LayoutRoot); //创建移动用的动画故事板     Storyboard storyboard =   Storyboard(); //创建X轴方向动画     DoubleAnimation xAnimation =   DoubleAnimation() {          //起点         From = Canvas.Getleft(rectangle), //终点         To = p.X, //花费时间         Duration =   Duration(TimeSpan.FromMilliseconds(500)),     }; //将X轴方向动画赋予rectangle     Storyboard.SetTarget(xAnimation, rectangle); //设置X轴方向动画所影响的对象属性为Canvas.left     Storyboard.SetTargetProperty(xAnimation,   PropertyPath( "(Canvas.left)" )); //将X轴方向动画添加进动画故事板中     storyboard.Children.Add(xAnimation); //创建Y轴方向动画     DoubleAnimation yAnimation =   DoubleAnimation() {         From = Canvas.Gettop(rectangle),         To = p.Y,     Storyboard.SetTarget(yAnimation, rectangle); //设置Y轴方向动画所影响的对象属性为Canvas.top     Storyboard.SetTargetProperty(yAnimation,monospace!important; Font-size:1em!important; min-height:inherit!important; @R_403_6004@:blue!important">"(Canvas.top)" ));     storyboard.Children.Add(yAnimation); //播放动画     storyboard.Begin(); }

以X轴方向动画实现为例(以上代码黄色部分),首先创建一个有起点、终点以及总耗时的DoubleAnimation:xAnimation,然后通过Storyboard.SetTarget(xAnimation,rectangle)这句将xAnimation动画过程绑定到矩形对象rectangle,并且通过Storyboard.SetTargetProperty(xAnimation,new PropertyPath(“(Canvas.left)”))这行代码告诉xAnimation动画它影响的是对象(rectangle)的Canvas.left属性。这两句话的写法是固定的,有兴趣的朋友可以将(Canvas.left)换成Opacity试试(注意Opacity不需要括号),从运行结果去理解体会这两行代码的重要意义。

  同样的,Y轴方向的动画依葫芦画瓢,唯一不同的是将Canvas.left改成了Canvas.top。

  完成后在VisualStudio2010中按下Ctrl+F5进行编译运行(仅F5可进入调试运行):

  通过本节的学习,一方面大家要学会使用Storyboard创建对象移动动画;另一方面也要掌握在Canvas画布容器中改变对象位置即X、Y坐标的方法分别是Canvas.Setleft(对象,x坐标)和Canvas.Settop(对象,y坐标)。

  在Silverlight中除了可以使用Storyboard来创建移动动画外,还有另外两个选择:Com@R_301_4612@Target和dispatcherTimer。

  1.2通过Com@R_301_4612@Target创建对象移动动画(交叉参考: 让物体动起来②)

  Com@R_301_4612@Target对象可以根据每个帧的回调来创建自定义动画。通俗的讲就是Com@R_301_4612@Target创建的动画是基于画面每次刷新时触发的,与窗体刷新率保持一致,因而频率是相对固定的(随Silverlight应用程序的FPS而变化),人工无法介入控制。

  那么如何使用它来实现1.1中一模一样的移动动画效果呢?

  与1.1的步骤一样,我们首先创建一个矩形对象(当圆角半径(RadiusX、RadiusY)与相应的边长(WIDth、Height)相等时呈圆形),并在MainPage初始化后将之添加进画布同时注册画布鼠标左键点击事件:

双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /// <summary> /// 填充色为蓝色,宽、高、圆角X、Y各50的矩形 /// </summary> Rectangle rectangle =  new  Rectangle() {     Fill =   SolID@R_403_6004@Brush(@R_403_6004@s.Blue),     Height = 50,     RadiusX = 50,     RadiusY = 50 };   public  MainPage() {     InitializeComponent();      //将矩形添加进画布容器中     LayoutRoot.Children.Add(rectangle); //注册画布容器的鼠标左键点击事件     LayoutRoot.MouseleftbuttonDown +=   MousebuttonEventHandler(LayoutRoot_MouseleftbuttonDown); }

  因为是基于画面不停的刷新实现的对象位置改变,因此此时的鼠标左键事件中我们需要做的是记录鼠标移动的目的以及每次移动X、Y方向的速度增量(根据三角函数中的等边比例算出)和移动次数,同时依据具体情况注册/注销Com@R_301_4612@Target.Rendering事件:

18
bool  isRendering =  false ;  //是否启动了刷新 double  speed = 10;  //每次移动10像素  xSpeed, ySpeed;  //X、Y方向的速度 int  num;  //需要移动次数  count;  //统计移动次数 private   voID  LayoutRoot_MouseleftbuttonDown( object      if  (!isRendering) {         Com@R_301_4612@Target.Rendering +=   EventHandler(Rendering);         isRendering =  true ;     }     Point start =   Point(Canvas.Getleft(rectangle), Canvas.Gettop(rectangle));     Point end = e.Get@R_301_4612@(LayoutRoot);  distance = Math.Sqrt(Math.Pow((end.X - start.X), 2) + Math.Pow((end.Y - start.Y), 2));     xSpeed = (end.X - start.X) * speed / distance;     ySpeed = (end.Y - start.Y) * speed / distance;     num = ( )(distance / speed);     count = 0; 最后编写Com@R_301_4612@Target_Rendering方法体逻辑实现矩形移动:

11
 Rendering(  y = Canvas.Gettop(rectangle);     Canvas.Setleft(rectangle, x + xSpeed);     Canvas.Settop(rectangle, y + ySpeed);  (count == num) {         Com@R_301_4612@Target.Rendering -= Rendering; ;     }     count++;   大体思路是:每次移动后记数count++,当移动到总次数num时将Com@R_301_4612@Target.Rendering事件注销(取消订阅)掉,从而实现到达目的地时对象自动停止的效果。

  1.3通过dispatcherTimer创建对象移动动画(交叉参考: 让物体动起来③  实现2D人物动画①  实现2D人物动画②)

  dispatcherTimer顾名思义是一个计时器,它的Tick事件类似于在Silverlight界面线程中进行Join *** 作;并且基于Silverlight/WPF的dispatcher机制,我们无需考虑任何跨线程问题。因此dispatcherTimer在Silverlight游戏开发中应用非常广泛。

  同样具备“心跳”特性的dispatcherTimer实现对象移动逻辑非常类似1.2中的Com@R_301_4612@Target,唯一不同的是dispatcherTimer是完全可控的。于是我们仅仅需要做的是在1.2代码基础上稍动些手脚即可,具体如下:

  1)  定义一个间隔为10毫秒的dispatcherTimer对象:

4
//计时器对象 dispatcherTimer dispatcherTimer =   dispatcherTimer() {      Interval = TimeSpan.FromMilliseconds(10) };

  2)在MainPage()中注册Tick事件:

  dispatcherTimer.Tick += new EventHandler(Rendering);

  3)将Com@R_301_4612@Target.Rendering += new EventHandler(Rendering);修改为dispatcherTimer.Tick += new EventHandler(Rendering);

  4)同样的将Com@R_301_4612@Target.Rendering -= Rendering;修改为dispatcherTimer.Stop();

  很简单对吧。由此可见dispatcherTimer实现动画的原理与Com@R_301_4612@Target确实非常类似,只是我们可以通过Start()和Stop()更方便的启动/停止dispatcherTimer对象。

  以上三种方式均能实现鼠控制对象移动,那么我们该如何将之与游戏联系起来呢?

  大家是否已迫不及待的想要把真实的精灵加入到游戏画布中?此时的Rectangle将再次大显身手,我们可以通过为其设置宽、高并填充上PNG图象,转眼间一个华丽的精灵即呈现在我们眼前:

12
/// 填充为一张宽高均150像素的PNG精灵图片矩形  ImageBrush() {         ImageSource =   BitmAPImage() {             UriSource =   Uri( @"/Lesson1.3;component/Res/Sprite.png" , UriKind.relative)         },monospace!important; Font-size:1em!important; min-height:inherit!important">    },     WIDth = 150,     Height = 150   Silverlight用于图象呈现的载体除Rectangle外还有Image;Image使用起来更智能,它可以根据图像源的宽高自适应尺寸,我们需要做的仅仅是为其设置源文件路径而已:

8
/// 图像对象 Image image =   Image() {     Source =   BitmAPImage() {         UriSource =      } };
总结

以上是内存溢出为你收集整理的Silverlight MMORPG网页游戏开发课程[一期] 第一课:控制对象移动全部内容,希望文章能够帮你解决Silverlight MMORPG网页游戏开发课程[一期] 第一课:控制对象移动所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1068180.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)