技术开发 频道

开发Silverlight游戏教程:精灵控件横空出世

    以上代码中用黄色背景突出的即为需要修改的地方,其中Storyboard.SetTargetProperty(keyFramesAnimationX, new PropertyPath("X"));和Storyboard.SetTargetProperty(keyFramesAnimationY, new PropertyPath("Y"));这两句作用是将主角(Spirit)的X,Y属性值作为Storyboard动画的更新对象目标,值得注意的是keyFrame.Value = i == 0 ? Spirit.X : framePosition[i].X * GridSize;与keyFrame.Value = i == 0 ? Spirit.Y : framePosition[i].Y * GridSize;这两句话,它们的作用是将寻路后得到的所有路径点按从角色起点到终点这样的顺序依次做为Storyboard的关键帧添加进Storyboard动画中,并且首先舍弃寻路得到的第一个点而以坐标(Spirit.X,Spirit.Y)作为动画起点(…i == 0 ? Spirit.X ……i == 0 ? Spirit.Y…)从而起到平滑衔接动画的效果。千万别小看它,很多人往往忽略了它导致动画衔接粗糙(大家可以尝试将keyFrame.Value = i == 0 ? Spirit.X : framePosition[i].X * GridSize;替换成keyFrame.Value = framePosition[i].X * GridSize;将keyFrame.Value = i == 0 ? Spirit.Y : framePosition[i].Y * GridSize;替换成keyFrame.Value = framePosition[i].Y * GridSize;后再运行一下程序看看,当角色正在移动且还未到达终点的时候,此时你用鼠标再点击别的地方让主角向新的目的地移动,由于未采取平滑处理将导致角色会突然跳动一下的效果(起始坐标定位错误BUG)。为了配合大家更好的理解,我用张图来说明(图中的网格即为单位为20*20的单元格,即GridSize=20的效果):

 

 A*寻路方法改造完成后,最后就是在鼠标左键点击事件中去启动它了:

 private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {

 Point p1 = e.GetPosition(Map); //点击的地方在Map中的坐标点

 //Point p2 = TranslatePoint(e.GetPosition(Carrier), Map); //此方法效果和上面一样

 AStarMoveTo(p1);

 }

 这里的e.GetPosition(Map)我们可以理解为:在Map地图图片上点击,返回Map上该点的坐标。而我们同样的可以通过一个名为TranslatePoint的方法来达到相同的目的,即我们在Carrier画布上点击,返回Carrier上该点的坐标,接下来再将该点转换成Map地图图片上的位置点,因此返回的结果都是一样的。TranslatePoint()的形式很直观,虽然在此处使用效果不太好,但是将之用于地图边缘判断、物体与物体的碰撞与重叠判断、射程计算等问题上不失为一种优雅的解决方案。

 OK,一切就绪,激动人心的时刻就要到了!按下CTRL+F5,尽情的在地图上随便点击吧,并且在任何的时候你用鼠标去牵引地图移动,主角和障碍物都会平滑的显示在正确位置上,什么叫完美?This is Perfect!Right?

 


 后面的章节中,我将完善前十六节中一直遗留着的一个很多很多朋友迫切想要解决的大问题:如何实现精灵的八个方向?重磅炸弹即将粉墨登场,敬请关注。

原文地址:http://www.cnblogs.com/alamiye010/archive/2009/06/21/1507926.html

0
相关文章