Silverlight Dynamic Video Puzzle

My blog title says it all, Monkey see, Monkey Build. I saw Microsoft Surface's video puzzle and I needed to build it. I took this opportunity to play with Microsoft's new technology,
Silverlight and build my own puzzle game. I couldn't find anything out on the Internet regarding dynamic video creation with Silverlight so I took it upon myself to do this. The screen shots in this demo will be in c#,
however, everything should hold true for VB.

Fixed the Silverlight.Js, used the new version that is included with the 1.1 Refresh SDK so the proper installer will prompt now. Downloads are corrected also too.

6/20/2008 - Verified the solution works with Silverlight 2.0beta2.

Spec's, Requirements and headaches

So I had a few mental requirements for the application to "entertain" myself.

Be able to rotate the video blocks

Be able to translate

Be able to increase the difficulty of the puzzle on the fly.

Zero interaction with the keyboard

Simple, right? You want to see a demo too see some awesomeness? No problem,
head over to my site and see it in person.

Microsoft Surface Video Puzzle

Clint's Silverlight Video Puzzle

To the Internet Batman!

To help save time building this, I first when out and attempting to see if anything has been done anything close to this before. I found

Also I need 2 small controls which I found out are in the Silverlight SDK. I needed horizontal slider controls for this app. While I know a text box control would have worked just as well, see requirement 4.

On the Silverlight community site, there is also a very nice demo showing the
photo application in Surface with source code. This is where I learned the majority of what I needed. This application was very close to where I needed to go with mine. However, while it was close, it wasn't perfect. Parts of the photo application code
are pretty much copied. This isn't the best way of doing this, but it is one way of doing it.

Toolbelt: check, Keyboard: check, Band-aids: check

So on to building it. I first started off with a new project and some XAML.

After clicking "OK", I get a very nice blank project.

We'll want to add an additional XAML object for the video blocks. Go to "Project -> Add New Item", select Silverlight Page, name it "VideoBlock.xaml" and click "OK".

So now we have everything we need for the most part, grab any video you have, if you don't have one, go to a site like
TeamXbox and grab one from there. I used Windows Movie Maker and grabbed a snippet from The Office (best show ever).

In addition to all these files, we need to add in a reference to the Silverlight SDK to get a hold of the Slider controls. Go to "Project -> Add Reference", and add in the
Silverlight.Samples.Controls.dll.

While we have a reference in the application, we still need the XAML to know about this also. So we'll add a line to link this in. It is the xmlns line that I bolded, XML name space, real clever, eh? We'll also change the background color to a gray so
we can see it more easy.

Silverlight 101

So in Silverlight, you have brushes which can "painted" onto objects. One of these brushes is called the VideoBrush which I'll talk about later on. For playing videos, one would use the
MediaElement. Lets add this to our canvas.

<MediaElementx:Name="media"Source="theOffice.wmv"/>

Now if we run the application at this point, we'll get the video playing. Lets sit back with some popcorn and enjoy this victory for a second or two. Now that we have this, lets hide it since this isn't what we want. We do that by adding in an XML attribute
Opacity and setting it to 0.

On top of that element, lets add on some TextBlock elements and the sliders.

Video as Paint?

So now that we have that small part done, lets get into more of the nitty gritty with video. As I said earlier, you'll use a
VideoBrush to paint on the video.

We'll use the brush as the Fill for the rectangle we'll be using to show off the clip of the video we want.

Still not moving? Try explosives?

While doing this project, I discovered an interesting thing when using the VideoBrush and dynamically appending items on. Having items in the XAML rather than programmatically creating everything caused it not to work properly. Nothing would appear.

Throwback to how UI's use to be done

The XAML for this is a simplified version of the Surface demo Photo.XAML. You have a 3 Rectangles, 1 for the video, 1 for translation and 1 for rotation. Simple, no? Doing all this by hand gets a bit annoying since you need to nest everything properly.

Here is the more interesting VideoBrush code. You need the name from the
MediaElement along with the how much of an offset you want the video. Since your moving the "camera" in, this value needs to be negative.

There is a mouse on my object!

So now we have our video block element prepped and ready. There are additional events added in, but they are fairly boiler plate. When looking at this code, you see I pass in a delegate, a function pointer if you will. Why do I do this? This is how the
mouse position is calculated. I bet this could be redone better, but this is how I did it. The parent element, the canvas, has the mouse position I need to calculate proper translation and rotation, however, mouse events on the VideoBlock object will give
me the mouse position only on that element. So I may be at point 150, 150 on the screen, on the VideoBlock object, I'm actually at 10,15.

Additionally, this approach allows me to move the VideoBlock to the top of the objects. Once again, this could be done other ways, this is how I chose to do it.

So on all my mouse related all boils down to doing the exact same function. Since events are bubbled, a mouse movement on a VideoBlock is also a mouse movement on the root canvas.

You built a car out of all these parts?

So we move back from VideoBlock.xaml.cs to Page.xaml.cs

We've created our primary object for painting video, lets populate it. First, how do we know how big the media file is? With the
MediaOpened event! And we'll restart the video with the
MediaEnded event.

So now that we have the media loaded, we can use the media.NaturalVideoWidth and media.NaturalVideoHeight properties to find out exactly how big the video is! I have a function that is fired off when the page is first loaded or a slider value has changed.
This is how we chop it up.

Wrapping it up

So as you can see, Silverlight is pretty powerful once you figure out how to tame it. I used example base code and modified it to suit my own needs to dynamically alter a video in real time. There are a few code tweaks that could happen to improve this
code and I'm betting with some additional effort, one could remove the delegate. In addition, you could add in edge detection code and a timer to make this into a true video puzzle game. This was a pet project I worked on while I was at the airport. This
demo can be downgraded to Silverlight 1.0 also. I don't believe anything I did was really Silverlight 1.1 (now 2.0) only.

Clint's Bio:

Clint is an academic developer evangelist for Microsoft. His two primary development languages are C# and JavaScript. He has built a
Disco Dance Floor too! In his off time, he whips up other random weird projects and does twenty something activities with his friends. His next two big projects are an automated bartender and a skateboard segway. Clint's blog is
betterthaneveryone.com and can be emailed at
crutkas@microsoft.com if you have any question.

Remove this comment

Remove this thread

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums, or
Contact Us and let us know.