一直在想应该用什么作为《Silverlight 2.5D RPG游戏技巧与特效处理系列教程》的终结,既要实用而不拖泥带水;又要通用而不哗众取宠。于是一不小心便成就了我一个未了心愿:一切基于动态绘制路径而生成的万象动画作为这又一部作品的谢幕,足矣。
还记得我们小时候玩的《坦克大战》、《雷电》吗?在那狭小的弹粒缝隙间躲闪追逐成为了每每课后最快乐的回忆:
还记得高三那年的春天吗?每次丢下书包第一时间总会跑进网吧与同学们联网《星级争霸》、《帝国时代》;4V4、罗马战车VS投石车,炮火与弓箭的洗礼下,我们幸福的青春就这样被无限的释放:
大学里,《博德之门》、《奇迹》、《半条命》、《破碎银河系》等N多顶级游戏/网游让我短暂的忘却了时代赋予大学生的苦闷,人生除了现实,其实成为一名虚拟的王者未必不是今生一件幸事。“魔法飞弹”横空掠过、“蓝翎弩”三重穿梭、“”华丽的抛物线、“跟踪弹”锲而不舍的精神如同网吧中弥漫着无上团结的凝聚力,走过了4年,也走过了最让我留念和感动的“兄弟年代”:
直至今日,当我们坐在凳子上开始编写属于自己的游戏时,当年战斗的画面早已模糊不清,残留的仅剩无数的弹粒在天空中你来我往,毫无眷恋。一直在想是否能够通过一块画板外加几个选项来完成所有一切的自定义路径动画,从而让游戏设计中那些如此神秘而又变幻莫测的“弹道轨迹”变得简单而轻松?
之前便有很多人公开了他们的相关成果,关于Silverlight中的路径动画(Path Animation)实现,比如下面两个链接:
http://www.codeproject.com/KB/silverlight/PathAnimation.aspx
http://geekswithblogs.net/cskardon/archive/2010/09/21/path-animation-in-silverlight.aspx
很可惜它们均为外国人所作,第一篇重新封装了一个名为PathAnimation的类,基于Blend绘制Path坐标数据实现路径动画;而后者则完全是通过Blend绘制的路径动画。虽然均能达到效果,但易用性及拓展性显然不够强。想想,怎样的自定义路径动画才能最大化适应当下绝大多数(各类型)游戏的需要?尤其在RPG游戏中,能为之增添无限乐趣和优秀的玩家视觉体验。
思路再一次回到那块画板上,通过鼠标在画板上移动,然后将鼠标所经过的轨迹以一定的密度绘制在其上并按顺序保存到List<Point>中,最后通过Storyboard的关键帧动画将所有的Point连成一个完整的路径动画。其中通过简单的顺时针/逆时针判断公式及匀加/减速度计算公式(任何公式都可以随意拓展)来分别实现动画延路径移动时的动态朝向及变速运动效果;当然,再配合上坐标缩放系数,从而最终整个自定义路径动画所实现的效果可完美无缝的移植到任何有相关需求的Silverlight游戏中:
弹粒的关键帧动画
Bulletbullet=newBullet(newBulletDatas(){Code=pathAnimationPainter[n].AnimationCode,Loop=true,Type=BulletTypes.Animation}){Z=100};
bullet.Center=bullet.Offset;
tabCanvas2.Children.Add(bullet);
Storyboardstoryboard=newStoryboard();
PointAnimationUsingKeyFramespointAnimationUsingKeyFrames=newPointAnimationUsingKeyFrames();
Storyboard.SetTarget(pointAnimationUsingKeyFrames,bullet);
Storyboard.SetTargetProperty(pointAnimationUsingKeyFrames,newPropertyPath("Position"));
DoubleAnimationUsingKeyFramesdoubleAnimationUsingKeyFrames=newDoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(doubleAnimationUsingKeyFrames,bullet);
Storyboard.SetTargetProperty(doubleAnimationUsingKeyFrames,newPropertyPath("Angle"));
doublespeed=pathAnimationPainter[n].Rate;
doublea=0.002;//加速系数
doubletimeSpanTemp=0;
doubledurationTemp=0;
doubleangleTemp=0;
intcircle=0;
if(pathAnimationPainter[n].Easing==2){//加速逆行即减速
for(inti=0;i<pathAnimationPainter[n].Path.Count;i++)
{speed+=a*i;}
}
for(inti=0;i<pathAnimationPainter[n].Path.Count;i++){
TimeSpantimeSpan=newTimeSpan();
PointlastPath=(i==0?pathAnimationPainter[n].Path[0]:pathAnimationPainter[n].Path[i-1]);
PointnowPath=pathAnimationPainter[n].Path[i];
PointnextPath=(i==pathAnimationPainter[n].Path.Count-1?pathAnimationPainter[n].Path[pathAnimationPainter[n].Path.Count-1]:pathAnimationPainter[n].Path[i+1]);
switch(pathAnimationPainter[n].Easing){
case0:
timeSpanTemp=GlobalMethod.GetDistance(lastPath,nowPath)/speed;
durationTemp+=timeSpanTemp;
timeSpan=TimeSpan.FromMilliseconds(durationTemp);
break;
case1:
speed+=a*i;
timeSpanTemp=GlobalMethod.GetDistance(lastPath,nowPath)/speed;
durationTemp+=timeSpanTemp;
timeSpan=TimeSpan.FromMilliseconds(durationTemp);
break;
case2:
speed-=a*(pathAnimationPainter[n].Path.Count-1-i);
timeSpanTemp=GlobalMethod.GetDistance(lastPath,nowPath)/speed;
durationTemp+=timeSpanTemp;
timeSpan=TimeSpan.FromMilliseconds(durationTemp);
break;
}
pointAnimationUsingKeyFrames.KeyFrames.Add(
newLinearPointKeyFrame(){
KeyTime=KeyTime.FromTimeSpan(timeSpan),
Value=newPoint(){X=nowPath.X*pathAnimationPainter[n].Proportion,Y=nowPath.Y*pathAnimationPainter[n].Proportion}
}
);
doubleangle=GlobalMethod.GetAngle(nowPath.Y-lastPath.Y,nowPath.X-lastPath.X)+360*circle;
//check大于0为顺时针个方向
doublecheck=(nowPath.X-lastPath.X)*(nextPath.Y-nowPath.Y)-(nowPath.Y-lastPath.Y)*(nextPath.X-nowPath.X);
if(check>0){
if(angleTemp>360*circle&&angle<360*circle){angle+=360;}elseif(angleTemp>360*circle+180&&angle<angleTemp){angle+=360;circle++;}
}else{
if(angleTemp<360*circle&&angle>360*circle){angle-=360;}elseif(angleTemp<360*circle-180&&angle>angleTemp){angle-=360;circle--;}
}
angleTemp=angle;//用于旋转时的角度衔接
doubleAnimationUsingKeyFrames.KeyFrames.Add(
newLinearDoubleKeyFrame(){
KeyTime=KeyTime.FromTimeSpan(timeSpan),
Value=angle
}
);
}
pointAnimationUsingKeyFrames.Duration=newDuration(TimeSpan.FromMilliseconds(durationTemp));
storyboard.Children.Add(pointAnimationUsingKeyFrames);
if(pathAnimationPainter[n].Direction==0){storyboard.Children.Add(doubleAnimationUsingKeyFrames);}
EventHandlerhandler=null;
storyboard.Completed+=handler=delegate{
storyboard.Completed-=handler;
tabCanvas2.Children.Remove(bullet);
bullet.Move_Completed(bullet,null);
};
storyboard.Begin();
还在羡慕《倩女幽魂Online》交织穿梭的吸血法术吗?
还在嫉妒《星辰变》中的移动粒子施法吗?还在恨2D/2.5D无法实现类似3D游戏中那些高随意性的路径动画吗?
有了本节的自定义路径动画攻略,大家只需一个描述路径的List<Point>,配合上几个参数而已,一切效果随手创造:
看到这你是否开始心动了?没错,尤其是在角色位置相对固定的回合制、SLG等类型游戏中,在发动者与它的目标之间创造出你认为最华丽的路径,无论魔法的走位还是角色的各类移动等效果都将变得轻而易举,这就是Silverlight给我们游戏开发者所带来的奇迹~!
Silverlight 时代即将来临,您准备好了吗?
本系列源码请到目录中下载
在线演示地址:http://silverfuture.cn
分享到:
相关推荐
Silverlight 2.5D RPG游戏技巧与特效处理源代码与说明
C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十六) 地图自定义切片与导出 C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十七) 地图自适应区域加载 C#开发WPF/Silverlight动画...
简单的Silverlight 自定义控件源码。 通过它,可以知道基本的silverlight自定义控件是如何编写的。
为了轻松的处理多对象间的Z轴层次顺序,可借助切分/分离某些图片/动画部件以达到更加逼真的2.5D游戏场景 碧月斩,直线穿梭类型技能,伤害范围为一个多边形,游戏中的激光等魔法同样可以类似处理,另外与圆月斩类似...
学习用Silverlight创建自定义控件经典教程。
在Silverlight自定义验证效果(带动画) http://blog.csdn.net/lijun7788/article/details/8495813 代码
Silverlight项目联网获取天气,PM2.5等详细天气信息
C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial) 的源代码 第一部分源码:WPFGameTutorial_PartI.rar(1-20节) 第二部分源码:WPFGameTutorial_PartII.rar (21-26节) 第三部分源码:WPFGameTutorial_Part...
提供三种窗体自定义样式,这只是个引子,您可以根据自己的想法自定义窗体
C#开发WPF+Silverlight动画及游戏系列的完整教程,有完整的代码 很炫的界面和游戏功能
Silverlight导航动画 Silverlight导航动画 Silverlight导航动画 Silverlight导航动画 Silverlight导航动画 Silverlight导航动画 Silverlight导航动画
C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手
Silverlight C# 游戏开发 资源的处理,图像算法 游戏开发在开始的时候一般不会注意一个重要的细节,就是“特效”,角色也好,场景也罢,可能都不会是最占用磁盘空间的资源,特效资源,包含了技能释放的、场景中的,...
Silverlight 制作可拖动的自定义控件 Silverlight 制作可拖动的自定义控件Silverlight 制作可拖动的自定义控件 Silverlight 制作可拖动的自定义控件
silverlight toolkit中的主题(theme)应用、SilverLight 桌面文件夹效果...与DataGrid组合源码、Silverlight动感小菜单源码、Silverlight分页源码、Silverlight进度条源码、Silverlight密码强度验证源码、Silverlight...
silverlight 显示gif动画控件,附例子~~~ http://www.dotnetdev.cn
silverlight做的小游戏,提供源代码!
自己开发sliverlight日历插件,可自主修改其各部分样式
Silverlight 2系列(35):升级Silverlight 2 Beta 1应用程序到Beta 2 Silverlight 2系列(34):使用Silverlight Streaming托管Silverlight应用程序 Silverlight 2系列(33):Silverlight 2应用Web Service两例 ...
深蓝色右手 C#开发WPF Silverlight动画及游戏系列教程 出处http://alamiye010.cnblogs.com/