Silverlight C# 游戏开发:Flyer03大图裁剪,高效动画的艺术

简介:

Flyer02最后,我们得到了一个屏幕,上面有云彩向上飘去,但是很容易发现有一个很明显的瑕疵,就是云彩不会限定在一个画面中,那么能不能控制在一个指定的范围内呢。

 

Sivlerlight中限定一个UIElement的边界,可以使用Clip来实现,在能够显示图片主窗口元素上添加如下代码:

 

 
  1. GameMainWindow.Clip = new RectangleGeometry() { Rect = new Rect(0, 0, 400, 400) };  

现在再运行一下,看到了吧,是否达到了我们想要的效果了呢?

是不是很有趣,让我们想想,如果能够裁剪的方式获得一个限定区域,那么是不是可以将一组图片的各个部分拆分出来呢?就如资源目录中的filyer.png,能否将每个部分拆分出来显示?Clip完全可以做到,但是并不高效,其原因是,Clip的裁剪并不会减少整张图片的大小,这意味着有多少动作帧内存中就要载入多少张整张图片,很显然,绝不优美,相信玩家也不会为此买内存的单,那么是不是就没有办法了呢?能否有一个好的方法,只加载一个张图片然后处理分成多张小图,对内存的占用就低的多了。

可以通过WriteableBitmap来实现分成小图,WriteableBitmap是Silverlight提供操作Bitmap数据的BitmapSouce,通过这个类可以生成多张指定大小的图片,在内存上不需要加载过多的图,只需要一张大图即可,那么我们的编写思路图如下:

 

 

通过截取整张图片当中的一个部分,渲染到WriteableBitmap当中,然后转换成为Image控件的Souce,最后通过一个定时器完成动画效果

一如既往,我们只使用代码实现这个部分,那么需要创造一个类,这个类的名字叫ClassFlyer

代码如下:

 
 
Image _image;
ImageSource[,] FlyerFrames
= new ImageSource[ 6 , 8 ];
public ClassFlyer()
{
_image = new Image();
BitmapImage bitmap = new BitmapImage( new Uri( @" Src/flyer.png " , UriKind.Relative));
bitmap.ImageOpened
+= new EventHandler < RoutedEventArgs > (bitmap_ImageOpened);
this .Children.Add(_image);
}
// 之所以在这里处理是因为Silverlight的图片下载是异步的,只有载入完毕后才好处理
void bitmap_ImageOpened( object sender, RoutedEventArgs e)
{
_image.Source = sender as BitmapImage;
for ( int j = 0 ; j < 6 ; j ++ )
{
for ( int i = 0 ; i < 8 ; i ++ )
{
WriteableBitmap wb
= new WriteableBitmap( 64 , 64 );
wb.Render(_image,
new TranslateTransform()
{ X = - 64 * i, Y = - 64 * j });
wb.Invalidate();
= (ImageSource)wb;
}
}
}
FlyerFrames[j, i]

最终的目的是得到了一个FlyerFrames的祯组,这组图片涵盖了以行为划分的动画序列,清晰的描述角色们的状态

现在看起来容易多了,实现动画只是找对正确的行和列,建议实现一个简单的枚举,当然了,C#不像C++那般方便的将enum转换成为数字,所以我的实现方法是用const

 

 
 
public class EmFlyerState
{
public const int 正常 = 0 ;
public const int 向上 = 1 ;
public const int 向右 = 2 ;
public const int 向左 = 3 ;
public const int 向下 = 4 ;
public const int 击中 = 5 ;

}

现在下面重要的是动画,动画是按照一个时间的循环,这种有很多方法来实现,在这里为了方便理解,用一个DispatcherTimer

 
  1. DispatcherTimer dispatcherTimer = new DispatcherTimer();  
  2.  
  3. dispatcherTimer.Tick += new EventHandler(TickGameFrameLoop);  
  4.  
  5. dispatcherTimer.Interval = TimeSpan.FromMilliseconds(30); //重复间隔  
  6.  
  7. dispatcherTimer.Start();  
  8.  
  9. private void TickGameFrameLoop(object sender, EventArgs e)  
  10.  
  11. {  
  12.  
  13.  
  14.  
  15. }  

也许你觉得现在有点意思了,但是还无法实现控制飞行员动作,为了达到这个目的需要为MainPage加上按键事件,

在MainPage类中加上下述代码,然后实现KeyDown和KeyUp的方法,这里做一个特别的说明,为什么还要检测KeyUp,这是因为当玩家松开键盘的时候,可以让飞行员的角色变为正常状态。

 
  1. this.KeyDown += new KeyEventHandler(MainPage_KeyDown);  
  2.  
  3. this.KeyUp += new KeyEventHandler(MainPage_KeyUp);  

在KeyDown和KeyUp事件里,我们可以写下如下代码来控制角色的状态,假设我们之前定为ClassFlyer的实例名为Hero

 

 
  1.  
  2.  
  3. void MainPage_KeyDown(object sender, KeyEventArgs e)  
  4.  
  5. {  
  6.  
  7. switch (e.Key)  
  8.  
  9.  
  10.  
  11. {   
  12.  
  13.  
  14.  
  15. case Key.Up:  
  16.  
  17.  
  18.  
  19. Hero.Flyerstate = EmFlyerState.向上;  
  20.  
  21.  
  22.  
  23. break;  
  24.  
  25.  
  26.  
  27. case Key.Down:  
  28.  
  29.  
  30.  
  31. Hero.Flyerstate = EmFlyerState.向下;  
  32.  
  33.  
  34.  
  35. break;  
  36.  
  37.  
  38.  
  39. case Key.Left:  
  40.  
  41.  
  42.  
  43. Hero.Flyerstate = EmFlyerState.向左;  
  44.  
  45.  
  46.  
  47. break;  
  48.  
  49.  
  50.  
  51. case Key.Right:  
  52.  
  53.  
  54.  
  55. Hero.Flyerstate = EmFlyerState.向右;  
  56.  
  57.  
  58.  
  59. break;  
  60.  
  61.  
  62.  
  63. }  
  64.  
  65.  
  66.  
  67. }  
  68.  
  69.  
  70.  
  71. void MainPage_KeyUp(object sender, KeyEventArgs e)  
  72.  
  73.  
  74.  
  75. {  
  76.  
  77.  
  78.  
  79. Hero.Flyerstate = EmFlyerState.正常;  
  80.  
  81.  
  82.  
  83. }  
 

基本上我们已经接近于完成,但是还有一些细节代码需要整理,在这里就不一一做讲解了,有兴趣的请直接看代码:)

点击这里进行下载:FlyerGame2

 


本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/712594


相关文章
|
3月前
|
存储 开发框架 .NET
【C#】C# 基础语法与游戏开发
【1月更文挑战第21天】【C#】C# 基础语法与游戏开发
|
3月前
|
存储 开发框架 .NET
【C#】认识C# (为了游戏开发 O(≧口≦)O)
【1月更文挑战第26天】【C#】认识C# (为了游戏开发 O(≧口≦)O)
|
9月前
|
C# 开发者
推荐一款C#开源的操作简单、免费的屏幕录制和GIF动画制作神器
推荐一款C#开源的操作简单、免费的屏幕录制和GIF动画制作神器
|
4月前
|
C# 开发工具 Windows
C#操作PPT动画窗格并插入音频文件的一些思路
C#操作PPT动画窗格并插入音频文件的一些思路
|
容器
Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)
原文:Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)   Silverlight的基础动画包括偏移、旋转、缩放、倾斜和翻转动画,这些基础动画毫无疑问是在Silverlight中使用得最多的动画效果,其使用也是非常简单的。
965 0
|
容器 数据可视化 内存技术
Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)
原文:Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)   用户界面组件、图像元素和多媒体功能可以让我们的界面生动活泼,除此之外,Silverlight还具备动画功能,它可以让应用程序“动起来”。
794 0
Silverlight & Blend动画设计系列四:倾斜动画(SkewTransform)
原文:Silverlight & Blend动画设计系列四:倾斜动画(SkewTransform)   Silverlight中的倾斜变化动画(SkewTransform)能够实现对象元素的水平、垂直方向的倾斜变化动画效果。
795 0
|
容器
Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)
原文:Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)   正如你所看到的,Blend是一个非常强大的节约时间的设计工具,在Blend下能够设计出很多满意的动画作品,或许他具体是怎么实现的,通过什么方式实现的我们还是一无所知。
911 0
Silverlight & Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)
原文:Silverlight & Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)   模糊效果(BlurEffect)与阴影效果(DropShadowEffect)是两个非常实用和常用的两个特效,比如在开发相册中,可以对照片的缩略图添加模糊效果,在放大照片的过程中动态改变照片的大小和模糊的透明度来达到一个放大透明的效果。
1045 0
Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效
原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效   当我们在进行Silverlight & Blend进行动画设计的过程中,可能需要设计出很多效果不一的图形图像出来作为动画的基本组成元素。
1003 0