How would you apply PhysicsExplodeBehavior to...

Jul 28, 2009 at 2:23 PM
Edited Jul 28, 2009 at 2:25 PM

the following scenario.

In your Flying Astronaut demo you apply a PhysicsExplodeBehavior to your astronaught usercontrol.

You specify that it will MatchLikeBodyNames so that any mine you hit will explode on contact.

In my example I'm trying to do it the other way around, I want the mines (bugs) to explode so in the mine usercontrol I apply the explode on collision.

The problem I'm seeing is that when multiple instances of the Bug user control are on the page, a collision with only one of the Bugs triggers the explosion, and in fact another bug entirely shows the explosion animation. All bugs disappear as a result of the explosion.

 

<Canvas x:Name="cnvBug" Height="50" Width="50" Canvas.Left="0">
<i:Interaction.Behaviors>
<pb:PhysicsObjectBehavior BoundaryElement="imgBug"/>
</i:Interaction.Behaviors>
<i:Interaction.Triggers>
<pb:PhysicsCollisionTrigger BodyOne="cnvBug" BodyTwo="cnvShip" MatchLikeBodyNames="False">
<pb:PhysicsExplodeBehavior DeactivateBody="True" NumParticles="8"/>
</pb:PhysicsCollisionTrigger>
</i:Interaction.Triggers>
<Image x:Name="imgBug" Height="50" Width="50" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" Source="Resources/Images/bug_green.png" Stretch="Fill" d:LayoutRounding="Auto">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-90"/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Canvas>

I'm assuming it's because the Bug's inner canvas (which is BodyOne) isn't unique between the instances and somewhere the explosions are being wired up by name.

Where would you suggest I look to change this behavior?

Coordinator
Jul 29, 2009 at 1:30 AM

I would probably need to recreate a similar situation to figure this out but it looks like you found a "bug" (heh) in the Explode or Collison behavior.

One thing to understand is that, when the Physics Helper translates your UI elements into Physics objects, all of the Physics objects get added into your main game canvas. This is necessary for embedded joints and other physics properties within user controls.

Also, if any elements would have the same name after this operation, the physics helper will append a number to make the element name unique. For example, if you had a cnvBug canvas inside a user control, and then added 3 instances of the control to the simulation, you would see the elements renamed to cnvBug, cnvBug_1, and cnvBug_2.

So it is likely that is part of what is happening here.

If there is any way for you to make your entire project available, it would be possible for me to take a look at it.

Jul 29, 2009 at 9:58 AM

I've emailed you the source to your .com address.

 

Coordinator
Jul 30, 2009 at 11:00 AM

Ok, thanks for the source. I see what the problem is now and unfortunately it's looking like the PhysicsExplodeBehavior needs some rework to handle this many-to-one type scenario. The way the cnvBug user control is set up, it has a PhysicsCollisionTrigger that will fire when "cnvBug" collides with "cnvShip" and that is working fine (this is indeed when the trigger is happening). And it is placing the Explode behavior at the first instance of cnvBug as well. But it isn't identifying the correct source of the collision because you have many bugs with a single source of the collision.

For now can you just handle the Collision event through code? Here is what that would look like:

 

public partial class MainPage : UserControl
{
    PhysicsControllerMain _physicsController;

    public MainPage()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        _physicsController = canvas.GetValue(PhysicsControllerMain.PhysicsControllerProperty) as PhysicsControllerMain;
        _physicsController.Collision += new PhysicsControllerMain.CollisionHandler(_physicsController_Collision);
    }

    void _physicsController_Collision(string sprite1, string sprite2)
    {
        if (sprite1 == "cnvShip" && sprite2.StartsWith("cnvBug"))
        {
            // your collision behavior here
        }
    }
}