Hi,

Today is September 29 - 2008 and I am writing this short post (though big, but short for writing anything over Farseer/SL) to give an idea about one of the immense possibilities with Silverlight - Game Development. I will focus on simplicity to target the beginners and specifically cover possibilities with Farseer Engine. The Farseer Physics Engine is an easy to use 2D physics engine designed for Microsoft’s XNA and Silverlight platforms.

I do not know why it is named Farseer but possibly because it refers to followers of Eldar; one of the most ancient and advanced races in the universe's history. Their armies usually have the advantages of speed and technology. Possibly Jeff Weber can tell.

Physics Engine:

There are several games that simulates their motion like a real world entity. For example, if you have used Windows Live SkyDrive, while uploading a file, you are presented with a screen having a Baal. You can push this ball and it collides with walls, bounces back pretty much the same way as if it was a real ball. The ball has all the properties of a real world - it always feels a gravitational pull downwards, on experiencing a force i would follow a parabolic path similar to a real world ball. Now, no one has written the logic on how a ball should move when hit. such simulation is done by associating certain features to the ball (like mass, friction etc.), rest all is handled by the underlying Physics Engine. Physics based games are more quality games and closer to real world experience and form a different group of games altogether.

In short statement, any piece of logic that could provide simulation of Newtonian Physics is a physics engine. It doesn't necessarily has to be a game engine, though the most common application is game industry, it is also used in various other fields such as research, advertisements etc. Primarily there are two kinds of Physics Engines - "Real Time" and "High Precision". Both the engines aim to simulate the laws of physics (like friction, moment of inertia, force, gravity (which is again a force) etc.) but since there is less availability of computation over most of the end users machines, "Real Time" engines eat up some of the details and simulate the bare minimum required to provide a real world feeling. On the other hand, "high precision" engines take into account of almost all the factors that exist in our world like air speed etc. and are commonly used in scientific projects like defence, space etc. and are run over high end machines like super computers.

most of the machines out there depend entirely on CPU alone for most of the computational needs. In areas where high graphics intensive tasks are required, we can install specialized GPU (Graphics Processing Units)- we also know them by common name - graphics card. Similarly, in high end applications which use Physics Engines, we can also install PPU (Physics Processing Unit) for shedding off the load from CPU giving a better performance.

In case of Farseer, it is not an easy task to write a Physics Engine for browser based scenarios since you have to think 100 times before planning for using resources. Physics based calculations cannot be done easily when the machines are poor. That is the reason why you might find some glitches in terms of performance on the physics games over Silverlight and Farseer will improve continually over time - sometimes to cope up with new releases of Silverlight, at other time to add new demanded features and performance restrictions. Hats off to the people out there who are contributing to the developer community by creating such product. Now I can start my post after paying respect to those great people.

Silverlight as gaming platform:

Games have few components. Let us examine these and see what Silverlight has to offer w.r.t. these requirements.

1. A nice light and programmable UI - Silverlight supports these features through various concepts like Path, Vector shapes etc. and most importantly, they are based on XAML so you can talk to your graphics during runtime which you might not be able to do with a normal graphics (like jpeg etc.).

2. A way to provide simulation to the UI elements - Silverlight supports these through various subtle concepts like animations. More importantly, since we can work in C# we can use all the good features and usability of the same. You don't have to learn any new tool/language.

3. A way to interact with end user in sufficient real time fashion - Silverlight makes this possible through its optimised CLR (called AgCLR; and do you know that CLR of SL is almost same as that of a the .NET Framework). Also adding to the fact that entire processing will be done at client side, we can expect SL based games to be sufficiently real time. And if you don't see it, probably its time to upgrade the machine.

4. Game Logic - Now don't expect SL to write game logic, otherwise it would have been a Product rather than a Platform.

5. Game Engine - Game engine is kind of another framework sitting on top of the underlying framework and it exposes functionality to your game to ease the development effort. It is similar to the fact that .NET APIs, provides a framework where we build other applications on top of them. However it has to be noticed that a game engine is not something that is generic. One game engine works only with a particular genere of games. It is similar to the concept of Software Factories which could be applied to a specific kind of applications only. Silverlight doesn't provide any. You have to write your own (if required) or depend on others available engines in market.

6. Generalized Game Engines - Physics engine is a good candidate to fit in this scenario. These engines help us to add certain features rather acting as a specific game engine. For example, Silverlight doesn't provide any API to simulate Physics, so we have to Physics Engines to add those features to our games/apps. Another example could be 3D rendering engine. Again, Silverlight doesn't support natively any 3D based APIs, so we have to take help of 3D rendering engines like Kit3D. By using Kit3D, we can develop 3D games over Silverlight. Combining Kit3D with Farseer could give us 3D, physics based games on Silverlight. Kit3D is my next topic of interest that I will take up.

Exploring Farseer:

I will not go into details of Silverlight/any other details and assume that people reading from here onwards have sufficient knowledge about concepts like Silverlight, Storyboards in Silverlight, C# etc. instead, we will straight away look at some common capabilities of Farseer engine to get started since there are lots of material over SL but very few on Farseer.

Out of the many capabilities of Farseer, I would explain only few capabilities like, PhysicsSimulator class, movement using "Body" class, Collision using "Geom" class. Apart from this I will also cover on how to achieve a Game Loop using Storyboards (although a better method exist in RC0 onwards of SL which is using CompositionTarget) and an organized way to Handling Keyboard Inputs. First we will discuss three classes and then we will move towards Logic of how to apply them.

PhysicsSimulator Class:

This is the main class that developer calls to apply the Physics he wants to apply. Physics Simulator class does many things but for now I could say that you can use it to specify Gravity to the world. It takes values through which you could specify how much gravity any object should experience in X/Y direction. Let's say we have Gravity of 5000 on Y direction and the scene is to represent a constant air flow in X direction, we can apply 100 units of force in X direction. So that ways whenever you will simulate any object, apart from the forces that you have applied, this gravitation and Air will also be applied. This can be specified in its constructor similar to this: PhysicsSimulator physicsSimulator = new PhysicsSimulator(new Vector2(0, 5000));

Movement (Body Class):

Body class is the central class that applies different Physics concepts like Force, torque, etc. It doesn't have any UI. We tie the Body object to a specific XAML object (or sprite) by writing a code which makes changes to different properties of the XAML code based on changes in the Body object. So, for example, if we want to give a physics motion to a rectangle XAML element, we will create a rectangle Body object and write code (lets say a method called Update) whose main job will be to keep the properties of Body object in sync with properties of Rectangle (like Canvas.Left etc.). So the concept is: Farseer world never does any changes directly to XAML (neither body object nor PhysicsSimulator). Physics Simulator only simulates the body object, it is we who make changes to the actual sprite based on the changes that Physics Simulator has done to body. So, Physics simulator will move the Body object according to the laws of physics and our code will merely keep our sprite in sync with Body object. This is important because now we can decide which properties to change based on the changes in Body object and not necessarily tied upon the Farseer Engines default functionality.

This feature essentially provides a loose coupling between the Engine and application making it reusable in different ways. Jeff could have written logic to change specific properties depending on the type of object in question. But then, we would have problems like:

  • It would have been impossible to use Farseer with the newly added classes/objects/third party XAMLs etc.
  • It would have become more time consuming for Jeff to build Farseer and also the engine could have become more heavy (which is a No Go for SL based applications). there are endless list of problems that could have got associated but thanks to Farseer designers for making it very generic and usable in different scenarios.

Collision (Geom Class):

We enrich a body further by providing it a geometry.

Collision is achieved through Geom (or Geometry) class. I don't know why Farseer implementers changed its name from Geometry to Geom so I will use this name interchangeably. Geom class is responsible to decide how a body should react when someone comes in its path. There are several factors in Physics which decide the result of collision. Like Friction (if its not a head on collision), Coefficient of Restitution etc. which we can set and then associate it with a Body.

In its creation process(basically using factory pattern) itself, we can specify the Physics Simulator to be used and the Body on which it has to act. You don't have to write any logic to handle collision. Based on the properties set to the Geometry of a Body, Physics simulator decides what should happen to other bodies 9which should also be controlled by the Physics Simulator) when they collide. The collision result will be calculated automatically. As said earlier, we have to keep our sprite in sync with Body object in the game loop since Body is the central place where Physics Simulator keeps its end result of any computation. We will see this shortly in a code segment. I will try to upload the code as soon as I finish this post but I might get busy so, if someone needs code sample for the explained concepts, please feel free to contact me by clicking on the email link on my home page of blog/share email via a comment (though that will be visible to everyone).

Game loop:

Game Loop is something that keep things going. It is kind of a timer mechanism. faster the game loop, the more real time the end user experience will be but at same time, a fast game loop will consume more memory (and sometimes its unnecessary). You have to decide the game loop frequency on your personal need basis.

In Silverlight, you could achieve the effect of time through DispatcherTimer but that is not a recommended approach, so people usually go for Empty Storyboard approach. But with release of Silverlight 2 RC, we have a better approach. Though I will show here the empty storyboard mechanism.

In empty storyboard approach, we create a storyboard in the code, set its duration, associate a event handler for completion and begin the storyboard. The code looks similar to below.

void GameLoop()
        {
            timer = new Storyboard();
            timer.Duration = TimeSpan.FromMilliseconds(15);
            timer.Completed += new EventHandler(timer_Completed);
            timer.Begin();
        }

When storyboard completes, it reached its completed event handler as show below and there we do all that we want to do with the game and at the end re-begin the storyboard.

void timer_Completed(object sender, EventArgs e)
        {
            //Write all logic that you need to execute every 15 milliseconds (in this case).

            timer.Begin();
        }

Simple!

Handling Keyboard:

Keyboard inputs can be handled directly by handling key down, key up events of the Canvas of our XAML. But it is not advised to handle it that way (you will do it if you want a real real realtime response). I am telling this because SL based applications has to be least resource intensive so it is good to share good practice. otherwise you could ignore this section and write canvas event handlers manually.

In a more optimised approach, we handle key inputs of canvas, and instead of responding to it directly, store the key stroke details in a shared array. When game loops itself (maybe 15 milliseconds in this case) we will simply fetch the key press activities from the array and react to it. this will allow us to move at our own pace rather than getting things hanged/behave abnormally because of an impatient end user hitting arrow keys more like a madman. Attached is a class file that is used to wrap this logic in the form of a class. the class file is present in the getting started samples of Farseer available from Codeplex web site. So, instead of reinventing the wheel, I am representing it as is. see the attached KeyHandler.zip file which has classes associated with it.

Farseer Sample Logic:

Okay, so enough of theories, here is one logic that you can apply to create a simple rectangle and circle and then apply motion to it along with handling collisions.

You need the sprites. In our case these would be XAML files for rectangle and circle having associated code behind files. The code behind files would contain nothing else than an object of type Body and a public function called Update (remember? This is the function which will keep different properties of rectangle/circle in sync with the contained Body object). here is a sample XAML and code behind class structure:

Rectangle XAML and Code Behind:

<UserControl x:Class="PhysicsSLGettingStarted.MyRectangle"
    xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
               <Canvas IsHitTestVisible="False">
                <Rectangle x:Name="rectangle" Fill="Yellow" Stroke="Black" StrokeThickness="2" Canvas.Left="0" Canvas.Top="0">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <RotateTransform x:Name="rotateTransform" Angle="0"/>
                            <TranslateTransform x:Name="translateTransform" X="0" Y="0"/>
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Canvas>

</UserControl>

public partial class MyRectangle : UserControl
    {
        //We could have implemented like a property but for simplicity I am not making it very complex.
        //This is the RectangleBody object that is changed by Physics simulator.
        //Our update method syncs the coordinates of rectangle with properties of this RectangleBody
        public Body RectangleBody;
        float x, y, rotation;

        public MyRectangle()
        {
            InitializeComponent();

        }

        //Exposing size as a property so that size of rectangle can be set from external code
        public Vector2 Size
        {
            set
            {
                //Vector class is just a structure of packaging things. Its upto us to use it the way we like

                //We are seeting the width and height of rectangle and the user control
                //equal to the value supplied by external code
                this.Width = value.X;
                rectangle.Width = this.Width;
                this.Height = value.Y;
                rectangle.Height = this.Height;

                //Required to match the coordinate systems
                translateTransform.X = -this.Width / 2;
                translateTransform.Y = -this.Height / 2;
                rotateTransform.CenterX = this.Width / 2;
                rotateTransform.CenterY = this.Height / 2;
            }
            get
            {
                return new Vector2((float)this.Width, (float)this.Height);
            }
        }

        //Method that keeps properties of the rectangle in sync with the RectangleBody properties
        //Look how we are simply mapping the properties of Canvas with body properties
        public void Update()
        {
            if (RectangleBody == null) return;

            if (x != RectangleBody.Position.X)
            {
                x = RectangleBody.Position.X;
                this.SetValue(Canvas.LeftProperty, Convert.ToDouble(x));
            }

            if (y != RectangleBody.Position.Y)
            {
                y = RectangleBody.Position.Y;
                this.SetValue(Canvas.TopProperty, Convert.ToDouble(y));
            }

            if (RectangleBody.Rotation != rotation)
            {
                rotation = RectangleBody.Rotation;
                rotateTransform.Angle = (rotation * 360) / (2 * Math.PI);
            }
        }
    }

Circle XAML and Code Behind:

XAML and code behind of circle is almost similar to rectangle above. Please see the attached code for details.

Main Page Code Behind (Page.xaml.cs)

Important details added:

public partial class Page : UserControl
    {
        PhysicsSimulator physicsSimulator;
        MyRectangle rect;
        Body rectBody;
        Geom rectGeom;
        Body circleBody;
        MyCircle circle;
        Geom circleGeom;

        Storyboard timer;
        Vector2 force;

        public Page()
        {
            InitializeComponent();
            //Create Physics Simulator
            physicsSimulator = new PhysicsSimulator(new Vector2(0, 5000));
            //Create Body. Note the constructor uses physics simulator
            rectBody = BodyFactory.Instance.CreateRectangleBody(physicsSimulator, 128, 128, 1);

            //Rectangle will not move
            rectBody.IsStatic = true;
            circleBody = BodyFactory.Instance.CreateCircleBody(physicsSimulator, 64, 1);//fix

            //Create Geometry and set different physics factors
            rectGeom = GeomFactory.Instance.CreateRectangleGeom(physicsSimulator, rectBody, (float)this.Width, (float)this.Height / 5);
            rectGeom.RestitutionCoefficient = .5f;
            rectGeom.FrictionCoefficient = .2f;
            circleGeom = GeomFactory.Instance.CreateCircleGeom(physicsSimulator, circleBody, 64, 20);
            circleGeom.RestitutionCoefficient = .5f;
            circleGeom.FrictionCoefficient = .2f;

            //Add these bodies to canvas
            AddtoCanvas();

            //Attach the bodies to physics simulator so that they can be managed by it.
            physicsSimulator.Add(rect.RectangleBody);
            physicsSimulator.Add(circle.CircleBody);

            //Call their update method once during load tiem so that their initial position and size are set
            circle.Update();
            rect.Update();
        }

         //This method adds the XAML (sprites) to the main page's XAML
        void AddtoCanvas()
        {
            //Create a rectangle sprite and give it a body, initial size etc.
            rect = new MyRectangle();
            rect.RectangleBody = rectBody;
            rect.RectangleBody.Position = new Vector2((float)this.Width / 2 + 400, (float)this.Height / 2 + 200);
            rect.Size = new Vector2((float)this.Width, (float)this.Height / 5);
            //Create a circle sprite and give it a body, size, position etc.
            circle = new MyCircle();
            circle.Radius = 60;
            circle.CircleBody = circleBody;
            circle.CircleBody.Position = new Vector2((float)this.Width / 2 +500, (float)this.Height / 2 - 100);
            //Add these sprites to main canvas
            this.LayoutRoot.Children.Add(circle);
            this.LayoutRoot.Children.Add(rect);

        }

        void GameLoop()
        {
            timer = new Storyboard();
            timer.Duration = TimeSpan.FromMilliseconds(15);
            timer.Completed += new EventHandler(timer_Completed);
            timer.Begin();
        }
        void timer_Completed(object sender, EventArgs e)
        {
            Button_Click(null, null);
            timer.Begin();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Apply force
            force = Vector2.Zero;
            force.Y = -force.Y;
            force += new Vector2(0, 5000);
            //apply force in y direction
            circle.CircleBody.ApplyForce(force);
            //Rotate the ball so that it falls down
            circle.CircleBody.ApplyTorque(-5000);
           //update simulation
            physicsSimulator.Update(0.005f);
            //update the effect of physics simulator by calling update methods of sprites
            rect.Update();
            circle.Update();
            //Start the game loop
            GameLoop();
        }
    }

Please see the attached code for more details.

I hope this would give you a quick start for moving ahead with Physics based animations and Games.

If you are an ISV and want our team to be engaged for training/development projects, please feel free to connect with me here.

Happy Gaming!

Rahul Gangwar