Project Description
The Physics Helper for Blend, Silverlight and WPF contains several Behaviors and controls which allow you to draw objects in Expression Blend 3, and have those objects translated directly into Physics objects using the
Farseer Physics Engine. This can be a great timesaver for creating games, as it is traditionally difficult to line up underlying physics bodies and geometries with your Blend artwork.
New to Version 3 of the Physics Helper are Triggers and Behaviors which allow you to add joints, input and collision detection to your applications.
Intro Videos
Watch these short videos to see how easy it can be to design physics using Expression Blend 3, Silverlight 3, and the Physics Helper Behaviors:
VIDEO ON "THE BASICS" VIEWThis is an intro video on using the Behaviors to apply Physics in Expression Blend.
VIDEO ON "JOINTS + PROGRAMMING" VIEW A more advanced video on using Behaviors to create Joints and accessing objects via code-behind.
VIDEO ON "FLUID CONTAINER" VIEWA short video on using the Fluid Container Behavior to simulate water.
CODING4FUN SHOW VIEWBrian Peek interviews Andy Beaulieu on the Physics Helper. Note that this demos Version 1, which is based on the User Controls instead of Behaviors.
MIX09 SHOW OFF! VIEWThe Physics Helper Library took 1st Place at the 2009 MIX Show Off! Event. This is the winning video.
Demos
These demos were created with minimal or no coding using the Physics Helper Behaviors:
LAUNCH DEMOS
Notes
- run install.bat to copy the required assemblies into Blend's folder so that the Behaviors are available in the asset library
- remember to use Canvas layout containers, NOT Grid containers!
- when using Raster Images as Physics Objects, be sure that you have a Clean Outline. That is, make sure there are no stray pixels in the background - because the boundary detection algorithm must be able to "trace" the complete outline of the image.
- if your boundaries are not being determined correctly, it may be because of Rotate or Scale Transforms that you applied in Blend. To work around this issue, Group your element into a Canvas and then apply the Physics Behaviors to the Canvas instead of the shape. You can easily Group things into a Canvas in Blend by right-clicking the object and selecting Group Into/Canvas.
Coding Techniques
Behaviors are great, but it would be difficult to complete a full game using only behaviors. So at some point, you will need to add code to do AI, control levels and game state, and other tasks. To do this more advanced coding you will need to get access to the underlying Physics simulation and Physics bodies. Here are some pointers to get started with that:
Once you drop a PhysicsController Behavior onto your main Canvas, you can later get a reference to that Physics Controller (the object that contains the simulation context) in code. Suppose your main Canvas is named "LayoutRoot" then you can get a reference as follows:
PhysicsControllerMain _physicsController = LayoutRoot.GetValue(PhysicsControllerMain.PhysicsControllerProperty) as PhysicsControllerMain;
After you have a reference to the PhysicsController, you can modify any of the Farseer Physics Geometry or Body objects by getting a reference through the PhysicsObjects dictionary. You can also get a reference to the main Farseer Physics simulation to change things such as gravity (for details on the classes provided by the Farseer Physics Engine,
go here):
_physicsController.PhysicsObjects["ball"].GeometryObject.RestitutionCoefficient = 1.3F;
_physicsController.Simulator.Gravity = new Vector2(0, 500);
You can also handle events, such as the Collision event, raised by the PhysicsController when two physics geometries collide:
_physicsController.Collision += new PhysicsControllerMain.CollisionHandler(_physicsController_Collision);
void _physicsController_Collision(string sprite1, string sprite2)
{
if (sprite1 == "ship" && sprite2.StartsWith("asteroid"))
{
// blow up the ship
}
}
... and you can also get a reference to the oringal XAML UI Element using the uiElement property of the Physics Object:
Ellipse ball = _physicsController.PhysicsObjects["ball"].uiElement as Ellipse;
ball.Fill = new SolidColorBrush(Colors.Red);
Speeding up Boundary Detection
As you add more objects into the simulation, you will undoubtedly see a slow down in startup time. This is due to the algorithm which is detecting the boundaries of your UI elements (it is basically tracing a path around each object). To alleviate this delay, the Physics Helper echoes out a PointCache containing the calculated boundary points for each element. This cache is echoed out through the Output Window in Visual Studio (using Debug.Writeline statements) and will look similar to the following:
public static void ReadBoundaryCache(PhysicsController physicsController)
{
physicsController.PointListCollection = new System.Collections.Generic.List<PointObject>();
physicsController.PointListCollection.Add(new PointObject("cnvLeftArm", new List<Point> { new Point(94, 84) ... });
}
Simply copy this code into a class in your project and call it, passing in the Physics Controller:
BoundaryCache.ReadBoundaryCache(physicsController1);
The Physics Helper is currently in Beta and is still a work in progress. You can find out more at Andy Beaulieu's blog:
Here and
Here