 |
|
 |
|
|
A Sprite Class for Silverlight |
|
Andy's Blog
|
By Andy Beaulieu on
7/5/2007 7:23 AM
|
|
|
|
In most 2D games (except for maybe some puzzle games), you have one or more characters moving around the screen that interact with each other, called Sprites. Each sprite has a position (x,y coordinate) and occupies a region on the screen. You need move these sprites and check them for collisions with other sprites, for example to see if the player will collide with an enemy.
One easy way to implement Sprites in Silverlight is to simply create a User Control. You can even create and design the User Control in an Expression Blend project and then use it inside your Visual Studio solution.
However, if we start creating oodles of User Controls within Blend and use them as Sprites, we will quickly find that we are adding repetitive code to each user control to manage the sprite. So why not create a base class that defines the basics of what we need from a sprite, and then have the user control inherit from that base class?
This is the approach I took for Destroy All Invaders (you can grab the source code for this game here). If we look at the source code, you will see a SpriteBase.cs class:
Notice that SpriteBase defines the position, bounds, current direction (angle of movement), speed, and whether or not the sprite is active. Another very important note is that SpriteBase inherits from Control:
public class SpriteBase: Control { ... }
... this inheritance is very important because it allows us to extend our "User Control Sprites" by inheriting from SpriteBase instead of Control.
So to use this base class, we simply need to change what our User Controls inherit from. So instead of using the default code generated by the user control designer...
public class MyUserControl : Control { ... }
... we can instead inherit from SpriteBase:
public class MyUserControl : SpriteBase { ... }
Another advantage to this OOP approach is that we can deal with Sprites at the generic SpriteBase level for any collision detection routines, etc. So to create a method to see if a sprite is off screen, we can pass in a generic SpriteBase to the following code:
public bool IsSpriteOffScreen(SpriteBase sprite) { /// Determines if a sprite is off the viewable screen if ((sprite.x + sprite.Width < -_scrollOffsetX) || (sprite.x > -_scrollOffsetX + this.Width) || (sprite.y + sprite.Height < -_scrollOffsetY) || (sprite.y > -_scrollOffsetY + this.Height)) return true; else return false;
}
That's it! Just a simple touch of OOP to increase code reuse. Happy coding!
|
 |
|
Comments (1)
|
|
|
|
Silverlight UI Controls |
|
Andy's Blog
|
By Andy Beaulieu on
6/24/2007 8:55 PM
|
|
|
|
If you have had a chance to play with Silverlight, you have probably asked yourself, where are the UI controls like TextBox, CheckBox, DropDown's, Grids? You might even have run across DevDave's Layout System and Controls which provide basic layout and input controls. And no doubt the official UI controls for Silverlight are coming soon.
But in the meantime, a company called Netikatech has released some very impressive demos of UI controls they built to mimic WindowsForms controls. Their main assembly looks a little bit hefty at about 900kb, but this is a nice demo of how Silverlight can support rich UI elements!
|
 |
|
Comments (0)
|
|
|
|
Destroy All Invaders! Source |
|
Andy's Blog
|
By Andy Beaulieu on
6/21/2007 3:09 AM
|
|
|
|
UPDATE 7/22/2009: The source code download and demo have been updated for Silverlight 3 RTW. Also, GPU Acceleration was added to the scrolling and the base class problem described in the comments was fixed.
UPDATE 10/14/2008: The source code download and demo have been updated for Silverlight 2 RTW.
In my last post, I talked a bit about Destroy All Invaders, a scrolling game I am working on using Silverlight which uses Microsoft Virtual Earth oblique (birds-eye) images for the background. In this post, I am making available the source code for Destroy All Invaders, and I'll talk a bit about how the scrolling background is accomplished.
 
Links to the Goodies!
You can play the game by clicking an image above, and you can get the source code here.
About the Scrolling
In order to do the scrolling background, I used a Canvas called ScrollBackground in Page.xaml to hold all the map tile images from Virtual Earth:
Each map tile for the oblique imagery is 256x256, and if you look at the function SetupTiles in Page.xaml.cs, you can see how these tiles are created and added into the ScrollBackground canvas:
string xaml = "<IMG height=256 width=256 source="\" \>"; _imgTiles[i, j] = (Image)XamlReader.Load(xaml); _imgTiles[i, j].SetValue(Canvas.TopProperty, i * 256); _imgTiles[i, j].SetValue(Canvas.LeftProperty, j * 256); ScrollBackground.Children.Add(_imgTiles[i, j]);
In order to create the scrolling effect, we then only need to change the position of ScrollBackground. This is done with two vars _scrollOffsetX and _scrollOffsetY.
Looking at the CheckScroll method, which controls the scrolling movement, we see that a handy utility function is used to calculate the X and Y position change of an object based on its Direction (angle) and Speed:
Utils.CalculateMovement(_scrollAngle, _scrollSpeed, out xdiff, out ydiff);
... after which we can change the location of the scrolled background:
ScrollBackground.SetValue(Canvas.LeftProperty, _scrollOffsetX); ScrollBackground.SetValue(Canvas.TopProperty, _scrollOffsetY);
So much more...
There is a lot more going on in Destroy All Invaders, like the actual integration with Microsoft Virtual Earth... which I hope to hit on in posts soon to come!
|
 |
|
Comments (7)
|
|
|
|
Destroy All Invaders! |
|
Andy's Blog
|
By Andy Beaulieu on
6/12/2007 9:44 PM
|
|
|
|
I had so much fun coding Silverlight Rocks! I thought I would try one more game in Silverlight before moving on to some data type stuff.
This prototype is called Destroy All Invaders and is inspired by Mark Fennell's Wings Flash game. But instead of using Google Maps, I am using Microsoft Virtual Earth Oblique (Birds-eye) imagery. The goal is simple: use the mouse to steer your chopper around and destroy the invading UFO's before they destroy you. You can use the Ctrl key to accelerate and the left mouse button to fire.

I am able to get about 30 fps consistently with the scroll, not as good as the 60 fps with stationary backgrounds, but still better than a sharp stick in the eye.
I may be able to do some tweaks to get more speed, and I'm guessing the final release of Silverlight 1.1 will be faster as well. Currently, the background is a canvas that I plug Image elements into with map tiles. Virtual Earth uses 256x256 tiles for its oblique view. These images are snapped by low flying aircraft and the quality is so good it's a bit spooky and big-brother-ish.
The ufo's and chopper are vector-based Path elements but the cool shadow effects were accomplished by using PNG images (so that the alpha blending comes through as a shadow).
I will be posting some more info on this game later and source code examples...
|
 |
|
Comments (0)
|
|
|
|
Silverlight Rocks! |
|
Andy's Blog
|
By Andy Beaulieu on
5/18/2007 5:15 AM
|
|
|
|
UPDATE 10/14/2008: The source code download and demo have been updated for Silverlight 2 RTW.
As I mentioned before, I have been playing around with Silverlight 1.1 Alpha (and now Silveright 2 Beta 1) to both learn and see how well it could handle a casual game such as an asteroids type clone.
Well, check out SILVERLIGHT ROCKS! I have also made the source code available.
As far as the Silverlight Alpha, it felt very stable for me and it felt quite productive for an alpha! In addition to some issues I mentioned before, I ran into some other things:
- The MediaElement did not want to play my MP3 sound effects created with Audacity (using either ID3v1 or ID3v2 format). So I ended up converting to .WMA and they were happy.
- I could not get the Downloader component to work with my .WMA files (so you will likely notice an uncomfortable "pause" when playing back the first laser fire sfx). Even worse I found that IE would lock up when refreshing or navigating off the page after attempting to use the Downloader component.
THE GAME LOOP
Most games contain a central loop that gets executed for each timer tick. Inside this loop, sprites are moved, AI is performed, and collisions calculated. You might be wondering, why not use the key-based animations available in XAML? Well, it would be pretty difficult to calculate dynamic, angle-based movement for sprites using strict Storyboards. Using a main game loop gives ultimate control over what is happening per frame.
But note that there is no customary Timer Class available in Silverlight 1.1 Alpha. Instead, we can use an animation timer as described in this previous post.
HANDLING XAML ASSETS
I used Expression Design to draw out the asteroids and ship and ultimately create their XAML. You will notice that there are separate XAML files (SpaceShip.xaml, Asteroid.xaml, AsteroidBig.xaml, etc.) for each "sprite" in the game. These are added to the main Page.xaml document at run time through the several "Create" methods in Page.xaml.cs.
If you examine the Properties Window for any of these "Sprite" XAML files, you will notice that their Build Option is set to "Embedded Resource." This will cause the XAML file to be built into the Assembly (.dll), which is downloaded to the web client when the user loads the Silverlight application.
So how do these XAML assets get used at run time? If we peek at Utils.cs, we see a short helper routine called GetResource which will return the XAML string from the embedded resource by name. Note that the resource name will be in the format ProjectName.File.xaml, where ProjectName is your project name, and File.xaml is the XAML file name.
public string GetResource(string ResourceName) { string resource;
using (System.IO.StreamReader reader = new System.IO.StreamReader(this.GetType().Assembly.GetManifestResourceStream(ResourceName)))
{
resource = reader.ReadToEnd();
} return resource;
}
For example, to load the embedded XAML resource "SpaceShip.xaml" we would call:
string xaml = utils.GetResource("SilverlightRocks.SpaceShip.xaml");
After we have the xaml string, we can create an instance of the class and insert the object into our main document using XamlReader.Load. For example,
_asteroids[i].PathObject = XamlReader.Load(thisXaml, false) as Path;
One important note: if you name any object in your XAML file using the x:Name attribute (which Expression will often do), and you plan on using XamlReader.Load, you must also include the xaml xml namespace (xmlns) like so:
http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Ship" Width="50" Height="44" Canvas.Left="350" Canvas.Top="175">
Keeping the Sprites' XAML files separate from the main Page.xaml has several advantages. It makes it easier to create multiple instances of a sprite through code; it keeps the XAML files shorter and easier to maintain; it allows editing of the separate assets through Expression Blend.
MIXING IN STORYBOARD ANIMATIONS
Although I mentioned earlier how a main Game Loop makes it easier to have ultimate control of movement and collisions, there are some animations that are better left to Storyboard animations. For example, when our ship hits an asteroid and explodes, there are three chunks of debris that float off and fade out. This kind of mundane animation - without collisions or user input - is perfect for a storyboard.
I created the explosion animation using Expression Blend, which offers easy to use Key based animation. The resulting XAML file is ExplosionDebris.xaml, and contains a storyboard animation named ShipExplode:
... and when the ship collides with an asteroid, we can first position the Canvas containing the explosion ("ExplosionDebris") over the Ship's position, and then start the Storyboard animation using its Begin() method.
MIXING SOUND
Silverlight's MediaElement class supports sound mixing - all we need to do is create enough copies of each sound to mix in. You can imagine that if we only created one copy of the Laser Fire sound in memory, the sound would restart every time the user pressed "fire" and the effect would be pretty poor! So for the laser fire sound effect, we create an array of copies of the sound and then iterate through them in sequence.
As I mentioned before, I am having issues with Silverlight 1.1 Alpha when trying to place my sounds in a ZIP and use the Downloader class. While I get an HTTP 200 and can assign the Source property without error, the sounds do not play back and IE locks up when trying to refresh or navigate using history.
SUMMARY
Silverlight is a promising technology for creating casual games with easy web distribution. While I have not done any testing on the Mac, the frame rate and performance on the PC seems quite adequate for many applications --- and this is at Alpha!
|
 |
|
Comments (11)
|
|
|
|
|
Silverlight for "Casual Games" |
|
Andy's Blog
|
By Andy Beaulieu on
5/9/2007 8:02 PM
|
|
|
|
I was curious about Silverlight's ability to create casual games with decent (circa 1985) graphics, frame rate, input and sound so I started on an Asteroids type proof of concept (gee, how many of those do you think are gonna surface!)
SEE MY WORK-IN-PROGRESS (you'll need Silverlight Alpha, link on page)
The game is not complete yet, but I think its safe to say Silverlight will support some fairly adequate games in the "casual" category. I'm seeing about 60 fps on the asteroids clone.

I have to go on the road for the next few days so I won't be able to finish this thing off right away but I'll be getting some code and tips up eventually. Here are a couple of things I ran into with the Alpha:
- I needed to implement my own (crappy) collision detection. I really expected with all of the vector capabilities that HitTest functionality would be in Silverlight but it isn't (yet anyway).
- There isn't a "real timer" class in Silverlight yet, so you need to use an Animation Timer as a workaround (see prior blog post)
- They KeyDown event doesn't appear to support arrow keys. Hopefully this will be fixed before release.
- I'm not sure if this is something I'm doing but my MediaElement only plays once (yeah I need to add in more sfx too anyway)
|
 |
|
Comments (1)
|
|
|
|
Timers in Silverlight |
|
Andy's Blog
|
By Andy Beaulieu on
5/5/2007 10:36 PM
|
|
|
|
I was surprised to see that custom timers (like System.Timers.Timer) are not yet supported in Silverlight 1.1 Alpha. These would be great for creating "casual games" such as those that made Flash so popular.
Luckily, I came across this post by Joe Stegman that shows a workaround by using an Animation Timer:
First set up an Animation Timer in your xaml...
< Canvas.Resources> <Storyboard x:Name="timer"> <DoubleAnimation Duration="00:00:0.02" /> </Storyboard> </Canvas.Resources>
Then you can add an "tick" event handler and start up the timer..
timer.Completed += new EventHandler(timer_Completed); timer.Begin();
And finally, make sure you restart the timer in the timer_Completed event.
void timer_Completed(object sender, EventArgs e) { // ... do per tick stuff here...
// restart the timer timer.Begin(); }
|
 |
|
Comments (4)
|
|
|
|
Getting Started with Silverlight 1.1 Alpha |
|
Andy's Blog
|
By Andy Beaulieu on
5/4/2007 8:59 AM
|
|
|
|
There is a quick Getting Started with Silverlight page here, but I thought I would extend this a bit with my own experiences.
First, I highly recommend going the route of using the VPC Images for Orcas because you can easily hose up your development PC so that when Orcas is released things will never be right! However, you'll need some chubby disk space for the VPC image - about 15 GB.
So here is the order of downloads:
1. Orcas Beta 1 VPC (first download the Base Image and then all of the .rar files containing the differencing images)
2. You will also need to install the Silverlight 1.1 Alpha runtime on the VPC image.
3. Next you can install the Silverlight Tools Alpha for Orcas.
4. If you made it this far, you can now start with the QuickStart Tutorials for 1.1 Alpha.
It appears there is no XAML designer yet for the Silverlight Alpha template inside Orcas (not even a bad designer) but you can copy-and-paste XAML from a WPF application template to get by.
|
 |
|
Comments (2)
|
|
|
|
Book Review: Practical .NET 2.0 Networking Projects |
|
Andy's Blog
|
By Andy Beaulieu on
4/25/2007 3:52 PM
|
|
|
|
As I've mentioned before, there is something really cool about controlling external devices from code (especially humanoid robots). Now I've stumbled across a book that is dedicated to just that: Practical .NET 2.0 Networking Projects by Wei-Meng Lee.
This book walks the reader through several projects, detailing hardware setup and code for integrating with: a GPS receiver, a fingerprint reader, IR devices, RFID, webcam, and an ultrasonic sensor. While the book is a fun read and feels geared towards hobbyists, its projects have definite applications in the professional world as well.
One of the most interesting projects in the book details an RFID attendance application using the $39 Parallax RFID Reader and $2 Parallax Tag. Lee uses the $119 Javelin Demo Board to hook the reader to his PC but also mentions cheaper solutions. It's amazing how mainstream and inexpensive this technology is.
Whether you're a hobbyist looking for a fun time, or a professional working on your latest project, Practical .NET 2.0 Networking Projects has relevant and timely info for home and office.
|
 |
|
Comments (0)
|
|
|
|
|
 |
|
 |
|
|