 |
|
 |
|
|
|
Silverlight for Linux |
|
Andy's Blog
|
By Andy Beaulieu on
9/5/2007 8:20 AM
|
|
|
|
I was excited today when I learned from Scott's post about a Microsoft/Novell partnership to provide support for Silverlight on Linux.
Not because I want to run my Silverlight apps under Linux, nor do I expect there to be a huge user base of Linux users accessing my Silverlight apps. Although all that is very cool.
I am excited because I think this acknowledgement of Moonlight will be the beginning of "Silverlight Everywhere." Since the Moonlight source code will be available for coders to port to other platforms, look for Silverlight coming soon to your Wii or iPhone!
You have to wonder how long before Microsoft makes Silverlight Open Source as well... It seems to only make sense since the competition did so earlier this year.
|
 |
|
Comments (0)
|
|
|
|
Mmmm... Beer |
|
Andy's Blog
|
By Andy Beaulieu on
8/14/2007 5:54 PM
|
|
|
|
I'll be giving a few Silverlight talks in the coming months, the first of which is for our local CNY .NET Developer Group. And I was thinking, I really need something a bit more data oriented than the games I have been working on... Something with a web service and LINQ, something showing JSON going over the wire, something with.... BEER!!!
And so was born Andy's Fridge. This is a mini (right now anyway) beer database that uses a Web Service with SQL Server back-end. If the web service is unavailable, a cached Xml file is used instead.
One of the neat dynamic things about Andy's Fridge is that the labels are stored as image Url's in the database and loaded onto the bottles at runtime, so you have kind of a beer mashup. The database is very simple - only one table in fact. And yeah, I need to add more beers so if you have any favorites let me know so I can both sample them and add them to the DB.
I don't want to give too many details away, you will have to come to one of my talks for that! But in the meantime, feel free to snag the code and take a look.
And no, beer isn't the only thing I keep in my fridge. I have mustard and ketchup too.
|
 |
|
Comments (0)
|
|
|
|
Silverlight 1.1 Alpha Refresh Migration |
|
Andy's Blog
|
By Andy Beaulieu on
8/3/2007 7:23 AM
|
|
|
|
Last Friday, July 27th, the 1.1 Alpha Refresh of Silverlight was released into the wild, breaking any previous Silverlight Alpha applications... including mine of course...
This morning I released updated versions of Silverlight Rocks! and Destroy All Invaders which are compatible with the 1.1 Alpha Refresh. Here are links to the updates (they use the same url's as previously so no need to update links you may have elsewhere):
Silverlight Rocks! [source and info] [play it] Destroy All Invaders [source and info] [play it]
There are lots of useful blog entries with help on migrating from 1.1 Alpha to the 1.1 Alpha Refresh but I did hit a couple of issues that I didn't see mentioned elsewhere...
Storyboard.Begin() Behaves Differently IMPORTANT: Read below for update to this problem!! The biggest snag I hit was that the behavior of Animation.Storyboard.Begin() apparently changed with the 1.1 Alpha Refresh. In the previous Alpha, it was possible to use a Storyboard DoubleAnimation to mimic a timer and form a Game Loop around it. But in the latest refresh, calling Storyboard.Begin() will cause the immediate execution of it's Completed event. This causes an endless loop with no UI updates when you call Storyboard.Begin() at the end of you game loop.
I wasn't able to find a way around this Storyboard.Begin() issue so instead I replaced my Storyboard timer with a browser timer like so:
System.Windows.Browser.HtmlTimer timer; timer = new System.Windows.Browser.HtmlTimer(); timer.Interval = 20; // not really reliable :( timer.Tick += new EventHandler(timer_Completed);
There are two problems with this. The first is that HtmlTimer is marked obsolete and has the following compiler warning:
System.Windows.Browser.HtmlTimer' is obsolete: 'This is not a high resolution timer and is not suitable for short-interval animations. A new timer type will be available in a future release.
... and the second problem is that the Interval property does not seem all that reliable in determining frame rate (as the compiler warning states). But, it does seem somewhat adequate at least until "a new timer type is available in a future release" (let's hope that warning is accurate).
UPDATE: Thanks to John Donnelly and Chris Cavanagh for both setting me straight on the Storyboard problem! It turns out the change in behavior for Storyboard is that you must have an animation target for the Storyboard, or an exception is thrown. Here is an example of setting up the Storyboard as timer:
<!-- Set up our game timer. As of Alpha 1.1 Refresh, you NEED to give the timer a bogus target to avoid exceptions --> <Canvas.Resources> <Storyboard x:Name="timer"> <DoubleAnimation Duration="00:00:00.01" Storyboard.TargetName="bogusTimerTarget" Storyboard.TargetProperty="Width" /> </Storyboard> </Canvas.Resources>
<Canvas Name="bogusTimerTarget"> </Canvas>
I have updated both Silverlight Rocks and Destroy All Invaders samples with this fix.
Silverlight Template and SDK Have Wrong Silverlight.js It turns out that the Alpha 1.1 Refresh SDK and Visual Studio Project Template add in the wrong version of Silverlight.js. The end result of this is that if a user visits your Silverlight-enabled web page and they do not have Silverlight 1.1 installed, the little icon that appears to install will point them to the 1.0 install instead of 1.1. The solution is to "borrow" the correct 1.1 version of Silverlight.js from somewhere else as described in this very helpful forum post.
Hidden Visibility went Bye-bye This is the one breaking change that I knew about before going into the conversion and was the easiest to solve. Basically just do a find-and-replace for Hidden wherever it is used to assign Visibility, and replace it with Collapsed.
Well, that's about it. I have to say the conversion took me longer than anticipated because of the first two issues. But being this is still only Alpha I am anticipating even more fun migrations in my near future :)
|
 |
|
Comments (3)
|
|
|
|
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 (10)
|
|
|
|
|
|
 |
|
 |
|
|