SpriteHand
Module Border
  Most recent blog entries
Module Border
Adding Behaviors Programmatically
Andy's Blog By Andy Beaulieu on 8/23/2009 7:31 AM

Expression Blend 3 has great design-time support for Behaviors – you can simply drag Behaviors from the Asset Library onto the Artboard (or Objects + Timeline Window), and the Behaviors are applied to an element. But what if you want to add Behaviors through code at runtime? We can do this by using the BehaviorCollection and GetBehaviors method in the System.Windows.Interactivity Namespace…

using System.Windows.Interactivity;


{…}

BehaviorCollection
behaviorCollection = Interaction.GetBehaviors(box);
behaviorCollection.Add(new MouseDragElementBehavior());

Adding Physics Behaviors Programmatically

In a previous blog post, I had a question about adding Behaviors at runtime for the Physics Helper Behaviors. These behaviors are a little different in that they are dependent on a PhysicsControllerBehavior as kind of a “master controller.” There are also dependencies for some of the other Behaviors – for example a PhysicsJointBehavior depends on the existence of a PhysicsObjectBehavior for the bodies it is joining. So there is an additional call necessary for some of the Physics Behaviors (this may be fixed in a future release).

Here is a code example. Suppose you have a Rectangle named “ground” that you want to make a Static Physics Object (one that stays in place, like some ground), and an Ellipse named “ball” that you want to make a physics object.

PhysicsControllerMain _physicsController = LayoutRoot.GetValue(PhysicsControllerMain.PhysicsControllerProperty) as PhysicsControllerMain;

 

// add physics behavior to an ellipse named "ball"

behaviorCollection = Interaction.GetBehaviors(ball);

behaviorCollection.Add(new PhysicsObjectBehavior());

_physicsController.AddPhysicsBody(ball.GetValue(PhysicsObjectMain.PhysicsObjectProperty) as PhysicsObjectMain);

 

// add static body behavior to a rectangle named ground

PhysicsObjectBehavior behPhysObj = new PhysicsObjectBehavior();

behPhysObj.IsStatic = true;

behaviorCollection = Interaction.GetBehaviors(ground);

behaviorCollection.Add(behPhysObj);

_physicsController.AddPhysicsBody(ground.GetValue(PhysicsObjectMain.PhysicsObjectProperty) as PhysicsObjectMain);


The key is the additional AddPhysicsBody call, which informs the PhysicsController that a new object should be added to the simulation.

Adding User Controls Programmatically

Most of the time, you will want to define Joints and other Physics Behaviors inside separate User Controls. This will help keep your assets in manageable parts. You can still add these user controls dynamically through code, and there is an example of this in the Physics Helper download (DemoBehaviors2, which dynamically adds a RagDoll):

// add a user control, then apply physics

ucRagDoll ragdoll = new ucRagDoll();

LayoutRoot.Children.Add(ragdoll);

_physicsController.AddPhysicsBodyForCanvasWithBehaviors(ragdoll.LayoutRoot);


Keep in mind that the Physics Helper caches any Boundaries that it detects (that is, the outline of your Physics Elements). This is because it is an expensive operation to trace the outline of each element. So you should try to have one instance of your Physics Objects on screen at startup so that subsequent instances are added quickly.

More Info on Physics Helper

Physics Helper on Codeplex


Farseer Physics on Codeplex

Physics Helper 3: Now with WPF Support

Coming Soon:Fluid Container Behavior

Comments (6)

Coming Soon: Fluid Container Behavior!
Andy's Blog By Andy Beaulieu on 8/20/2009 2:22 PM
Have you figured out that Behaviors are the greatest thing since sliced bread? You WILL... only a matter of time :) I'm still having fun in my spare time adding to the Physics Helper Behaviors, and coming soon to the library is a Fluid Container Behavior, which can be used to simulate water and waves. I threw this water/ragdoll test together using the new behavior (oh, and no code!):




MUCH of the credit for the Fluid Container goes to Jeff Weber - besides being the creator of the Farseer Physics Engine, he also published an inspiring Water Physics Demo. And he was nice enough to publish the source code as well! So it took about 60 minutes to wrap Jeff's sample code into a Behavior. THANK YOU JEFF!

Comments (7)

Physics Helper 3: Now with WPF Support!
Andy's Blog By Andy Beaulieu on 8/17/2009 1:34 PM
Several people have asked if the Physics Helper Library for Silverlight could also support WPF. While there are lots of similarities between Silverlight and WPF, there are also LOTS of differences, including the way VisualTreeHelper works - which is something the library uses for its boundary detection.

While I had it somewhere on my TO DO list to incorporate WPF support, it had always been on the backburner in favor of other tasks. But thanks to a new contributor to the code, Bill Seddon, I'm happy to say a new version of the Physics Helper Library is available with WPF support!

This library of Behaviors and Controls for Expression Blend makes it very quick to create physics games and simulations in Silverlight and WPF using the Farseer Physics Engine.

DOWNLOAD PHYSICS HELPER 3

VIEW THE DEMOS

Here are the highlights for this release:
  • Special thanks to contributions made by Bill Seddon!

    • WPF Support has been added
    • MagneticBehavior added, allowing two objects to attract
    • Behaviors now Categorized in Blend Asset Folder

  • PhysicsSoundBehavior adds support for buffered sound

  • PhysicsJoint has Min and Max angle limits

  • Silverlight Pinball game sample added (video tutorial coming soon)

Demos using Behaviors

Demo Behaviors 1
Falling Astronaut
Demo Behaviors 2
Rag Doll
Demo Behaviors 3
Truck w/Camera
Demo Behaviors 4
Flying Astronaut
Pinball Game
Pinball Game

Getting Started Videos

I have a couple of quick (10 min) screen casts which show how to use the new Physics Behaviors:

VIDEO ON "THE BASICS": VIEW | DOWNLOAD

VIDEO ON "JOINTS + PROGRAMMING": VIEW | DOWNLOAD


Comments (6)

Physics Behaviors for Silverlight 3!
Andy's Blog By Andy Beaulieu on 7/15/2009 7:21 PM


Today I released an initial version of “Physics Helper 3” to Codeplex. This includes a collection of new Behaviors for Expression Blend which makes it very quick to create physics games and simulations in Silverlight using the Farseer Physics Engine. This release requires Silverlight 3 and Expression Blend 3, which you can get here.

DOWNLOAD PHYSICS HELPER 3

Demos

There are four new demos using Behaviors, plus the original demos depending on the older User Control model. Note that version 3 still supports the User Control model, but I would recommend checking out the new Behaviors model as there is nice design time support in Blend.

VIEW ALL DEMOS

Demo Behaviors 1
Falling Astronaut
Demo Behaviors 2
Rag Doll
Demo Behaviors 3
Truck w/Camera
Demo Behaviors 4
Flying Astronaut

Getting Started Videos

I have a couple of quick (10 min) screen casts which show how to use the new Physics Behaviors:

VIDEO ON "THE BASICS": VIEW | DOWNLOAD

VIDEO ON "JOINTS + PROGRAMMING": VIEW | DOWNLOAD

Enhancing Behaviors with Code

Behaviors are great, but I can't imagine creating a full game using only canned behaviors. So at some point, you will need to add code to do AI, control levels and game state, and other tasks. 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 throught the PhysicsObjects dictionary:

_physicsController.PhysicsObjects["ball"].GeometryObject.RestitutionCoefficient = 1.3F;

... 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);

Feedback and Issues

This is an initial release and my first swing at Behaviors, so I'm sure there will be issues and suggestions. Please let them fly on the Codeplex Forum, and I hope you have fun! 

Comments (8)

Silverlight 3 Released!
Andy's Blog By Andy Beaulieu on 7/10/2009 12:45 PM

Today, the FINAL RTW version of Silverlight 3 was released! You can get everything you need to get started with Silverlight 3 at
silverlight.net/GetStarted, and the launch site is now live at www.seethelight.com (which features a rather amusing Infomercial). And as always, ScottGu is quick to the draw with his announcement post.

I have added some new posts on Silverlight 3:

Printing in Silverlight 3 with WriteableBitmap – Shows how to use the new WriteableBitmap class to “print” the Silverlight UI or take a screenshot.

Silverlight 3: HitTest with WriteableBitmap - Shows how to do pixel-perfect collision detection between Raster (Image) and Vector (XAML) elements in Silverlight.

Physics Helper 3: Coming Soon! - Shows the soon-to-be-released Physics Helper 3, with support for Behaviors in Blend.

And I have updated the older Silverlight 3 Beta posts so everything is compatible:

Silverlight 3: GPU Acceleration and Bitmap Caching – This is the most exciting feature of Silverlight 3, IMHO!

Silverlight 3: Pixel Shaders and Effects - See how you can create new effects using HLSL.

Silverlight 3: PlaneProjection with Storyboard - Looks at how to display and animate the new 3D Perspective projection.

Comments (0)

Physics Helper 3: Coming Soon!
Andy's Blog By Andy Beaulieu on 7/10/2009 11:08 AM


Silverlight 3 and Blend 3 introduce the concept of Behaviors, which make it easy to add common functionality using drag/drop inside Blend.

I’ve been working on creating a set of Behaviors for the Physics Helper Library, and have made good progress. Using these behaviors, you can very quickly put together physics-based games and simulations with little or no code. (Ok, I don’t really believe in the no-code scenario … but you can do some pretty neat stuff without code). Another new feature in the library is the ability to automatically determine the outline (collision boundary) of raster images (such as a PNG).

I’ll be releasing this updated library soon on Codeplex, but here is a screencast I put together to show the Behaviors in action:

[DOWNLOAD THE VIDEO]

Or click below to view it:

Comments (4)

"Printing" in Silverlight 3 with WriteableBitmap
Andy's Blog By Andy Beaulieu on 7/10/2009 8:30 AM


One of the high-profile missing features in Silverlight has been Printing support. If you have ever tried to print a web page containing Silverlight content, what you saw on the printed page may be skewed or even missing altogether!  So, what if you wanted to print a portion of your Silverlight screen, or take a “snapshot” image of the Silverlight UI to include in a report or other printable format?

Silverlight 3 can accomplish these scenarios using the WriteableBitmap API. WritableBitmap includes a Render method which can snag all of the pixels of a given UI Element and place them into a buffer for manipulation.

In this demo, I’ll show how to take a “snapshot” of a Silverlight UI screen, upload the image to a web server, and include it in a Report Viewer (RDLC) report. You could easily modify these steps to save the snapshot to an image file on the server, or otherwise manipulate the pixels.

VIEW THE DEMO        

DOWNLOAD THE SOURCE

The steps used in the demo are as follows:

1.       Render the Silverlight UI to a WriteableBitmap, passing in the UI Element and an arbitrary Transform. In the code below, the content of a Canvas named cnvSource is rendered to the WriteableBitmap. We pass in an empty TranslateTransform simply because one is required by the constructor:

WriteableBitmap bitmap = new WriteableBitmap(cnvSource, new TranslateTransform());


2. Convert the WriteableBitmap pixels to a PNG using Joe Stegman's PNG encoder.

EditableImage imageData = new EditableImage(bitmap.PixelWidth, bitmap.PixelHeight);

 

 

for (int y = 0; y < bitmap.PixelHeight; ++y)

{

    for (int x = 0; x < bitmap.PixelWidth; ++x)

    {

 

        int pixel = bitmap.Pixels[bitmap.PixelWidth * y + x];

 

        imageData.SetPixel(x, y,

                    (byte)((pixel >> 16) & 0xFF),

                    (byte)((pixel >> 8) & 0xFF),

                    (byte)(pixel & 0xFF),

                    (byte)((pixel >> 24) & 0xFF)

                    );

 

    }

}

 

Stream pngStream = imageData.GetStream();

 


NOTE that this PNG encoder does NOT include compression! This would be a good optimization to add, but also note that the GZipStream class is not present in Silverlight, so you would need to use an outside compression library such as SharpZipLib.

3. At this point, we have the PNG bytes in a stream, and you could take several approaches to get these bytes up to the server – such as using an Http Handler (ASHX). In this demo, we’ll place the bytes into a hidden field on the ASPX page and post the page back to the server  for inclusion in a report. To do this, we’ll translate the PNG bytes into a string using Base64 encoding:

byte[] binaryData = new Byte[pngStream.Length];

long bytesRead = pngStream.Read(binaryData, 0, (int)pngStream.Length);

 

string base64String =

        System.Convert.ToBase64String(binaryData,

                                      0,

                                      binaryData.Length);

 

// save the encoded PNG bytes to the page

HtmlDocument document = HtmlPage.Document;

HtmlElement txtPNGBytes = document.GetElementById("txtPNGBytes");

txtPNGBytes.SetProperty("value", base64String);

 

// this calls a js function "postBackPrint" which will cause a postback

HtmlPage.Window.CreateInstance("postBackPrint", new string[] { });



4. Now that we have our bytes up on the server, we can decode them and feed them to a ReportViewer (RDLC) report. This will give us a nicely printed format and the ability to export to PDF:

string bytes64 = Request["txtPNGBytes"];

byte[] imageBytes = System.Convert.FromBase64String(bytes64);

 

 

DSReportPrintImage ds = new DSReportPrintImage();

DataRow drImage = ds.Tables[0].NewRow();

drImage["ImageBytes"] = imageBytes;

ds.Tables[0].Rows.Add(drImage);

 

ReportViewer1.LocalReport.ReportPath = "ReportPrintSilverlight.rdlc";

 

ReportDataSource src = new ReportDataSource("DSReportPrintImage_ImageData", ds.Tables[0]);

ReportViewer1.LocalReport.DataSources.Add(src);

ReportViewer1.LocalReport.Refresh();

That’s it! I really think this use of WriteableBitmap as a snapshot/print function will be useful in some of my projects that need to capture the current view of the Silverlight application.

 

Comments (28)

Improved HitTest Method for Silverlight 3
Andy's Blog By Andy Beaulieu on 7/10/2009 8:24 AM


With the new Silverlight 3 WriteableBitmap class, it’s possible to do pixel-perfect collision detection (a “HitTest”) on bitmap (raster) images. In a
previous blog post, I showed how we can do a HitTest on Vector graphics in Silverlight 2. In this blog post, we’ll enhance the collision detection to handle BOTH Vector graphics and Raster graphics in Silverlight 3.

VIEW THE DEMO        

DOWNLOAD THE SOURCE

Looking at the demo code, one of the main routines is the CheckCollisionPoint class, which does a HitTest on a UI Element at a specific Point. If the element is an Image, then a WriteableBitmap object is used to check the specific pixel point (this WriteableBitmap is created in the CheckCollision method, shown later.). If the element is not an image, then we assume it is Vector based and we use the VisualTreeHelper class for a hit test:

public bool CheckCollisionPoint(Point pt, FrameworkElement control, FrameworkElement controlElem)

{

    if (controlElem is Image)

    {

        // NOTE that we saved the WB in the Tag object for performance.

        // in a real app, you would abstract this in your sprite class.

        WriteableBitmap wb = controlElem.Tag as WriteableBitmap;

 

        int width = wb.PixelWidth;

        int height = wb.PixelHeight;

 

        double offSetX = Convert.ToDouble(control.GetValue(Canvas.LeftProperty));

        double offSetY = Convert.ToDouble(control.GetValue(Canvas.TopProperty));

 

        pt.X = pt.X - offSetX;

        pt.Y = pt.Y - offSetY;

 

        int offset = Convert.ToInt32((width * pt.Y) + pt.X);

 

return (wb.Pixels[offset] != 0);

    }

    else

    {

        List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, controlElem) as List<UIElement>;

        return (hits.Contains(controlElem));

    }

}

The CheckCollisionPoint method is used by the CheckCollision method, which checks for a collision between two UI elements. Note that we always want to do a quick Rect.Intersect test on the bounds of the elements before doing the slower per-pixel Hit Test. This method also creates the WriteableBitmap and stores it in the Tag property (you may want to abstract this into a Sprite class in a real application):

private bool CheckCollision(FrameworkElement control1, FrameworkElement controlElem1, FrameworkElement control2, FrameworkElement controlElem2)

{

    // first see if sprite rectangles collide

    Rect rect1 = UserControlBounds(control1);

    Rect rect2 = UserControlBounds(control2);

 

    rect1.Intersect(rect2);

    if (rect1 == Rect.Empty)

    {

        // no collision - GET OUT!

        return false;

    }

    else

    {

        bool bCollision = false;

        Point ptCheck = new Point();

 

        // NOTE that creating the writeablebitmap is a bit intense

        // so we will do this once and store results in Tag property

        // in a real game, you might abstract this into a Sprite class.

        if (controlElem1 is Image)

            controlElem1.Tag = GetWriteableBitmap(control1);

 

        if (controlElem2 is Image)

            controlElem2.Tag = GetWriteableBitmap(control2);

 

        // now we do a more accurate pixel hit test

        for (int x = Convert.ToInt32(rect1.X); x < Convert.ToInt32(rect1.X + rect1.Width); x++)

        {

            for (int y = Convert.ToInt32(rect1.Y); y < Convert.ToInt32(rect1.Y + rect1.Height); y++)

            {

                ptCheck.X = x;

                ptCheck.Y = y;

 

 

                if (CheckCollisionPoint(ptCheck, control1, controlElem1))

                    if (CheckCollisionPoint(ptCheck, control2, controlElem2))

                    {

                        bCollision = true;

                        break;

                    }

 

            }

            if (bCollision) break;

        }

        return bCollision;

    }

}

A quick note about performance: This method provides a simple way of getting pixel-perfect collision detection in Silverlight 3. But if you have a lot of elements that are colliding simultaneously (without being destroyed), this may not perform well.  Also, high velocity objects could pass through each other.

 

 

Comments (10)

Coding4Fun Show - Physics Helper
Andy's Blog By Andy Beaulieu on 6/9/2009 6:21 AM


Brian Peek has a new show on Channel9 called Coding4Fun TV. Brian is the author of the famous Wiimote Library as well as the Coding4Fun Book.

I had the pleasure of being Brian's guest for the first episode of Coding4Fun TV! We talked about using the Physics Helper Library to code simulations and games in Silverlight.

You can view the episode here.

 

 
Comments (0)

Blend Artboard Exceptions and Loaded Event
Andy's Blog By Andy Beaulieu on 6/3/2009 8:35 AM

It can be frustrating when you are coding along in Silverlight, and you open up a UserControl in Blend only to see something like the following:


An Exception was thrown.
InvalidOperationException: HtmlPage_NotEnabled
StackTrace
InnerException: None

This is often caused by a UserControl that has a Loaded event with some code that isn't happy inside Blend's artboard. That's right - when you preview a UserControl inside Blend, the Loaded event for the control actually fires, and code in that handler is executed! You may have noticed this when you place a StoryBoard.Begin() call in the Loaded event, Blend will actually show the animation on the artboard.

So how do we workaround these exceptions? First, expand the StackTrace arrow, and you'll get some more details. In this case, we can see that the Loaded event for a UserControl named "ucResults" is the culprit:

Now that we know which Loaded event is causing the issue, take a look at the code and see what is going on. In this case, the code is accessing the HtmlPage class - which would not be available to Blend when it hosts the control on the artboard:

private void UserControl_Loaded(object sender, RoutedEventArgs e)

{

    // Did the QueryString contain an Email address?

    if (HtmlPage.Document.QueryString.Keys.Contains("Email") )

        txtEmailTo.Text = HtmlPage.Document.QueryString["Email"].ToString();

}

Luckily, there is a special class, System.ComponentModel.DesignerProperties, which allows us to check at runtime whether we are in Design Mode or not. We can just add a check on this, and if we are in Design Mode, we get out of the Loaded event handler:

private void UserControl_Loaded(object sender, RoutedEventArgs e)

{

    if (DesignerProperties.GetIsInDesignMode(this))

        return;

 

    // Did the QueryString contain an Email address?

    if (HtmlPage.Document.QueryString.Keys.Contains("Email") )

        txtEmailTo.Text = HtmlPage.Document.QueryString["Email"].ToString();

}

 

Comments (1)

Module Border Module Border
Module Border
  Subscribe
Module Border
RSS   Twitter
Module Border Module Border
Module Border
  Diversions
Module Border

TALKING RAGDOLL
This Windows Phone 7 App was created using Silverlight, the  Physics Helper Library,  and the Farseer Physics Engine. It gets interesting when you import your friends photos and have your way with them!

MORE INFO



DROPPYPOP
This Windows Phone 7 game was created using Silverlight, the  Physics Helper Library,  and the Farseer Physics Engine.
DEMO

MORE INFO



BOSS LAUNCH
This physics game won first place in the Server Quest Contest. Created using Silverlight 2, the Physics Helper Library,  and the Farseer Physics Engine.
PLAY IT

MORE INFO



DESTROY ALL INVADERS
A scrolling shooter game where the objective is to destroy the invading UFO's flying over a neighborhood of your choosing. Imagery provided by Microsoft Virtual Earth. Created using Silverlight 2.
PLAY IT

INFO AND CODE



PHYSICS HELPER DEMOS
These demos were created for the Physics Helper Library, which makes it easy to create physics games and simulations using Expression Blend, Silverlight, and the Farseer Physics Engine.
PLAY IT

INFO AND CODE



HOOK SHOT
This little basketball game took first place in the TeamZoneSports Silverlight Contest. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



SORT THE FOOBARS
A game where you need to sort the good foobars from the bad ones. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



POLYGON PHYSICS DEMO
A demo showing polygon physics where the user draws physics objects with the mouse. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



SILVERLIGHT ROCKS!
Destroy the asteroids before they destroy your ship! Created using Silverlight 2.
PLAY IT

INFO AND CODE



FISH GAME
A simple game of harpoon-the-fish. Written using the AJAX Sprite Toolkit.
PLAY IT

INFO AND CODE

Module Border Module Border
Module Border
  Search_Blog
Module Border
Module Border Module Border
Module Border
  Blog_Archive
Module Border
Module Border Module Border
Copyright (c) 2013 andy.beaulieu.com - Login