Page view counter

Silverlight Tips of the Day - Blog by Mike Snow

Game Programming with Silverlight

March 2009 - Posts

Silverlight Tip of the Day #103 – Use Integers for Layout Calculations

When calculating the positions of objects such as Images make certain to use integer values not floating point values.

For example, take a look at this code that centers a map around a given position:

private void CenterMap(double windowWidth, double windowHeight)
{
    if (null != _parentCanvas)
    {
        int leftPos = (int) ((windowWidth / 2) - _currentX);
        int topPos = (int) ((windowHeight / 2) - _currentY);
 
        _parentCanvas.SetValue(Canvas.LeftProperty, (double) leftPos);
        _parentCanvas.SetValue(Canvas.TopProperty, (double)topPos);
    }
}

Notice I converted the map layout position left and top to be integers. The following screen shot shows an example where double values were used instead of integers. The result is the images are slightly blurred and lines (or seams) appear between the image tiles.

image

Compare the screenshot above that used doubles with the shot below that used integers. In the screen shot below the images are crisp and the terrain tiles have no seams or lines.

image

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #102 - Bypassing the Image Cache

By default Silverlight will not download an image more than once if is contained within the image cache. That is, as long as the URI remains the same it will reference the image from the cache.

So what if the image changed on the server even though it has the same URI? Your application can force an update by setting the property IgnoreImageCache to true.

Example:

Image img = new Image();
Uri uri = new Uri("http://YourServer.com/MyImage.png", UriKind.Absolute);
BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage(uri);
bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
img.Source = bi;
LayoutRoot.Children.Add(img);

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #101 – Silverlight 3 Beta 1 Feature Summary

Unless you have had your head under a rock you probably have heard Silverlight 3 Beta 1 has been released! If you haven’t already, please install it from http://silverlight.net/getstarted/silverlight3/default.aspx

This release comes packed with some of the greatest features to date. If you are a game developer, you will be happy to hear the following features below are now included in Silverlight 3. I will be writing detailed blogs on a number of these to help you apply them to your application.

Image Opened

In Silverlight 2 it was difficult to accurately determine when a image was completely opened. This case was often needed to determine the actual dimensions of the image. The problem occurred because the DownloadProgress is fired at 100% before the image is fully decoded. The solve this, a new event called ImageOpened is available. Now you can be guaranteed to get the right size for the image. Example:

private void LoadImage(string fileName)
{
    Image img = new Image();
    Uri uri = new Uri(fileName, UriKind.Relative);
    img.Source = new System.Windows.Media.Imaging.BitmapImage(uri);
    img.ImageOpened += new EventHandler<RoutedEventArgs>(Image_ImageOpened);
}
 
void Image_ImageOpened(object sender, RoutedEventArgs e)
{
    Image img = (Image)sender;
    BitmapImage bi = (BitmapImage)img.Source;
    double width = bi.PixelWidth;
    double height = bi.PixelWidth != _radius)
}

XAP Compression

Optimization were made to drastically reduce the size of the XAP file. You can expect the XAP file size to now be on par (if not better) than Windows zipping. Games often come packed with a lot of content so obviously the smaller your XAP the faster your customers will be able to download your game.

Perspective 3D

Perspective 3D transforms can now be applied to Silverlight controls via the PlaneProjection property. This allows you to rotate a 2D control in a 3D plane.

image

Example code that shows how to do this:

<Image Source="Man.png">
    <Image.Projection>
        <PlaneProjection RotationX="45"></PlaneProjection>
    </Image.Projection>
</Image>

Pixel Shaders 

Pixel shaders allow you to apply effects to controls such as images. There are two built in effects available by default: Drop Shadow and Blur. In addition, you can write and apply your own custom effects.

The following images show the result of applying pixel shader effects to them.image

Example code to accomplish this through a built in shader:

<Image Source="dwarf.jpg">
    <Image.Effect>
        <BlurEffect></BlurEffect>
    </Image.Effect>
</Image>

Binding 

You can now bind controls to properties of each other. For example, the Text of a TextBlock can bind to the Text of a TextBox. Or, a TextBox Text can bind to the Value of Slider. Example:

<StackPanel>
    <TextBox x:Name="UserText"></TextBox>            
    <TextBlock Text="{Binding Text, ElementName=UserText}"></TextBlock>
</StackPanel>

Whatever someone types in the TextBox is automatically reflected in the TextBlock.

 

Bitmap API

Bitmap APIs are now available through a class called WriteableBitmap. This method takes as parameters the surface width and height and the pixel format.

Example code:

WriteableBitmap wb = new WriteableBitmap(0, 0, PixelFormats.Bgr32);
wb.Render(img, new ScaleTransform());
wb.Lock();
// walk through WriteableBitmap[]
wb.Invalidate();
wb.Unlock();

 

Hardware Acceleration

Silverlight now makes use of the GPU (Graphics Processing Unit) for rendering which frees up CPU time for other tasks. The GPU typically sits on a video card. It is a dedicated graphics processing device that is used for a variety of tasks such as calculating floating point operations.

Animated Text Performance Improvements

A property called TextRenderingMode now allows you specify RenderForAnimation. This turns off optimizations that could directly affect text animation such as scaling, rotating, etc. The result is a smother, more peformant animation of text. Example on how to set this property:

RenderOptions.SetTextRenderingMode(MyTextbox, TextRenderingMode.RenderForAnimation);

Network Monitoring API

There are now API’s that allow you to monitor the status of the network. To see if a network is available you can call:

bool isConnected = NetworkInterface.GetIsNetworkAvailable();

You can also hook up an event that will fire when the network status changes:

NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);

To access these methods you will need to reference the namespace System.Net.NetworkInformation;

SaveFileDialog

Finally we are able to save files in Silverlight! Calling this method will invoke a dialog that will allow you to specify a file to save to. The method returns a pointer to a Stream that you can than write to. Example code:

SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "map files (*.xml)|*.xml|All files (*.*)|*.*";
sfd.ShowDialog();
System.IO.Stream stream = sfd.OpenFile();
 
// Save your data here
 
stream.Flush();
stream.Close();

Make certain to flush and close the stream or the file will not be created.

CaretBrush

The CaretBrush is useful because you can now change the appearance of the caret. This was a problem if, for example, you wanted to have a background color of a textbox set to back. The cursor was also black so it would not appear.  Example on how to set it:

<TextBox Foreground="White" Background="Black" Width="200" Text="Hello">
    <TextBox.CaretBrush>
        <SolidColorBrush Color="White"></SolidColorBrush>
    </TextBox.CaretBrush>
</TextBox>

Resulting Screenshot (notice the white caret):

image

Local Connection

This feature allows two separate Silverlight applications to communicate with each other on the client side without the need to roundtrip to the server.

Implementing this is fairly straight forward. Start by creating two separate Silverlight applications. To one, add this code that will listen for a message:

LocalMessageReceiver receiver = new LocalMessageReceiver("R2D2");
receiver.MessageReceived += new EventHandler<MessageReceivedEventArgs>(receiver_MessageReceived);
receiver.Listen();

You will need to reference System.Windows.Messaging to make these calls. The constructor for LocalMessageReceiver takes any unique identifier.

To the other application add this code that will send a message to the first Silverlight application:

LocalMessageSender sender = new LocalMessageSender("R2D2");
sender.SendCompleted += new EventHandler<SendCompletedEventArgs>(sender_SendCompleted);
sender.SendAsync("Hello World!");

 

Navigation

Navigation is now supported in Silverlight. This allows you to do things like hook up navigation in your Silverlight application to the Back and Forward buttons of your browser. A new template called “Silverlight Navigation Application” is available that demonstrates how to do this.

Essentially to accomplish this you will need to put your main page in a <navigation:Frame>. You add history by this call:

this.Frame.Navigate(new Uri(currentPage, UriKind.Relative));

Then, when the back and forward buttons of your browse are clicked this frame object will intercept them and display the correct page.

System Colors

You can now get access to a users settings for their System Colors. These are available through System.Windows.SystemColors.*. Example: System.Windows.SystemColors.ActiveBorderColor. This will allow ou present a contrast that matches  a user's settings.

Other

  1. Out of Browser Experience – Allows you to run your Silverlight application as a desktop application.
  2. Assembly Caching – Enables non-core runtime extensions to be cached.
  3. ManagedResourceDictionary – Manage resources files in separate files.
  4. New controls – A number of new controls have been added.
  5. H.264 / AAC Media Playback – Newly supported Media format.
  6. Animation Easing Effects – Grants more visual effects including smoother transitions.
  7. Media Logging – Allows you to collect data about a customer and their meda experience. The data is posted back to one or many servers for analysis.

Thanks,

--Mike Snow

Silverlight Tip of the Day #100 – ComponentArt Controls

I recently had the opportunity to try out the controls from ComponentArt.com. I was very impressed with their ease of use, professional design and overall quality. Also, their staff are very prompt to responding to questions which made my developer experience a lot easier. Overall, they are very friendly and easy to work with.

ComponentArt currently has a Beta 2 release available here; I highly recommend you check it out!

The Silverlight controls they currently support include:

image

Let’s take a look at the Toolbar, Menu, Data Grid and Tree View controls.

Toolbar

The following screenshots shows you what the toolbar looks like in each of the available themes. These themes can be applied to all controls. For the toolbar, you can enable/disable items, change orientation from horizontal to vertical, and more. Also, you can have a seperate icon represented for enabled, disabled and hover.

Black Ice

image

Arctic White

image

Office 2003

image

Office 2007

image

Windows 7. 

 

image

Example code needed to create a toolbar:

<ComponentArt:ToolBar Width="600" x:Name="MainToolbar" Canvas.Left="250" ItemOrientation="Horizontal" >
    <ComponentArt:ToolBarItem Icon="Arrow.png" Click="ToolBarItemSelect_Click" ></ComponentArt:ToolBarItem>
    <ComponentArt:ToolBarItem Icon="Draw.png" Click="ToolBarItemDraw_Click" ></ComponentArt:ToolBarItem>
    <ComponentArt:ToolBarItem Icon="Dropper.png" Click="ToolBarItemDropper_Click" ></ComponentArt:ToolBarItem>
    <ComponentArt:ToolBarItem Icon="Fill.png" Click="ToolBarItemFill_Click" ></ComponentArt:ToolBarItem>
    <ComponentArt:ToolBarItem Icon="Erase.png" Click="ToolBarItemErase_Click" ></ComponentArt:ToolBarItem>
    <ComponentArt:ToolBarItem Icon="Grid.png" Click="ToolBarItemGrid_Click" ></ComponentArt:ToolBarItem>
</ComponentArt:ToolBar>

Menu

The following screenshot shows an example menu in action.

image

 

With menus you can change how they expand and collapse. You can make it so they instantly expand or you can send an interval for the rate of acceleration or deceleration. You can also set whether they expand when hovered or expand when clicked. There are a lot more settings that make the menu extremely customizable to your needs.

Example code needed to create a menu:

<ComponentArt:Menu ExpandDuration="0" ExpandTransition="None" Width="222" ExpandDelay="0" x:Name="MainMenu" MenuClick="MainMenu_MenuClick">
            <ComponentArt:MenuItem ItemLabel="File" >
                <ComponentArt:MenuItem x:Name="MenuItemNewMap"  ItemLabel="New Map..."/>
                <ComponentArt:MenuItem x:Name="MenuItemOpenMap" ItemLabel="Open Map..."/>
                <ComponentArt:MenuItem x:Name="MenuItemSaveMap" ItemLabel="Save Map..."/>
                <ComponentArt:MenuItem ItemLabel="Close"/>
            </ComponentArt:MenuItem>
            <ComponentArt:MenuItem ItemLabel="Layers">
                <ComponentArt:MenuItem x:Name="MenuItemLayer1" IsCheckable="True" IsChecked="True"   ItemLabel="Layer 1"/>
                <ComponentArt:MenuItem x:Name="MenuItemLayer2" IsCheckable="True" IsChecked="True"  ItemLabel="Layer 2"/>
                <ComponentArt:MenuItem x:Name="MenuItemGameObjefts" IsCheckable="True" IsChecked="True"  ItemLabel="Game Objects"/>
            </ComponentArt:MenuItem>
            <ComponentArt:MenuItem ItemLabel="Help">
                <ComponentArt:MenuItem ItemLabel="Search"/>
                <ComponentArt:MenuItem ItemLabel="Contents"/>
                <ComponentArt:MenuItem ItemLabel="Index"/>
            </ComponentArt:MenuItem>
        </ComponentArt:Menu>

Data Grid

The data grid is probably one of the more impressive controls. Columns can be resized and re-ordered. Check out the screen shot here:

image

You can also group rows by area:

image

 

 

 

 

 

TreeView

The following screen shot shows the tree view in action.

image

The tree view supports icons, drag/drop, node editing, tree view lines styles (none, solid, dotted), tree view line colors, multiple selection, enabling and disabling nodes and more.

Given a tree view control:

<ComponentArt:TreeView x:Name="TreeViewObjects"  Width="220" Height="300"></ComponentArt:TreeView>

The following snippet of code shows you how easy it is to add nodes to the tree:

public void CreateRootNode()
{
    TreeViewNode rootNode = new TreeViewNode();
    rootNode.Header = "Mailbox";
    TreeViewObjects.Items.Add(rootNode);
}

Any data you want to store with a node in the tree can be set in the TreeViewNode.Tag property.

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #99 – Silverlight 3 Game Programming Book
imageI would like to announce that I am currently working on a book titled “Silverlight Game Programming” due to be released around June this year! You can find it on Amazon by clicking here. image It’s taking most of my blogging time up so I apologize for the lack of blogs recently.

Based on Silverlight 3, this book walks you through how to create a multi-player online RPG in Silverlight. Included is a Map Editor written in Silverlight that allows you to create maps for your game.

Map Editor Features include:

  1. Object Templates – The base template for all objects that can appear in your game. These objects are stored in XML and include generic object properties such as name, description, image(s), animation properties and more.
  2. Advanced Object Placement- Draw, Drag/Drop, Fill, Delete, Undo, Redo.
  3. Object Editing – Objects added to the game can be fully customized by changing their properties. For example, a creatures strength, a potions potency, a weapons damage, etc.
  4. Collision Detection – Each object in the template can have a polygon that represents its collision zone.
  5. Animation – Preview your animated objects in the map editor.
    Triggers – Triggers cause events to fire when walked on. For example, triggers can activate traps, warp a player to another map, play a music file, etc.
  6. Terrain Editing – The Map Editor allows you to place tiles on different layers and it also allows you to apply opacity masks to these tiles for impressive tile transition effects.
  7. Undo/Redo – Undo or redo your last action.
  8. Map Generation – Create maps of any height and width. In addition, you can specify the radius of each tile.

Here is a screenshot of the Map Editor (in early development):

image

 

 

 

 

 

 

 

 

Let me know if you have any suggestions or comments about what you are hoping to see out of the book.

Thank you,

--Mike

Silverlight Tip of the Day #98 – Creating Sprites from 3D Models - EnvyGames

I recently stumbled across a cool tool by EnvyGames that allows you to generate sprites from 3D Models and their animation files. This tool, called SpriteWorks, is ideal for creating high quality sprite animations and one that I’ll be adding to my arsenal of game development tools for Silverlight. Since Silverlight does not yet support 3D models, sprite animation is really the only way to go.

On a side note, EnvyGames is also working on a Silverlight Game Engine. For a complete list of features visit this link: http://www.envygames.com/content/?page_id=327. A beta is due out in a number of weeks.

Once you have installed SpriteWorks make certain to have the following installed or the tool will not work:

  1. Microsoft Visual Studio 2008 or Microsoft Visual C# Express 2008.
  2. Microsoft XNA 3.0

SpriteWorks currently supports importing the following 3D file formats:

  • DirectX (.X)
  • Torque Game Engine (.DTS)
  • Autodesk (.FBX)

This tool is still undergoing improvements and fixes and I would recommend using it with Torque models for the best result.

I will now give a quick overview on how the tool works. Start by launching SpriteWorks, Click the Browse button and choose your 3D model. In the left pane a preview of the model will appear.

image

If your model doesn’t appear at first click the Camera tab and adjust the Camera Angles and Position until the model is centered in the preview window.

image

Next click the Model tab and open up your Animation Sequence file. You can click the Play button to preview the animation.

image

 

Finally, when you are ready click the Output tab. Enter the Output File Name, check the “Animate this model” checkbox and click the “Create Sprite Sheet” button.

image

The tool will start taking a snapshot of each animation frame.

image

The tool will go up to 52% and sit there for a minute or two before completing. Be patient here, the tool has not hung!

The result is a PNG file that has each sequence of the animation in it:

image

Thank you,
--Mike Snow

 Subscribe in a reader