silverlight 加载zip资源

silverlight自身是用标准的zip缩压xap文件的,所以我们可以通过silverlight自身提供的zip解压类帮我们加载资源,例如:图片,xml等。这功能对游戏开发中的资源加载有一定帮助。因为游戏的资源一般情况下并不小,所以通过这个功能成达到动态加载并可以选择保存在独立存储空间中。这样更可以通过判断资源文件名达到不重复下载资源。开心银光觉得这样的游戏资源解决方案相对来说是比效完美的。

当然,这只是一些举例,只要你对它了解后,你可以加载任何东西,因为这功能是直接操作二进制的。除非你加载的流本身存在问题,否则它是工作的很好的。

a)它位于System.Windows.Resources.StreamResourceInfo.它作为一个流形式保存你的资源。帮你准备好让silverlight原生的zip解决类还原资源文件。

b)解决是通过System.Windows.Application.GetResourceStream方法进来解压并还原资源。

以下是我完整的通过webclient下载zip加压的资源文件,然后还原资源并使用的代码:

 1:  public class Loader
 2:      {
 3:          public delegate void loadComplateEventHandler(List<StreamResourceInfo> resources);
 4:          public event loadComplateEventHandler loadComplate;
 5:          public delegate void loadProgressChangedHandler(int prosent);
 6:          public event loadProgressChangedHandler loadProgressCheanged;
 7:  
 8:          WebClient wc;
 9:  
10:          public Loader()
11:          {
12:              wc = new WebClient();
13:              wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
14:          }
15:  
16:          void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
17:          {
18:              if (loadProgressCheanged != null)
19:              {
20:                  loadProgressCheanged(e.ProgressPercentage);
21:              }
22:          }
23:  
24:          public void loadPng(string uri)
25:          {
26:              wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wcPng_OpenReadCompleted);
27:              wc.OpenReadAsync(new Uri("../" + uri, UriKind.Relative));
28:          }
29:  
30:          public void loadPngAbs(string uri)
31:          {
32:              wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wcPng_OpenReadCompleted);
33:              wc.OpenReadAsync(new Uri(uri, UriKind.Absolute));
34:          }
35:  
36:          public void loadWma(string uri)
37:          {
38:              wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wcWma_OpenReadCompleted);
39:              wc.OpenReadAsync(new Uri("../" + uri, UriKind.Relative));
40:          }
41:  
42:          public void loadWmaAbs(string uri)
43:          {
44:              wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wcWma_OpenReadCompleted);
45:              wc.OpenReadAsync(new Uri(uri, UriKind.Absolute));
46:          }
47:  
48:          void wcWma_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
49:          {
50:              if (e.Error == null)
51:              {
52:                  complate(e.Result, ".wma");
53:              }
54:          }
55:  
56:          void wcPng_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
57:          {
58:              if (e.Error == null)
59:              {
60:                  complate(e.Result, ".png");
61:              }
62:          }
63:  
64:          void complate(System.IO.Stream result, string ext)
65:          {
66:              List<StreamResourceInfo> res = new List<StreamResourceInfo>();
67:              StreamResourceInfo zipResourceInfo = new StreamResourceInfo(result, null);
68:              for (int i = 1; i < 100; i++)
69:              {
70:                  StreamResourceInfo imageResourceInfo = Application.GetResourceStream(zipResourceInfo,
71:                      new Uri(i.ToString() + ext, UriKind.Relative));
72:                  if (imageResourceInfo != null)
73:                  {
74:                      res.Add(imageResourceInfo);
75:                  }
76:                  else
77:                  {
78:                      break;
79:                  }
80:              }
81:              loadComplate(res);
82:          }
83:      }
84:  

以上操作可能看起来有点复杂,开心银光再简单讲解一下重点,重点操作在complate方法中。

a)我先定义了一个List<StreamResourceInfo> res = new List<StreamResourceInfo>();这个res作用是准备装载解压还原后的文件流。一个StreamResourceInfo为一个文件。所以这里表示有多少个文件就用多少个元素。

b)以上代码中的zipResourceInfo是一个Stream。它里边是一个完整的zip二进制文件流。因为开心银光的zip资源里的的文件都是用数字int来命名的。所以才会出现一个for语句去枚举这些文件名,然后再调用Application.GetResourceStream(zipResourceInfo,Uri);这样就可以读取到流中的资源文件。这里要注意的是,Uri中的uriKind一个是用Relative,因为加载回来的资源文件是已经在silverlihgt的缓存程序集中的资源位置。

接下来开心银开再写一段简化代码,让大家更好地理解这文章的重点:

1:  void complate(System.IO.Stream result, string ext)
2:  {
3:      StreamResourceInfo pngResource = new StreamResourceInfo(result, null);
4:      StreamResourceInfo pngfile = Application.GetResourceStream(pngResource, new Uri("1.png", UriKind.Relative));
5:      System.Windows.Media.Imaging.BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage();
6:      bi.SetSource(pngfile.Stream);
7:  }
8:  

怎样。简单吧。这样就可以返回你的1.png为一个BitmapImage。然后可要在你的Image.source=bi;这样即可把图片显示出来。

接下来要讲解下开心银光上边那个完整的功能类的使用方法:以下是加载的方法

 1:              //loadmap
 2:              Loader pl = new Loader();
 3:              pl.loadComplate += (res) =>
 4:              {
 5:                  Dictionary<int, StreamResourceInfo> maps = new Dictionary<int, StreamResourceInfo>();
 6:                  int counter = 0;
 7:                  for (int i = 0; i < res.Count; i++)
 8:                  {
 9:                      counter++;
10:                      maps.Add(counter, res[i]);
11:                  }
12:              };
13:              pl.loadProgressCheanged += (ps) =>
14:              {
15:                  var mp = App.Current.RootVisual as MainPage;
16:                  mp.textBlock3.Text = "地?图?下?载?" + ps.ToString() + "%";
17:              };
18:              pl.loadPng("res/map2.zip");
19:              //pl.loadPngAbs("http://域名/map1.zip");//这个方法加载的是互联网地址上的zip
20:  

以下是如何使用加载后的maps的代码:

1:  public BitmapImage GetImageFromStream(StreamResourceInfo stream)
2:  {
3:      BitmapImage bi = new BitmapImage();
4:      bi.SetSource(stream.Stream);
5:      stream.Stream.Position = 0;
6:      return bi;
7:  }
8:  
1:  body.Source = GetImageFromStream(mapUri);
2:  

以上的body其实是一个Image控件。

好了。到此为止我已把大部份功能说明了一次。至于如果通过独立存储区来防止重复下载资源开心银光会在下一次文章中再另作说明。

你可能感兴趣的:(silverlight)