 |
|
|
|
Adding Behaviors Programmatically
|
|
|
 |
|
Location: Blogs Andy's Blog |
|
| Posted by: host |
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
|
|
| Permalink |
Trackback |
Comments (6)
Add Comment
|
Re: Adding Behaviors Programmatically
|
By Anonymous on
10/13/2009 6:06 AM
|
Nice post, Andy. In the first example, you also need:
using Microsoft.Expression.Interactivity.Layout;
|
|
|
Re: Adding Behaviors Programmatically
|
By Anonymous on
10/29/2009 4:03 AM
|
Is it possible to have "MouseDragElementBehavior" and "PhysicsObjectBehavoir" for same object?
I was wondering if I could move an object smoothly by mouse and apply the PhysicsObjectBehavior at the same time...
Thanks in advance, Mehdi m_mehdi_m62@yahoo.com
|
|
|
Re: Adding Behaviors Programmatically
|
By Anonymous on
11/2/2009 9:54 AM
|
They MousePickSpring is enabled at the PhysicsController object, and applies to all objects (that are not static). You could change this behavior with some customization (I would just copy the pick spring code from the phyiscs Controller main class)
But I don't think you will be able to have smooth drag/drop with the Farseer engine. It is meant to move objects by applying force, torque, and other simulation elements (such as the pick spring). If you move objects with the mouse directly, you will likely see tunneling problems.
-Andy
|
|
|
Re: Adding Behaviors Programmatically
|
By Anonymous on
12/13/2009 2:27 AM
|
There is a demo in codeplex which shows "Adding User Controls Programmatically". Can you attach a simple demo here or in codeplex which can shows how to "Adding Physics Behaviors Programmatically". I tried to "Adding Physics Behaviors Programmatically" but all failed... Thanks a lot...
|
|
|
Re: Adding Behaviors Programmatically
|
By Anonymous on
6/22/2011 4:09 PM
|
|
This doesn't work for me at all when trying to add a custom user control (using either AddPhysicsBody or AddPhysicsCanvas functions), and it only works about half the time when adding a custom path as a PhysicsBody (it gives an exception at SetVertices). However, the strange thing is it works perfectly when adding the behaviors through Blend (including those user controls I mentioned), and it only ever fails when doing it programatically. Please help!
|
|
|
Re: Adding Behaviors Programmatically
|
By Anonymous on
1/27/2012 2:36 AM
|
Hey i'm trying to add Explode behavior but its not working... This is the code, plz help me with this..
if ( sprite1.Name.Contains("bouncball") && sprite2.Name.Contains("Ground")) {
PhysicsExplodeBehavior exp=new PhysicsExplodeBehavior(); exp.NumParticles = 4; exp.DeactivateBody = true; PhysicsCollisionTrigger e = new PhysicsCollisionTrigger(); e.Attach(bouncball); e.BodyOne = bouncball.Name; e.BodyTwo = Ground.Name; e.Actions.Add(exp); System.Windows.Interactivity.Interaction.GetTriggers(bouncball).Add(e);
When i do
_physicsController.AddPhysicsBody(bouncball.GetValue(PhysicsObjectMain.PhysicsObjectProperty) as PhysicsObjectMain); It shows an exception saying the element is already a child of another element. Help me with this. I want the bouncball to explode in 4 pieces when it touches the ground.
|
|
|
|
 |
|
 |
|
|