Pirates Video

by Cameron Albert 11. March 2010 12:22

Here is a video of the Pirates game:

General Purpose Sprite Class

by Cameron Albert 10. March 2010 23:09

On the heels of some great posts by Bill Reiss on Sprites Part 1 and Sprites Part 2 in Silverlight I wanted to post some general base sprite classes that I use. The classes are intended to be used with the SilverSprite framework.

These classes all exist in an assembly I lovingly call the “Shady Engine” (to explain the namespaces)

The base class I used is ingeniously called Sprite. It implements an interface called ISprite. I added the interface in order to create an interface called IPlayer that the main Game class uses.

ISprite.cs

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

namespace Shady.Sprites
{
    public interface ISprite
    {
        ISprite Owner { get; set; }
        Vector2 Position { get; set; }
        double Rotation { get; set; }
        System.Windows.Point Scale { get; set; }
        double Width { get; set; }
        double Height { get; set; }
        Rect Bounds { get; }
        bool IsActive { get; set; }
    }
}

And here is the Sprite.cs file:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Xna.Framework;

namespace Shady.Sprites
{
    [TemplatePart(Name = PART_RootElement, Type = typeof(Canvas))]
    [TemplatePart(Name = PART_ContentElement, Type = typeof(ContentControl))]
    [TemplatePart(Name = PART_DebugCenter, Type = typeof(Ellipse))]
    [ContentProperty("Content")]
    public class Sprite : Control, ISprite
    {
        public const string PART_RootElement = "PART_RootElement";
        public const string PART_ContentElement = "PART_ContentElement";
        public const string PART_DebugCenter = "PART_DebugCenter";

        protected Canvas RootElement { get; set; }
        protected ContentControl ContentElement { get; set; }
        protected Ellipse DebugCenterElement { get; set; }

        protected TranslateTransform TranslateTransform { get; set; }
        protected RotateTransform RotateTransform { get; set; }
        protected ScaleTransform ScaleTransform { get; set; }

        protected double HalfWidth = 0;
        protected double HalfHeight = 0;

        public ISprite Owner { get; set; }    

        public object Content
        {
            get { return (object)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }
        public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(Sprite), new PropertyMetadata(null));

        public bool Debug
        {    
            get { return (bool)GetValue(DebugProperty); }
            set { SetValue(DebugProperty, value); }
        }
        public static readonly DependencyProperty DebugProperty = DependencyProperty.Register("Debug", typeof(bool), typeof(Sprite), new PropertyMetadata(false, new PropertyChangedCallback(Sprite.OnDebugPropertyChanged)));
        private static void OnDebugPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var sprite = obj as Sprite;
            if (sprite == null)
                return;

            if (sprite.DebugCenterElement != null)
                sprite.DebugCenterElement.Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed;
        }
            
        public Vector2 Position    
        {
            get 
            { 
                var x = (double)GetValue(Canvas.LeftProperty);
                var y = (double)GetValue(Canvas.TopProperty);
                return new Vector2((float)x, (float)y); 
            }
            set
            {
                SetValue(Canvas.LeftProperty, (double)value.X);
                SetValue(Canvas.TopProperty, (double)value.Y);
            }
        }

        public virtual double Rotation
        {
            get { return this.RotateTransform.Angle; }
            set { this.RotateTransform.Angle = value; }
        }

        public System.Windows.Point Scale
        {
            get { return new System.Windows.Point(this.ScaleTransform.ScaleX, this.ScaleTransform.ScaleY); }
            set
            {
                this.ScaleTransform.ScaleX = value.X;
                this.ScaleTransform.ScaleY = value.Y;
            }
        }

        public new double Width
        {
            get { return base.Width; }
            set
            {
                base.Width = value;
                HalfWidth = Width * 0.5;
                TranslateTransform.X = -HalfWidth;
                if (this.DebugCenterElement != null)
                    Canvas.SetLeft(this.DebugCenterElement, HalfWidth);
            }
        }

        public new double Height
        {
            get { return base.Height; }
            set
            {
                base.Height = value;
                HalfHeight = Height * 0.5;
                TranslateTransform.Y = -HalfHeight;
                if (this.DebugCenterElement != null)
                    Canvas.SetTop(this.DebugCenterElement, HalfHeight);
            }
        }

        public Rect Bounds
        {
            get
            {
                Vector2 position = this.Position;
                return new Rect(position.X - HalfWidth, position.Y - HalfHeight, this.Width, this.Height);
            }
        }

        private WriteableBitmap _bitmap;
        protected internal virtual WriteableBitmap Bitmap
        {
            get
            {
                if (_bitmap == null && this.ContentElement != null)
                {
                    var content = this.ContentElement.Content;
                    if (content != null && content is Image)
                    {
                        _bitmap = new WriteableBitmap((int)this.Width, (int)this.Height);
                        _bitmap.Render((content as Image), new TranslateTransform());
                        _bitmap.Invalidate();
                    }
                }
                return _bitmap;
            }
        }

        private bool _isActive = true;
        public bool IsActive
        {
            get { return _isActive; }
            set
            {
                _isActive = value;
                this.Visibility = _isActive ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public Sprite()
        {
            this.DefaultStyleKey = typeof(Sprite);

            this.TranslateTransform = new TranslateTransform();
            this.RotateTransform = new RotateTransform();
            this.ScaleTransform = new ScaleTransform();
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.RootElement = GetTemplateChild(PART_RootElement) as Canvas;
            this.ContentElement = GetTemplateChild(PART_ContentElement) as ContentControl;
            this.DebugCenterElement = GetTemplateChild(PART_DebugCenter) as Ellipse;

            if (DebugCenterElement != null && !Double.IsNaN(this.Width) && !Double.IsNaN(this.Height))
            {
                Canvas.SetLeft(DebugCenterElement, HalfWidth - 1.5);
                Canvas.SetTop(DebugCenterElement, HalfHeight - 1.5);
            }

            if (this.RootElement != null)
            {
                var group = new TransformGroup();
                group.Children.Add(TranslateTransform);
                group.Children.Add(RotateTransform);
                group.Children.Add(ScaleTransform);

                this.RootElement.RenderTransform = group;
                this.RootElement.RenderTransformOrigin = new System.Windows.Point(0, 0); // At 0,0 because the translate transform positions the sprite.
            }

            this.Initialize();
        }

        public virtual void Initialize()
        {
        }

        public virtual void Update(GameTime gameTime)
        {
        }

        public virtual void Draw(GameTime gameTime)
        {
        }

        /// <summary>
        /// Re-initializes the sprite.
        /// </summary>
        public virtual void Reset()
        {
            this.IsActive = true;
            this.Owner = null;
        }

        protected static void OnDependencyPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var sprite = obj as Sprite;
            if (sprite == null) return;
            sprite.Initialize();
        }
    }
}

Because Sprite is a templated control there is also some XAML to go along with it (You will need to place this in a themes/generic.xaml file):

<Style TargetType="sprites:Sprite">
        <Setter Property="Background" Value="{x:Null}"></Setter>
        <Setter Property="Foreground" Value="{x:Null}"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="sprites:Sprite">
                    <Canvas x:Name="PART_RootElement" Background="{TemplateBinding Background}">
                        <ContentControl x:Name="PART_ContentElement"/>
                        <Ellipse x:Name="PART_DebugCenter" Width="3" Height="3" Fill="Red" Visibility="Collapsed"/>
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

That is my basic Sprite class, I will post my animated sprite class next.

Tags: , , , ,

Silverlight Games | Silverlight | Game Development | General

Yar, I do be re-visiting Pirates!

by Cameron Albert 10. March 2010 13:03

One of the first games I started building in Silverlight I called Pirates! Since working on Perenthia and various other tasks I have not re-visited the game for a long time. I really would like to get this game finished so I have to decided to spend some time working on it. I hope to include some videos soon that show the game in varied stages of development. The first screen shot displays what currently exists after implementing some path finding and the SilverSprite library:

Here is the post from the game blog: Pirates Game in Silverlight

XNA and Silverlight Development

by Cameron Albert 1. February 2010 13:57

Mad Laumann has a new post up about the development progress of his game Little Longhorn, a tower defense game written for XNA and Silverlight using the SilverSprite framework. I have been following his progress with the game and have been able to play the early versions of it (both XNA and Silverlight) and have found it quite fun and challenging. The game has grown quite a bit over the last few months with game play and graphics improving all the time. Needless to say Mads is becoming an authority on XNA/Silverlight combination platform development so be sure to check out his blog A Silverlight Playground.

Tags: , , ,

Game Development | General | Silverlight | Silverlight Games

Silverlight 4 Business Application Development – Beginner’s Guide

by Cameron Albert 18. January 2010 19:47

For those of you out there wanting to get into Silverlight development but just do not know where to start, Frank LaVigne and I have just about completed our book titled Microsoft Silverlight 4 Business Application Development – Beginner’s Guide(link to pre-order). This book will be ideal for current Windows or ASP.NET developers who want to learn Silverlight and because the book is centered on Business Application Development we will empower you with knowledge so you can recommend Silverlight for the next business project at your company.

Gaining the basics required to develop in Silverlight, make use of data binding, WCF and RIA Services you will be prepared to lead the Silverlight charge at your company. Be warned, once you start developing in Silverlight you will have a hard time going back to normal ASP.NET development.

Tags:

General | Silverlight | Silverlight Business Development

Powered by BlogEngine.NET 1.5.0.7
Modified Theme by Mads Kristensen

About the Author

CameronAlbert.com I am Senior Software Development Consultant specializing in Silverlight, WPF and the Microsoft .NET Framework. 

My current project Perenthia is a Silverlight multi-player game based in a fantasy world that combines text adventure games with some moderate graphics

View Cameron Albert's profile on LinkedIn
See how we're connected

Follow cameronalbert on Twitter

 

Recommended Books

Silverlight 4 Business Application Development - Beginner's Guide:

http://www.packtpub.com/microsoft-silverlight-4-business-application-development-beginners-guide/book

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide