Can't make the physics behaviors work with my xaml objects

Jul 22, 2009 at 5:22 AM

Hi!

I found the physics behaviors an excelent idea to implement physics in a game in a fast and easy way.

However, I can't make them work.

For each element I try to implement the behaviors in, I get the following exception:

"System.ArgumentException: Could not determine the outline of UIElement arbolIzquierdo. Could not find a point within its boundaries."

This is the Xaml of my element:

<Path x:Name="arbolIzquierdo" Fill="#FF866819" Stretch="Fill" Stroke="Black" Height="402" Width="134" Data="M55,366 L40,325 L34,288 L32,238 L35,209 L55.900707,201.07875 L88,193 L110,188 L128.52844,179.70753 L122.52844,170.70753 L100.21276,170.00125 L78,168 L34.751774,167.99625 L40.794327,125.89124 L53.886524,121.88125 L79.063828,111.85625 L112,107 L130.42552,100.82875 L138.48227,83.786247 L125,86 L72,84 L54,85 L32.737587,84.78875 L35,43 L41,22 L48,-1 L63,-31 L-1,-30 L-1,93 L-1,368 L58,370 z" UseLayoutRounding="False" Canvas.Top="-31.5" StrokeThickness="3">
			<i:Interaction.Behaviors>
				<pb:PhysicsObjectBehavior IsStatic="True" BoundaryElement="arbolIzquierdo"/>
			</i:Interaction.Behaviors>
		</Path>
Can anybody help me with this, please? 
Coordinator
Jul 22, 2009 at 11:37 AM

A couple of things to try...

- What sort of Layout Container is your Path in? Remember that a Physics Simulation must be inside a Canvas (not a Grid).

- Did you put a PhysicsController Behavior on the main Canvas? This is what controls the main physics simulation.

If you're still having problems, maybe post your entire XAML.

Jul 22, 2009 at 11:03 PM

Yes... I'm using a Canvas with the PhyicsControllerBehavior.

This is my Xaml:

<UserControl
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:pb="clr-namespace:Spritehand.PhysicsBehaviors;assembly=Spritehand.PhysicsBehaviors" xmlns:PickMeAFruit_Fruits="clr-namespace:PickMeAFruit.Fruits"
	x:Class="PickMeAFruit.Scenes.Forest"
	d:DesignWidth="640" d:DesignHeight="480" Height="400" Width="600">

	<Canvas x:Name="LayoutRoot">
		<i:Interaction.Behaviors>
			<pb:PhysicsControllerBehavior/>
		</i:Interaction.Behaviors>
		<Rectangle x:Name="cielo" Fill="#FF23C7CD" Stroke="Black" StrokeThickness="2" Height="410" Width="601" Canvas.Left="-1" Canvas.Top="-10"/>
		<Rectangle x:Name="suelo" Fill="#FF4BA52B" Stroke="Black" StrokeThickness="2" Height="51" Width="649" Canvas.Left="-17" Canvas.Top="369">
			<i:Interaction.Behaviors>
				<pb:PhysicsObjectBehavior IsStatic="True">
			</i:Interaction.Behaviors>
		</Rectangle>
		<Path x:Name="arbolDerecho" Fill="#FF866819" Stretch="Fill" Stroke="Black" StrokeThickness="3" Height="402" Width="140.5" UseLayoutRounding="False" Canvas.Left="459.5" Canvas.Top="-31.5" Data="M55,366 L40,325 L34,288 L32,238 L35,209 L55.900707,201.07875 L88,193 L110,188 L128.52844,179.70753 L122.52844,170.70753 L100.21276,170.00125 L78,168 L34.751774,167.99625 L40.794327,125.89124 L53.886524,121.88125 L79.063828,111.85625 L112,107 L130.42552,100.82875 L138.48227,83.786247 L125,86 L72,84 L54,85 L32.737587,84.78875 L35,43 L41,22 L48,-1 L63,-31 L-1,-30 L-1,93 L-1,368 L58,370 z" RenderTransformOrigin="0.5,0.5">
			<i:Interaction.Behaviors>
				<pb:PhysicsObjectBehavior/>
			</i:Interaction.Behaviors>
			<Path.RenderTransform>
				<TransformGroup>
					<ScaleTransform ScaleX="-1"/>
					<SkewTransform AngleX="0" AngleY="0"/>
					<RotateTransform Angle="0"/>
					<TranslateTransform/>
				</TransformGroup>
			</Path.RenderTransform>
		</Path>
		<Ellipse Fill="#FFE5EE3C" Stroke="Black" StrokeThickness="2" Height="69" Width="73" Canvas.Left="305" Canvas.Top="19"/>
		<Path Fill="Black" Stretch="Fill" Stroke="Black" StrokeThickness="2" Height="22" Width="3.32" UseLayoutRounding="False" Canvas.Left="330" Canvas.Top="41" Data="M331,42 C332.23529,49.941113 332.68378,54.022697 332,62"/>
		<Path Fill="Black" Stretch="Fill" Stroke="Black" StrokeThickness="2" Height="25" Width="5" UseLayoutRounding="False" Canvas.Left="350" Canvas.Top="39" Data="M351,40 C352.31277,48.168415 353.14124,54.412239 354,63"/>
		<Path Stretch="Fill" Stroke="Black" StrokeThickness="2" Height="10" Width="25" UseLayoutRounding="False" Canvas.Left="330" Canvas.Top="69" Data="M332,71 L346,79 L355,73"/>
		<PickMeAFruit_Fruits:Apple x:Name="apple" Canvas.Left="291" Canvas.Top="142">
			<i:Interaction.Behaviors>
				<pb:PhysicsObjectBehavior/>
			</i:Interaction.Behaviors>
		</PickMeAFruit_Fruits:Apple>
		<Path x:Name="arbolIzquierdo" Fill="#FF866819" Stretch="Fill" Stroke="Black" Height="402" Width="134" Data="M55,366 L40,325 L34,288 L32,238 L35,209 L55.900707,201.07875 L88,193 L110,188 L128.52844,179.70753 L122.52844,170.70753 L100.21276,170.00125 L78,168 L34.751774,167.99625 L40.794327,125.89124 L53.886524,121.88125 L79.063828,111.85625 L112,107 L130.42552,100.82875 L138.48227,83.786247 L125,86 L72,84 L54,85 L32.737587,84.78875 L35,43 L41,22 L48,-1 L63,-31 L-1,-30 L-1,93 L-1,368 L58,370 z" UseLayoutRounding="False" Canvas.Top="-31.5" StrokeThickness="3">
			<i:Interaction.Behaviors>
				<pb:PhysicsObjectBehavior IsStatic="True">
			</i:Interaction.Behaviors>
		</Path>
	</Canvas>
</UserControl>
Coordinator
Jul 23, 2009 at 1:16 AM

It looks like the problem is actually in the "Apple" user control. If I remove that, then it seems ok. Can you check that the Apple user control has a Canvas layout container as well (not a Grid)?

Also, I noticed one other issue - you did a transform on the "arbolDerecho" Path, which isn't handled well by the boundary detection algorithm. To work around this issue, just place the Path inside a Canvas, and then apply the PhysicsObjectBehavior to the Canvas. You can use this method of encapsulating objects in a Canvas whenever you need to do a transform on a primitive like a Path, etc.

Below is the XAML that works (notice the Canvas wrapper for arbolDerecho):

 

<UserControl
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d"
 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:pb="clr-namespace:Spritehand.PhysicsBehaviors;assembly=Spritehand.PhysicsBehaviors" xmlns:PickMeAFruit_Fruits="clr-namespace:PickMeAFruit.Fruits"
 x:Class="TestPathProblem.MainPage"
 d:DesignWidth="640" d:DesignHeight="480" Height="400" Width="600">

 <Canvas x:Name="LayoutRoot">
  <i:Interaction.Behaviors>
   <pb:PhysicsControllerBehavior MousePickEnabled="True"/>
  </i:Interaction.Behaviors>
  <Rectangle x:Name="cielo" Fill="#FF23C7CD" Stroke="Black" StrokeThickness="2" Height="410" Width="601" Canvas.Left="-1" Canvas.Top="-10"/>
  <Rectangle x:Name="suelo" Fill="#FF4BA52B" Stroke="Black" StrokeThickness="2" Height="51" Width="649" Canvas.Left="-17" Canvas.Top="369">
   <i:Interaction.Behaviors>
    <pb:PhysicsObjectBehavior IsStatic="True"/>
   </i:Interaction.Behaviors>
  </Rectangle>
  <Canvas x:Name="arbolDerecho" Height="402" Width="140" Canvas.Left="460" Canvas.Top="-31">
   <i:Interaction.Behaviors>
    <pb:PhysicsObjectBehavior/>
   </i:Interaction.Behaviors>
   <Path x:Name="Path" Fill="#FF866819" Stretch="Fill" Stroke="Black" StrokeThickness="3" Height="402" Width="140.5" UseLayoutRounding="False" Data="M55,366 L40,325 L34,288 L32,238 L35,209 L55.900707,201.07875 L88,193 L110,188 L128.52844,179.70753 L122.52844,170.70753 L100.21276,170.00125 L78,168 L34.751774,167.99625 L40.794327,125.89124 L53.886524,121.88125 L79.063828,111.85625 L112,107 L130.42552,100.82875 L138.48227,83.786247 L125,86 L72,84 L54,85 L32.737587,84.78875 L35,43 L41,22 L48,-1 L63,-31 L-1,-30 L-1,93 L-1,368 L58,370 z" RenderTransformOrigin="0.5,0.5">
    <Path.RenderTransform>
     <TransformGroup>
      <ScaleTransform ScaleX="-1"/>
      <SkewTransform AngleX="0" AngleY="0"/>
      <RotateTransform Angle="0"/>
      <TranslateTransform/>
     </TransformGroup>
    </Path.RenderTransform>
   </Path>
  </Canvas>
  <Ellipse Fill="#FFE5EE3C" Stroke="Black" StrokeThickness="2" Height="69" Width="73" Canvas.Left="305" Canvas.Top="19"/>
  <Path Fill="Black" Stretch="Fill" Stroke="Black" StrokeThickness="2" Height="22" Width="3.32" UseLayoutRounding="False" Canvas.Left="330" Canvas.Top="41" Data="M331,42 C332.23529,49.941113 332.68378,54.022697 332,62"/>
  <Path Fill="Black" Stretch="Fill" Stroke="Black" StrokeThickness="2" Height="25" Width="5" UseLayoutRounding="False" Canvas.Left="350" Canvas.Top="39" Data="M351,40 C352.31277,48.168415 353.14124,54.412239 354,63"/>
  <Path Stretch="Fill" Stroke="Black" StrokeThickness="2" Height="10" Width="25" UseLayoutRounding="False" Canvas.Left="330" Canvas.Top="69" Data="M332,71 L346,79 L355,73"/>
  <!--<PickMeAFruit_Fruits:Apple x:Name="apple" Canvas.Left="291" Canvas.Top="142">
   <i:Interaction.Behaviors>
    <pb:PhysicsObjectBehavior/>
   </i:Interaction.Behaviors>
  </PickMeAFruit_Fruits:Apple>-->
  <Path x:Name="arbolIzquierdo" Fill="#FF866819" Stretch="Fill" Stroke="Black" Height="402" Width="134" Data="M55,366 L40,325 L34,288 L32,238 L35,209 L55.900707,201.07875 L88,193 L110,188 L128.52844,179.70753 L122.52844,170.70753 L100.21276,170.00125 L78,168 L34.751774,167.99625 L40.794327,125.89124 L53.886524,121.88125 L79.063828,111.85625 L112,107 L130.42552,100.82875 L138.48227,83.786247 L125,86 L72,84 L54,85 L32.737587,84.78875 L35,43 L41,22 L48,-1 L63,-31 L-1,-30 L-1,93 L-1,368 L58,370 z" UseLayoutRounding="False" Canvas.Top="-31.5" StrokeThickness="3">
   <i:Interaction.Behaviors>
    <pb:PhysicsObjectBehavior IsStatic="True"/>
   </i:Interaction.Behaviors>
  </Path>
 </Canvas>

 

</UserControl>

Jul 23, 2009 at 2:39 AM

Thanks for your answer, but... when I try your code, it only work sometimes... I mean, sometimes I debug and it works, and sometimes I debug and it doesn't work anymore.

The farseer behaviors look great! But, for some reason I can't make it work, so I think I'll have to use Farseer in the "normal" way =/

Coordinator
Jul 23, 2009 at 11:18 AM

If you have the time, it would be helpful if you could tell me what happens when it doesn't work.  Are you making changes between runs? I haven't personally seen inconsistent behavior unless changes are made.

Do you get an error? Or are you seeing something odd in the behavior?

Jul 23, 2009 at 1:59 PM

Ok... I found the error...

My stages, where I draw my game assets, all of them have a Canvas LayoutRoot, but, I host them in another control, called "Game.xaml".

The "Game.xaml" user control should be the class where I display my scenes and my hud, so the layoutRoot of the Game.xaml is actually a Grid, and inside it I place my "Forest.xaml" control.

So now I changed it for a Canvas and it works right.

I thought the only requirement was that the layoutRoot of the control which contains all of the physics elements should be a Canvas, as I did it in my example.

Can't I use a Grid in a parent control to lay out the game states and the hud?

Coordinator
Jul 23, 2009 at 4:51 PM

There are some cases where the VisualTreeHelper.FindElementsInHostCoordinates method behaves a little differently (this is the method that the PhysicsHelper uses to determine outlines of elements).

I think the scenario you described is OK _if_ the Canvas with the PhysicsController is the topmost and leftmost element in the Grid. But if there is any kind of Grid Layout causing the Canvas to move around then it causes the issues you are seeing.

I'll see if there is a way around this issue, I remember looking at it briefly before.

Jul 23, 2009 at 5:42 PM

Thank you for your help!

With your helper behaviors it looks like we all could help by developing other game funcionalities behaviors to make the game development with silverlight and expression blend easier and faster.

When I come back to house I'll try to figure out why my other user control I instantiated in the forest.xaml doesn't work with the behaviors.

Thanks for your great contribution!

Coordinator
Jul 23, 2009 at 6:02 PM

Yes, absolutely. If anyone comes up with Behaviors or enhancements that they would like to share please let me know. I can add folks into the project here on Codeplex or get the changes in myself and give credit to the developer.

Sep 28, 2010 at 8:10 PM

HI,

I am having this error all over again...

I copied two files(MainPage.xaml and ucRagDoll.xaml with an appropriates .cs files) from your DemoBehaviors2 (ragdoll demo) to my project.

and i wrote next metod>

 

 private void RagDoll_Click(object sender, RoutedEventArgs e)
        {
           
            border.Child = new DemoBehavior.Doll();

        }
I renamed your MainPage class to Doll class (because of collision with mine) in your project and it worked just fine...
SO what this suppose to do is to render your MainPage user control within my border control but instead it trows an mentioned error.
Why?? I've done this with may other controls and it never have shown this error?

I also tried clearing content of entire usercontrol that contains other user controls but the same happens.

IN APp.xaml i wrote>

Border _border = new Border();

private void Application_Startup(object sender, StartupEventArgs e) { _border.BorderBrush = new SolidColorBrush(Colors.Orange); _border.BorderThickness = new Thickness(3.0); this.RootVisual = _border; _border.Child = new MainPage(); } public static void ChangePage(UserControl page) { var currentApp = (App)Application.Current; currentApp._border.Child = null; GC.Collect(); currentApp._border.Child = page; }
and in mainpage.xaml i wrote next method so that whole content of page change on button cliclk
 private void RagDoll_Click(object sender, RoutedEventArgs e)
        {
            App.ChangePage(new DemoBehaviors2.Doll());
            
        }