Technical feasibility report of writeablebitmap in Silverlight games

Source: Internet
Author: User

I hope this article will help my friends who are devoted to Silverlight games.

CodeDownload: silverlighttestwbresource.zip

The directory settings are as follows:

 

Scenario 1: Set all PNG files to resource and do not copy.

Source code of the specified image:

 
Spirit. Source =NewBitmapimage(NewUri(@ "Player /"+ Count +". PNG",Urikind. Relative ));

 

Note that the relative path is used here, which is the position of the current mainpage. XAML relative to the image, rather than the server path.

If the source of the image is specified in spirit, that is, the relative path is changed, the code should be written as follows:

Body. Source =NewBitmapimage(NewUri(@ "../Player/2.png",Urikind. Relative ));

 

In this case, all images are embedded into the DLL as resources. Observing the organizational structure in the xap confirms our conclusion:

Scenario 2: Set all PNG files to content and copy If newer.

Source code of the specified image:

 
Spirit. Source =NewBitmapimage(NewUri(@ "/Player /"+ Count +". PNG",Urikind. Relative ));

 

Note that the server path is used, but the relative path is not used.

One advantage of using the server path is that no matter where the XAML is located, it can be ignored. For example, the above spirit control:

 
Body. Source =NewBitmapimage(NewUri(@ "/Player/2.png",Urikind. Relative ));

 

In this case, all the images are packaged into the xap player directory. Observing the organization structure in the xap confirms our conclusion:

The player folder contains the 8 PNG images ranging from 0 to 7.

 

The Technology analyzed below is to take a big picture and only part of it.

There are two methods:

Method 1: Use clip technology.

 Public partial class  Mainpage : Usercontrol {Private int Count = 1; Private  Image Spirit; Public Mainpage () {initializecomponent (); spirit = New  Image () {Width = 1500, Height = 150, source = New  Bitmapimage ( New  Uri ( @ "Player/playermagic.png" , Urikind . Relative)}; carrier. Children. Add (spirit ); Dispatchertimer Dispatchertimer = New  Dispatchertimer (); Dispatchertimer. Tick + = dispatchertimer_tick; dispatchertimer. interval = Timespan . Frommilliseconds (150); dispatchertimer. Start ();} Void Dispatchertimer_tick ( Object Sender, Eventargs E) {spirit. Clip = New  Rectanglegeometry () {Rect =New  Rect (Count * 150, 0,150,150)}; spirit. rendertransform = New  Translatetransform () {X =-count * 150}; Count = COUNT = 7? 0: Count + 1 ;}}

You can use the relative path or server path. Of course, you must set the image to resource or content.

 

Method 2: Use writeablebitmap Technology

This writeablebitmap is very mysterious and should be noted in many aspects during use. I almost got killed by the dark blue right hand yesterday and got to the QQ Group for discussion. Only then did I know that many people are equally troubled and confused.

1) programming model using server paths:

 Public partial class  Mainpage : Usercontrol { Private int Count = 1; Private  Image Spirit; Public Mainpage () {initializecomponent (); spirit = New  Image () {Width = 150, Height = 150}; carrier. Children. Add (spirit ); Dispatchertimer Dispatchertimer = New  Dispatchertimer (); Dispatchertimer. Tick + = dispatchertimer_tick; dispatchertimer. interval = Timespan . Frommilliseconds (150); dispatchertimer. Start ();}Void Dispatchertimer_tick ( Object Sender, Eventargs E ){ // Spirit. Source = new bitmapimage (New uri (@ "/images/" + Count + ". PNG", urikind. Relative )); Spirit. Source = composeequip ( @ "/Images/body0.png" , 150,150, New  Point (-Count * 150, 0); Count = COUNT = 33? 0: Count + 1 ;} Public static  Writeablebitmap Composeequip ( String Bodyaddress,Int Width, Int Height, Point Bodyoffset ){ Writeablebitmap Writeablebitmap = New  Writeablebitmap (Width, height); writeablebitmap. Render ( New  Image () {Source = getimage (bodyaddress )}, New  Translatetransform () {X = bodyoffset. X, Y = bodyoffset. y}); writeablebitmap. invalidate (); Return Writeablebitmap ;}Public static  Bitmapsource Getimage ( String Address ){ Return new  Bitmapimage ( New  Uri ( String . Format ( @ "{0 }" , Address ), Urikind . Relative ));}}

 

 

If we want to merge two images, the composeequip method may be as follows:

 Public static  Writeablebitmap Composeequip ( String Bodyaddress, String Weaponaddress, Int Width, Int Height, Point Bodyoffset, Point Weaponoffset ){ Writeablebitmap Writeablebitmap = New  Writeablebitmap (Width, height); writeablebitmap. Render ( New  Image () {Source = Super . Getimage (bodyaddress )}, New  Translatetransform () {X = bodyoffset. X, Y = bodyoffset. y}); writeablebitmap. Render ( New  Image () {Source = Super . Getimage (weaponaddress )}, New  Translatetransform () {X = weaponoffset. X, Y = weaponoffset. y}); writeablebitmap. invalidate (); Return Writeablebitmap ;}

 

 

2) programming model using relative paths:

How to replace the above path with a relative path and change the image to a resource is not a problem.

I guess the problem lies in writeablebitmap. Render (....); And writeablebitmap. invalidate. Because render takes time,

How can this problem be solved?

Someone had an idea to open a thread between the two statements and then sleepfor 1 second, but he didn't take into account that our composeequip is a method to execute every 150mm.

The correct solution is as follows:

We have attached a method to the imageopened event of the large image to be loaded. In this method, we cut the large image into several small images, and put it in the frames array-in this case, large images can be used, so there is no need to worry about the blank space when cutting.

Note that when Will bitmap_imageopened be triggered? We can see the last statement of the mainpage constructor:

Spirit. Source = bitmap;

Yes, it is triggered when this statement is executed -- do not believe? Comment out this sentence to see if the bitmap_imageopened method can be executed. I did not see the breakpoint will stop here.

 Public partial class  Mainpage : Usercontrol { Private int Count = 1; Private Image Spirit; Imagesource [] Frames = New  Imagesource [10]; Public Mainpage () {initializecomponent (); spirit = New  Image (); Bitmapimage Bitmap = New  Bitmapimage ( New  Uri ( @ "Src/playermagic.png" ,Urikind . Relative); bitmap. imageopened + = New  Eventhandler < Routedeventargs > (Bitmap_imageopened); carrier. Children. Add (spirit); spirit. Visibility = Visibility . Collapsed; spirit. Source = bitmap ;} Void Dispatchertimer_tick ( Object Sender, Eventargs E) {spirit. Source = frames [count]; Count = COUNT = 7? 0: Count + 1 ;} Void Bitmap_imageopened (Object Sender, Routedeventargs E) {spirit. Source = sender As  Bitmapimage ; For ( Int J = 0; j <10; j ++ ){ Writeablebitmap WB = New  Writeablebitmap (150,150); WB. Render (spirit, New  Translatetransform () {X =-150 * j}); WB. invalidate (); frames [J] = (Imagesource ) WB ;} Dispatchertimer Dispatchertimer = New  Dispatchertimer (); Dispatchertimer. Tick + = New  Eventhandler (Dispatchertimer_tick); dispatchertimer. interval = Timespan . Fromilliseconds (150 ); // Repetition Interval Dispatchertimer. Start (); spirit. Source = frames [count]; spirit. Visibility = Visibility . Visible ;}}

 

 

In other words, when I was learning the dark blue right hand game tutorial, I converted his WPF version into the Silverlight version. During this period, I found this problem. The dark blue right hand handed me a task last night, that is, to understand this study and then give an ultimate answer. So this articleArticle.

Review the key points of this article,

1. Differences between images, resources, and content

2. Applicable scenarios of clip and writeablebitmap

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.