Page view counter

Silverlight Tips of the Day - Blog by Mike Snow

Game Programming with Silverlight

April 2008 - Posts

Silverlight Tip of the Day #7: Creating Transparent PNG files for Silverlight

With GIF's, which aren’t supported in Silverlight2, transparency is fairly easy because you can just specify what color in that GIF you want to be your transparent color. With PNG's, it's a little tougher. You will need to use an editing tool to go in and "clear" out the sections of the bitmap that you do not want displayed. There are tools that do this; and I will walk you through one such scenario.

Step 1. Find a image editing tool that supports PNG file format and a feature like the "Magic Wand" that is used to clear selected areas. Open the image you want to edit in that tool. For our example, we will use this cute little attacking mage as seen in Figure 7.1.

attack e0005
Figure 7.1 Attacking Mage

Step 2. Click the "magic wand" image button on the toolbar. If you are using a tool like Photoshop, first duplicate the layer and delete the original background layer. This way the background you clear away is transparent and not white. If available, set the Tolerance level = 0 so that it only grabs the brown color. Also, if available, turn off Anti-Alias.

Step 3. Left click on the brown surface as seen in Figure 7.2 (plus left shift click to grab the brown piece under his cloak) and you will see that everything in brown is selected.

image 
Figure 7.2 Image Boundaries Selected

Step 4. Hit the delete key. The result is the background is now erased as seen in Figure 7.3.

image
Figure 7.3 Background Erased.

Step 5. Save the file as a PNG file. This image will now render in Silverlight as transparent through the spaces that you cut out of the image. Below is an example on how to load and display and PNG image. We call our routine LoadImage() and than add the image resource to a Canvas control I have named MapCanvas.

public void DisplayPNG()
{
    Image img = LoadImage("images/mage.png");
    MapCanvas.Children.Add(img);
}
 
public Image LoadImage(string resource)
{
    Image img = new Image();
    Uri uri = new Uri(resource, UriKind.Relative);
    ImageSource imgSrc = new System.Windows.Media.Imaging.BitmapImage(uri);
    img.SetValue(Image.SourceProperty, imgSrc);
    return img;
}

Credits: Thanks to the site http://reinerstileset.4players.de/ (Reiner "Tiles" Prokein) for these images.

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #6: Monitoring for Keyboard and Mouse Events.

Silverlight 2 provides full support for keyboard and mouse event handling. Not only can you monitor events for the entire application but you can also monitor them at the individual control level.

The following is an example of how to monitor all the keyboard and mouse events available at the application level:

Page.xaml.cs:

namespace SilverlightApplication
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
 
            this.KeyDown                += new KeyEventHandler(Page_KeyDown);
            this.KeyUp                  += new KeyEventHandler(Page_KeyUp);
            this.MouseEnter             += new MouseEventHandler(Page_MouseEnter);
            this.MouseLeave             += new MouseEventHandler(Page_MouseLeave);
            this.MouseLeftButtonDown    += new MouseButtonEventHandler(Page_MouseLeftButtonDown);
            this.MouseLeftButtonUp      += new MouseButtonEventHandler(Page_MouseLeftButtonUp);
            this.MouseMove              += new MouseEventHandler(Page_MouseMove);
        }
 
        void Page_KeyDown(object sender, KeyEventArgs e)
        {
        }
 
        void Page_KeyUp(object sender, KeyEventArgs e)
        {
        }
 
        void Page_MouseEnter(object sender, MouseEventArgs e)
        {
        }
 
        void Page_MouseLeave(object sender, MouseEventArgs e)
        {
        }
 
        void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
        }
 
        void Page_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
        }
 
        void Page_MouseMove(object sender, MouseEventArgs e)
        {
        }
    }
}

To monitor at the control level you can add an event handler directly to the control in the XAML. In the example below, we have added a mouse left down and mouse left up button event handler to a <Textblock> control.

Page.xaml:

<UserControl x:Class="SilverlightApplication6.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock x:Name="FPS" MouseLeftButtonDown="FPS_MouseLeftButtonDown" 
                   MouseLeftButtonUp="FPS_MouseLeftButtonUp">Hello there</TextBlock>
    </Grid>
</UserControl>

Page.xaml.cs:

namespace SilverlightApplication
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }
 
        private void FPS_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FPS.Text = "Mouse button down";
        }
 
        private void FPS_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            FPS.Text = "Mouse button up";
        }
    }
}

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #5: Timers and the Main Game Loop

Main Game Loop

The main game loop is the heart of your game. In this function you will execute the majority of your game related tasks including:

  • Game AI
  • Animations - Updating objects and their positions.
  • Etc...

In this tip I will be demonstrating how to setup the main game loop using the DispatcherTimer. Alternate methods you should look into for your main game loop include:

  1. StoryboardTimer – See Tip of the Day #16
  2. CompositionTarget.Rendering -  See Tip of the Day #50.

My preferred method is using the CompositionTarget.Rendering event as the event is fired before the rendering of each frame.

Couple notes about DispatcherTimer:

  1. You will need to add a using statement: using System.Windows.Threading;
  2. If you set the timer interval to TimeSpan.Zero it will put the rate to be in sync with your monitors refresh rate.

Now, let’s take a look at the code. In the demo below we are simply displaying the number of frames per second our browser is rendering.

Page.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
 
namespace SilverlightApplication6
{
    public partial class Page : UserControl
    {
        private DispatcherTimer _gameLoopTimer;
        private int _fps = 0; 
        private DateTime _lastFPS = DateTime.Now;
 
        public Page()
        {
            _gameLoopTimer = new DispatcherTimer();
            _gameLoopTimer.Interval = TimeSpan.Zero;
            _gameLoopTimer.Tick += new EventHandler(MainGameLoop); 
            _gameLoopTimer.Start();
 
            InitializeComponent();
        }
        void MainGameLoop(object sender, EventArgs e)
        {
            _fps++; 
            if ((DateTime.Now - _lastFPS).Seconds >= 1) 
            { 
                FPS.Text = _fps.ToString() + " FPS"; 
                _fps = 0; 
                _lastFPS = DateTime.Now; 
            }
        }
    }
}

Page.xaml:

<UserControl x:Class="SilverlightApplication6.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock x:Name="FPS">Current FPS</TextBlock>
    </Grid>
</UserControl>

Thank you,
--Mike Snow

 Subscribe in a reader