Mar 23

Since XNA and Silverlight are both supported on Windows Phone 7, a common question is which makes more sense for developing games. The definitive answer is “it depends” :)

Both technologies have their benefits and it would be great if we could eventually get to the point where you could combine the graphics capabilities of both in the same application and use the best tool for the job. Now I haven’t delved too deep into the changes in XNA for Windows Phone so I’ll be going mostly off of what I’ve experienced with game development on XNA in the past.

Generally writing a game will be easier in XNA since XNA was built from the ground up to be a game framework. Many of the decisions made when architecting XNA also make it a non-ideal platform for developing many other types of apps besides games.

The most notable architectural difference is the idea of a visual tree versus drawing everything every frame. In Silverlight for something to be displayed it needs to be added as the child of some other element. In XNA, everything is drawn every frame. If you don’t explicitly draw something it won’t show up. Which one of these is better depends on your game, but if there is a lot of action the XNA “immediate mode” type rendering will probably be the better choice.

Let’s take a look at some benefits of each (I’m sure there are more on both sides):

XNA Benefits

  • Great support for 3D
  • Superior performance when many elements moving or being added/removed
  • Built in game loop
  • XNA’s polling based input generally a better fit than Silverlight’s event based input for games
  • XNA content pipeline makes handling large stores of content easier
  • More image formats supported
  • Can make game for both Xbox and Phone
  • Graphics blend modes (Silverlight only has alpha blending)
  • More GPU acceleration built in
  • Lighter memory footprint for bitmap based games
  • Superior shader support
  • Drawing with a “tint” easier

Silverlight Benefits

  • Vector graphics (XNA has some very basic line drawing support)
  • Vector drawing of text (XNA text is bitmap based)
  • Can make game for phone and web
  • Storyboard animations
  • Visual states and behaviors
  • Navigation framework
  • Controls (button, listbox, user controls, etc)
  • Expression Blend design support
  • Event based model is more familiar to many developers
  • Data binding can come in handy in some scenarios
  • VisualTreeHelper useful for determining what element is being touched

So if you have a game that’s vector graphics based, or relies on things like buttons and other GUI elements you probably want to choose Silverlight for your game development. If you’re doing a 3D game or a 2D game with a lot of motion or particle effects choose XNA. If you’re somewhere in between you may want to pick whatever you’re most familiar with, or it may depend on whether you also want to make the game available on Xbox or web.

It’s great that both options are available and you have the choice of which to use.

Mar 23

Things got a lot more interesting last week for developing games on the .NET framework with the announcements at MIX10 about Windows Phone 7 development. You will be able to write games in either XNA or Silverlight and Silverlight games will have access to many of the XNA libraries (except those related to graphics rendering). Libraries such as the XNA audio APIs are a big help for Silverlight game developers and you also have access to things like Vector2 and Matrix. Over the last few posts on this blog I hope you can start to see the power of using these classes in conjunction with Silverlight.

All you need to do to access Vector2 and other XNA classes on Windows Phone in your Silverlight project is to add a reference to the Microsoft.Xna.Framework assembly and you’re ready to go.

The only downside to using these classes in Silverlight on the phone is that these classes are not available in Silverlight for desktop. Not all is lost, however, and you can still create games that work on both while still taking advantage of what the XNA libraries offer. To do this simply use the actual XNA libraries on Windows Phone and use the SilverArcade.SilverSprite.Core library that I’ve been using to create the Space Rocks game for the web version. For those that have been following the evolution of SilverSprite hopefully the changes over the past couple of months make a lot more sense now. SilverSprite is perfectly positioned to fill the gap between phone and desktop Silverlight game development and will be enhanced further to support the XNA audio APIs and whatever else makes sense.

To make going back and forth even easier I have made a version of the SilverSprite core library for Windows Phone that just contains the game loop class and helper classes so that you can easily get games that use the SilverSprite core game loop working on the phone. Right now it’s a straight port but I’ll be improving it to take advantage of things the phone offers like Stopwatch for high resolution timing. This assembly is now available in the Version 3 Alpha 2 download of SilverSprite.

Mar 14

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_5_rotation.zip

Adding rotation is actually pretty simple, we just need to use a RotateTransform on the ship. The only tricky part is that the RotateTransform uses degrees clockwise, and XNA uses radians counter-clockwise. So we have a choice to make. When setting the rotation should we expose the property using the XNA or Silverlight convention? I prefer the XNA style because radians are easier to work with in general. Here is our Ship class with a new Rotation property:

using System.Windows.Media;
using Microsoft.Xna.Framework;

namespace SpaceRocks
{
    public class Ship : Sprite
    {
        float rotation;
        RotateTransform rotateTransform;

        public Ship()
        {
            this.DefaultStyleKey = typeof(Ship);
            rotateTransform = new RotateTransform();
            this.RenderTransform = rotateTransform;
        }

        public float Rotation
        {
            get
            {
                return rotation;
            }
            set
            {
                if (rotation != value)
                {
                    rotation = value;
                    double degrees = -MathHelper.ToDegrees(rotation);
                    rotateTransform.Angle = degrees;
                }
            }
        }
    }
}

So in the constructor we set the RenderTransform property of the control to a RotateTransform. In the Rotation property we convert the radians to degrees using the SilverSprite MathHelper.ToDegrees method (this is based on the XNA MathHelper class which has the same method) and then we set the Angle property of the rotate transform.

In the Game class we can define a rotation speed and update the rotation angle in the game loop:

double rotationSpeed = 4.75;

private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
{
    double seconds = e.Result.TotalSeconds;
    ship.Rotation += (float)(rotationSpeed * seconds);
}

If you run this you’ll see that it rotates but not quite how you would expect. It’s rotating around the top left corner. We can fix this by setting the RenderTransformOrigin of the Ship control. So in the Ship’s constructor add the following:

this.RenderTransformOrigin = new System.Windows.Point(.5, .5);

This tells the Ship to do its render transforms around a point at half of the width and half of the height (the center). Now if you run it again you should see the ship rotate properly.

image

Mar 14

Source code: http://www.bluerosegames.com/SpaceRocks/SpaceRocks_4_Inheriting_Sprite.zip

One of the big benefits of using a Silverlight Templated Control for our sprite class is that it’s easy to inherit from it. This can be tricky if using a user control and if you use something else it’s hard to associate visuals with it. The first sprite type we’ll inherit from Sprite is our ship. Create a new Silverlight Templated Control called Ship.cs. This creates a new template in Generic.xaml and a barebones class definition. This class inherits from Control by default, but you can change it to inherit from Sprite (since Sprite inherits from Control this is ok).

In Generic.xaml, let’s replace the default template generated for the Ship control with one for how we want the ship to look.

<Style TargetType="local:Ship">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Ship">
                <Canvas Height="27" Width="22">
                    <Path Data="M11,1.5 L19,25 14,21 8,21 3,25 11,1.5z" Stroke="White" StrokeThickness="2" StrokeLineJoin="Round"/>
                </Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

You can also edit templates in Generic.xaml in Blend by selecting them from the Resources tab. This is how the ship looks in Blend:

image

We’ll do some other work later to make it look more like the original arcade game but for now this will work. Now if we go into the Game class and replace the sprite with our ship and center it on the screen the code will look like this:

using System;
using System.Windows.Controls;
using Microsoft.Xna.Framework;

namespace SpaceRocks
{
    public partial class Game : UserControl
    {
        Ship ship;

        public Game()
        {
            InitializeComponent();
            ship = new Ship();
            ship.Position = new Vector2(320,240);
            LayoutRoot.Children.Add(ship);
        }

        private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
        {
            double seconds = e.Result.TotalSeconds;
        }
    }
}

Now if you run the game you should see the sprite in the middle of the screen. Well, almost in the middle if the screen. The top left corner of the sprite is actually in the middle of the screen. We can see this easier if we draw a little rectangle in the middle of the screen:

<Rectangle Width="4" Height="4" Canvas.Left="318" Canvas.Top="238" StrokeThickness="0" Fill="White" />

And the output looks like this:

image

For this game, we want to position sprites by specifying their center value. Since the sprites are going to be different sizes it would be best to figure out dynamically based on the size of the sprite where the center is.If we add this code to the Sprite class all of our sprites will be able to take advantage of it. What we’ll do is use the OnApplyTemplate method to get the size of the root element in the sprite template and then subtract half of the size from the position when the set the Canvas.Left and Canvas.top properties. Here is the new Sprite class:

using System.Windows.Controls;
using Microsoft.Xna.Framework;
using System.Windows;
using System.Windows.Media;

namespace SpaceRocks
{
    public class Sprite : Control
    {
        double x, y;
        double dw = 0;
        double dh = 0;
        static Vector2 gameSize = new Vector2(640, 480);

        public Sprite()
        {
            this.DefaultStyleKey = typeof(Sprite);
            this.SizeChanged += new SizeChangedEventHandler(Sprite_SizeChanged);
        }

        void Sprite_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Vector2 pos = Position;
            x = double.NaN;
            y = double.NaN;
            Position = pos;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            FrameworkElement element = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
            dw = element.Width / 2;
            dh = element.Height / 2;
            Width = element.Width;
            Height = element.Height;
        }

        public double X
        {
            get
            {
                return x;
            }
            set
            {
                if (x != value)
                {
                    x = value;
                    this.SetValue(Canvas.LeftProperty, x - dw);
                }
            }
        }

        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                if (y != value)
                {
                    y = value;
                    this.SetValue(Canvas.TopProperty, y - dh);
                }
            }
        }

        public Vector2 Position
        {
            get
            {
                return new Vector2((float)x, (float)y);
            }
            set
            {
                X = value.X;
                Y = value.Y;
            }
        }

        public Vector2 Velocity { get; set; }

        public void Update(double elapsedSeconds)
        {
            Position += Velocity * (float)elapsedSeconds;
            if (Position.X > gameSize.X) Position -= new Vector2(gameSize.X, 0);
            if (Position.X < 0) Position += new Vector2(gameSize.X, 0);
            if (Position.Y > gameSize.Y) Position -= new Vector2(0, gameSize.Y);
            if (Position.Y < 0) Position += new Vector2(0, gameSize.Y);
        }
    }
}

In the OnApplyTemplate method, we get the root element of the template using the VisualTreeHelper class, and set the size of the control to the size of the root element. We also set dw and dh to half of this size so that we can use these values when setting the left and top properties. In the SizeChanged event, in order to force the position to be set when the size changes, we need to set the backing fields to an invalid value (well, actually any value other than the previous value) otherwise the actual positioning code will be skipped. This is one problem with the optimization of checking againt the backing field property but it’s not that big of a deal and the benefits far outweigh this extra complexity.

Now if you run the game you should see that the ship is centered on the screen.

image

We can now remove our little rectangle since it has served its purpose. In the next step we’ll see how we can rotate the ship.

Mar 12

Looking to squeeze every bit of performance out of your Silverlight game? Be careful about setting and getting dependency property values (like Visibility, Canvas.Left, etc). First of all, there is overhead and code that runs behind the scenes when doing this, so it’s a good idea to wrap these properties and keep a local copy and return this one when getting a value and comparing against it before setting a value. This is just some common sense optimization.

There is, however, a potentially more important reason to compare to a local value before setting the property. Even if you set a dependency property to the same value it had before, this is treated as a change and can cause Silverlight to have to re-render the element. This is especially important when using BitmapCache to take advantage of GPU rendering.

Mar 09

Source code: http://www.bluerosegames.com/spacerocks/SpaceRocks_3_Sprites_2.zip

In the last step we created a sprite class based on the Silverlight Templated control. We gave this class X and Y properties to position the sprite. This is a great start and combining that with our game loop from step 1 we could start putting together the basics for a game. In our Space Rocks game, sprites will move based on a velocity. Let’s see how we can add code to the sprite class to take care of this.

Velocities have an X and Y component and to calculate the position at any point in time we can calculate the distance traveled by multiplying the velocity by the time since the last time we set the position and add that to the previous position. This is where the SilverSprite core assembly can help us out. One of the things that this assembly provides for us in the XNA Vector2 data type. A Vector2 is a value data type (aka a struct) with an X and Y value and a bunch of helper methods to let us do game related things like multiplying by a value or adding two Vector2 values together. Let’s implement a Position property on the Sprite class which is of type Vector2 and also create a Velocity property. Add the following to Sprite.cs:

public Vector2 Position
{
    get
    {
        return new Vector2((float)x, (float)y);
    }
    set
    {
        X = value.X;
        Y = value.Y;
    }
}

public Vector2 Velocity { get; set; }

You’ll also need a using statement for the Xna namespace:

using Microsoft.Xna.Framework;

For the Position property under the covers we are actually setting and getting the X and Y properties of the Sprite class. This allows us to use whichever makes the most sense for the task at hand.

One nice thing about using the SilverSprite core library to help us out is that you can start to get an idea about how to do some of the basics in XNA. This looks like it’s going to get more important with Windows Phone 7 Series if there is a game you want to develop that makes more sense to write in XNA. SilverSprite attempts to mimic the XNA APIs and doesn’t require XNA to be installed for you to use it.

Something that’s a little tricky about the Vector2 struct and most other things in XNA is that they use the float data type. Almost everything in Silverlight uses double. So we need to cast between the two when going back and forth. XNA uses float for its values for efficiency since these translate directly to the data structures used by the graphics card.

Let’s add a method to the Sprite class that we can call from our game loop to update the sprite position based on the current velocity and time since the last update.

public void Update(double elapsedSeconds)
{
    Position += Velocity * (float)elapsedSeconds;
}

This is where Vector2 starts to shine. We can simply use addition and multiplication operators and we don’t have to worry about the X and Y components.

Now in the Game class, we’ll make some changes to use the Position and Velocity properties and we’ll keep a reference to the sprite object so that we can reference it in the GameLoop_Update method.

using System;
using System.Windows.Controls;
using Microsoft.Xna.Framework;

namespace SpaceRocks
{
    public partial class Game : UserControl
    {
        Sprite sprite;

        public Game()
        {
            InitializeComponent();
            sprite = new Sprite();
            sprite.Position = new Vector2(100, 50);
            sprite.Velocity = new Vector2(100, 100);
            LayoutRoot.Children.Add(sprite);
        }

        private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
        {
            double seconds = e.Result.TotalSeconds;
            sprite.Update(seconds);
        }
    }
}

Now the sprite should move diagonally. You can play with the velocity values and see how it behaves. You can even use negative values for the X and Y components of the velocity.

One problem we have is that the sprite now moves right off of the edge of the screen. In our game we want these values to “wrap” and if they get too large or too small, we’ll move them to the other end of the screen. We can do this in our Sprite.Update method.

static Vector2 gameSize = new Vector2(640, 480);

public void Update(double elapsedSeconds)
{
    Position += Velocity * (float)elapsedSeconds;
    if (Position.X > gameSize.X) Position -= new Vector2(gameSize.X, 0);
    if (Position.X < 0) Position += new Vector2(gameSize.X, 0);
    if (Position.Y > gameSize.Y) Position -= new Vector2(0, gameSize.Y);
    if (Position.Y < 0) Position += new Vector2(0, gameSize.Y);
}

Now if you run the game the sprite should wrap when it hits the edge. One thing you’ll probably notice is that the sprite goes off of the end of the game surface. The Canvas panel doesn’t clip to its bounds by default so we can add a Clip property to the game canvas.

<Canvas x:Name="LayoutRoot" Background="Black" Width="640" Height="480">
    <Canvas.Clip>
        <RectangleGeometry Rect="0,0,640,480"/>
    </Canvas.Clip>
</Canvas>

This isn’t necessary if your game fills the entire Silverlight plug-in and has some overhead so only use it if you need it. Now if you run the game the edges should be clipped and you won’t see the sprite go off of the game surface.

In the next post we’ll look at inheriting from the Sprite class and creating the ship for our asteroids game.

Mar 09

Source code: http://www.bluerosegames.com/spacerocks/SpaceRocks_2_Sprites.zip

When we refer to a “sprite” in game development, we’re typically referring to any 2D visual element. Sometimes sprites are defined as only elements that can move but since any element in Silverlight can be moved by repositioning it, the definition still fits. In the Space Rocks game, the sprites will be the ship, asteroids, bullets, particles, and enemy ships.

These elements share some common needs including the following:

  • Movement based on velocity
  • Collision detection
  • Ability to “wrap” when hits edges of screen

The common behaviors of sprites for your game really depends on the game itself and so it’s difficult to create a general purpose sprite class that meets all of your needs. Generally when starting a new game I grab a sprite class I’ve done before that’s closest to what I need and then tweak it for the current game. Odds are that the sprite class we create for this game won’t do exactly what you need but it can be a good starting point to create your own.

I’ve tried a few different techniques for creating a sprite class, but the one I’ve settled on is to use a templated control. Templated controls are nice for sprites because it’s easy to inherit from a base class while still making the sprite look however you want. It’s also easy to edit these templates in Expression Blend to design your sprites.

Let’s create a Silverlight Templated Control called Sprite.cs.

image

When you create this, the class is generated as follows:

using System.Windows.Controls;

namespace SpaceRocks
{
    public class Sprite : Control
    {
        public Sprite()
        {
            this.DefaultStyleKey = typeof(Sprite);
        }
    }
}

The default style key is set to typeof(Sprite) and this corresponds to an entry in Themes/Generic.xaml. This entry looks like this:

<Style TargetType="local:Sprite">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Sprite">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

You can replace the contents of the ControlTemplate with whatever you want. Let’s just set a couple of properties on the Border so that we have a default sprite that can be displayed if we’re not inheriting it with a custom template.

<ControlTemplate TargetType="local:Sprite">
    <Border
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" Width="50" Height="50" Background="Red"/>
</ControlTemplate>

This will display a 50×50 red square.So let’s see how we can add this sprite to our game control. The game control currently had a Grid as its root element. We don’t really need the layout features of a Grid for this game, so we can change the root element to a Canvas. You can also remove the TextBlock we used in the last sample, and make sure to remove the code from the GameLoop_Update method too. This is our new Game.xaml:

<UserControl x:Class="SpaceRocks.Game"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Width="640" Height="480"
	xmlns:local="clr-namespace:SpaceRocks"
	xmlns:silverSprite="clr-namespace:SilverArcade.SilverSprite;assembly=SilverArcade.SilverSprite.Core">
    <UserControl.Resources>
        <silverSprite:GameLoop x:Key="gameLoop" Update="GameLoop_Update" />
    </UserControl.Resources>
    <Canvas x:Name="LayoutRoot" Background="Black" Width="640" Height="480">
    </Canvas>
</UserControl>

Now to add the sprite. You can add it in XAML, but many times in a game you want to have more control over when your sprites are displayed so let’s add it in code. In the Game constructor after the InitializeComponent() method we’ll create a sprite and add it to the canvas’ children:

using System;
using System.Windows.Controls;

namespace SpaceRocks
{
    public partial class Game : UserControl
    {
        public Game()
        {
            InitializeComponent();
            Sprite sprite = new Sprite();
            LayoutRoot.Children.Add(sprite);
        }

        private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
        {
        }
    }
}

And here is what it looks like when you run the game:

image 

 

Pretty cool huh? Ok so that’s not very exciting. Let’s see what we can do about positioning this sprite. For elements on a Canvas, you can use the Canvas.Left and Canvas.Top attached properties to position them. To avoid doing GetValue and SetValue all over the place and also to only set the attached properties if something changed, we can add an X and Y property to our sprite class which will set these for us.

using System.Windows.Controls;

namespace SpaceRocks
{
    public class Sprite : Control
    {
        double x, y;
        public Sprite()
        {
            this.DefaultStyleKey = typeof(Sprite);
        }

        public double X
        {
            get
            {
                return x;
            }
            set
            {
                if (x != value)
                {
                    x = value;
                    this.SetValue(Canvas.LeftProperty, x);
                }
            }
        }

        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                if (y != value)
                {
                    y = value;
                    this.SetValue(Canvas.TopProperty, y);
                }
            }
        }
    }
}

By storing off the x and y values we don’t need to call GetValue to get those properties if needed. Now if you add the following lines to the Game constructor:

sprite.X = 100;
sprite.Y = 50;

And run the game again you’ll see that the sprite is positioned according to our X and Y values.

image

Mar 08

Source code: http://www.bluerosegames.com/SpaceRocks/SpaceRocks_1_GameLoop.zip

Most games require a game loop which is simply a method that executes on a timer. This method can contain things like input handling, repositioning sprites, checking for collisions, or spawning particles. In Silverlight there are a few options for this, including using a zero duration Storyboard, a DispatcherTimer, or the CompositionTarget.Rendering event.

We’ll be using the SilverSprite core assembly for this project, you can learn more about it here:

http://blogs.silverarcade.com/silverlight-games-101/08/silverlight-silversprite-not-just-for-xna-games-any-more/

The SilverSprite core assembly contains a general purpose game loop you can use. This game loop uses the CompositionTarget.Rendering event. This event fires once per frame so it’s a good choice for a game loop.

It’s also useful to keep track of how long it’s been since the last time the game loop executed so that you can handle things like running at different frame rates. The SilverSprite game loop does this for you too. This will probably get even more important when Silverlight moves to other platforms like Windows Phone.

First let’s create a new Silverlight application and call it SpaceRocks. Take the defaults for creating a web application.

In order to use the SilverSprite core assembly we need at add a reference to the Silverlight project. The reference we need is to SilverArcade.SilverSprite.dll.

UPDATE: I had a typo in the name of the SilverSprite core assembly. The assembly we really need is SilverArcade.SilverSprite.Core.dll.

You can get this assembly from this link:

http://silversprite.codeplex.com/releases/view/41574

or you can get it from the source code included at the top of this post.

Next in the SpaceRocks project, add a new Silverlight User Control called Game.xaml. It’s a good idea to keep logic out of your MainPage.xaml and just use it as a container for other controls. Then in MainPage.xaml  we’ll add the Game control:

<UserControl x:Class="SpaceRocks.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
    xmlns:local="clr-namespace:SpaceRocks">
    <Grid x:Name="LayoutRoot">
        <local:Game VerticalAlignment="Top" HorizontalAlignment="Left"/>
    </Grid>
</UserControl>

Notice the xmlns:local attribute. This tells Silverlight to look in the SpaceRocks namespace to find any elements that start with the local: prefix. Then we add the Game control to the LayoutRoot Grid. In the  Game.xaml we can add our game loop object to the user control’s resources and while we’re in there we can set the width, height, and background color. We’ll also add a TextBlock to display something so that we can see the loop is executing.

<UserControl x:Class="SpaceRocks.Game"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Width="640" Height="480"
	xmlns:local="clr-namespace:SpaceRocks"
	xmlns:silverSprite="clr-namespace:SilverArcade.SilverSprite;assembly=SilverArcade.SilverSprite.Core">
    <UserControl.Resources>
        <silverSprite:GameLoop x:Key="gameLoop" Update="GameLoop_Update" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="Black">
        <TextBlock x:Name="text" Foreground="White"/>
    </Grid>
</UserControl>

Now for the Game control’s code behind file. In the code we’ll implement the GameLoop_Update event and put some code in to increment a number every time it executes and set the TextBlock’s text to that value.

using System;
using System.Windows.Controls;

namespace SpaceRocks
{
    public partial class Game : UserControl
    {
        int count = 0;
        public Game()
        {
            InitializeComponent();
        }

        private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
        {
            text.Text = count.ToString();
            count++;
        }
    }
}

Now if you run the program (we can’t really call it a game yet) you should see the number change as it gets incremented every time through the game loop.

image

We’ll do more interesting things with the game loop going forward, but this is a good starting point. If this works then we know that the SilverSprite core assembly has been referenced properly and that the game loop is firing once per frame.

Mar 08

The last time I started creating a sample game on this blog, I had to go through creating a game loop, handling keyboard input, dealing with vector mathematics, and a few other low level tasks. Along the way I created a helpers library which people could use to get started with their own games. A good amount of code from these samples made its way into SilverSprite, a free open source library that I created to make it easier to get XNA 2D games running in Silverlight. Because of my work on this library and other life changes such as writing a book and becoming an independent consultant and then finally ending up at Vertigo, this game development blog became almost non-existent. I’m looking to change that now.

Last night I released an Alpha 2 of the SilverSprite library for Silverlight 3.

One of the major changes is that I split out some of the core functionality that I thought would be useful to Silverlight game developers that didn’t need all of the XNA related graphics and content management stuff. This core assembly, named SilverArcade.SilverSprite.Core.dll is 69k, and in your XAP file it will compress down to under 29k. This isn’t a major size hit, and gives you the following:

  • An easy to use game loop class
  • Vector2, Vector3, and Matrix structures
  • MathHelper methods including linear interpolation helpers
  • A color tint pixel shader that can be applied to any element
  • Keyboard input helpers
  • Mouse input helpers

I will also be looking at moving some of the sound effect classes into the core going forward.

Along with this new assembly being available, I’ll be starting over on my Asteroids clone sample using this assembly and will cover its key features as we progress. I look forward to being able to focus on common game development tasks and letting the SilverSprite code assembly take care of a bit of the plumbing.

If you are already familiar with SilverSprite, one of the other major changes with this release is that we are now using the Microsoft.Xna namespaces to make it easier to get XNA code ported over. There are some great free libraries such as physics engines which can be useful for Silverlight games and these are now a whole lot easier to get working. SilverSprite is distributed under the MIT license and is free to use in binary form in any commercial or non-commercial project.

http://silversprite.codeplex.com

Jan 10

I get a huge kick out of other people using things that I’ve created and especially when they do things that I haven’t even imagined and take it to the next level. Adam Kinney posted about doing a torn photo effect with the image blitting methods that I contributed to the open source WriteableBitmapEx project on codeplex. For those not familiar with image blitting, it is when you copy a bitmap into another bitmap as fast as you can.

What’s especially cool about this post is that he was reproducing a tutorial previously done in Flash and it would have been much more difficult without these methods. Even more exciting is that Adam has contributed some extra blending modes that he needed back into the project so everyone can benefit from them. I took at look at the original Flash tutorial and it seems more complicated than the Silverlight version but I don’t know enough about Flash to have more than a general feeling about it.

Here is the final result of Adam’s sample:

torn

Pretty cool and it will take any image and do some random and dynamic effects to make it look torn and crumpled.

Adam’s original post is here: http://adamkinney.wordpress.com/2010/01/09/image-blitting-in-silverlight-with-writeablebitmapex/

preload preload preload