SpriteHand
Module Border
  Using HitTest Method in Silverlight 2 for Collision Detection
Module Border
Location: BlogsAndy's Blog    
Posted by: host 3/6/2008 12:03 PM


UPDATE 7/10/2009: See
THIS BLOG POST regarding Silverlight 3 RTW, which demonstrates collision detection between XAML and Image elements.

 

Prior to Silverlight 2.0 Beta 1, there was no method provided in the framework for determining if two UI elements were colliding. So if you wanted collision testing, you had to pretty much brew up your own. But there is now a FindElementsInHostCoordinates method provided on the VisualTreeHelper class. This method returns a list of elements that intersect with a Point or Rect. Not particularly helpful out of the box, and also not a very fast operation, but using this new method we can do some fair collision detection.

 

[TRY THE DEMO]  [DOWNLOAD SOURCE]

 

If you try the demo above, you can use the mouse to move the ship around the asteroid. Notice that a collision is only detected when the ship's outer path element collides with the asteroid's path element.

 

This was done using the method below, which can be used to determine if two UI Elements are colliding. Remember that the FindElementsInHostCoordinates method is very slow so we always want to do a quick Rectangle Intersect collision test first before doing a per-pixel Hit Test. Once the intersection rectangle is found, the code simply loops through pixel-by-pixel to see if both elements in question share a Hit Test on the same x,y pixel…

 

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

 

        // 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;

 

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

                if (hits.Contains(controlElem1))

                {

                    // we have a hit on the first control elem, now see if the second elem has a similar hit

                    List<UIElement> hits2 = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(ptCheck, control2) as List<UIElement>;

                    if (hits2.Contains(controlElem2))

                    {

                        bCollision = true;

                        break;

                    }

                }

            }

            if (bCollision) break;

        }

        return bCollision;

    }

 

 

}

Permalink |  Trackback

Comments (18)   Add Comment
Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/13/2008 2:53 PM
Great info thanks.
For a game like a basic platformer that only requires fairly simple physics do you think this would be a better way to go than the Farseer physics engine or do you think all games are better off with Farseer? Is there a post somewhere talking about how much file size, cpu, memory req etc farseer adds?

Thanks

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/13/2008 5:09 PM
If the player character in the platformer is a biped or quadraped (that is, walks around), if you know what I mean, I think it would be tough to pull that off with Farseer. The reason is, Farseer works off the concept of moving things by applying force and torque to an object. Also, Farseer doesn't have the concept of resting bodies. So yeah - for a standard platformer I would probably not use Farseer. But for something like Gumboy (http://www.gumboycrazyadventures.com/) it would be perfect.

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/17/2008 4:21 PM
Pretty cool sample, I have tested but found a nasty surprise... for a border element you get a hittest as well if you click inside :-(, is it possible to configure hittest so only add that border element when you click just on the border?

Thanks
Braulio (info@tipsdotnet.com)

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/18/2008 7:13 AM
Braulio - for the border issue, the only thing I can think of is to design the border element as a separate path and do the hit test on that. So you would basically draw out the border as a Path (say using Blend) and have it loop back into the shape you want. Or, you could use the menu option "Object/Combine/Subtract" in Blend to subtract out the core of an object so you are left with a Path that matches the border. A bit of design work to do that I know, but I think it would get you by.

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/25/2008 5:46 AM
A Pretty Clear & Useful Tutorial~!!!

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/26/2008 5:55 AM
how about more then one control ?
eg 2 Rock and 1 Ship ?

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/26/2008 6:18 AM
For collisions between more than one control, you need to check collision for each combination (for example. ship and rock 1, and ship and rock 2, etc).

If you look at the Silverlight Rocks! game code (available on this site - just follow the MORE INFO link on the right side of this page), it shows a good example as it is using this collision detection.

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/27/2008 4:24 AM
well i have try the example , Path, Ellipse, Rectangle is work
but if i using Thumb, it not work.
In some condition, it maybe need fire by DragDelta event instead of mousemove event.

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 12/19/2008 3:50 PM
Thank you for sharing man. And nice Demos.

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 1/7/2009 2:16 PM
thanks!

zhuqian    By Anonymous on 2/19/2009 9:15 PM
hjqha@live.cn

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 3/12/2009 11:41 AM
Just what I was looking for. Keep up the good work.

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 4/22/2009 5:40 AM
Thanks for good tutorial. Very easy and usefull

Re:This collision detection vs Farseer collision detection    By Anonymous on 6/7/2009 8:25 AM
Is this colission detection better or worse comparing to collision detection of farseer? which will take more time and memory. Do anyone has any idea?

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 7/31/2009 5:22 PM
This article was translated into Russian

http://silverlight.su/

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 12/12/2009 8:05 AM
Andy, this is good stuff. I made a slight change to the code because I didn't like the idea of always having to create a single element (like a path) to surround my object in order for the hit test to work.

So I changed the CheckCollision method signature to accept Panels for controlElem1 and controlElem2. Then, the only change is that after getting the hits, the if looks like this:

if (hits.Intersect(controlElem1.Children).Count() > 0)

and

if (hits2.Intersect(controlElem2.Children).Count() > 0)

Admittedly this will be a bit slower, but I think it gives more versatility for the user control graphics. What do you think?

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 12/12/2009 8:06 AM
Andy, this is good stuff. I made a slight change to the code because I didn't like the idea of always having to create a single element (like a path) to surround my object in order for the hit test to work.

So I changed the CheckCollision method signature to accept Panels for controlElem1 and controlElem2. Then, the only change is that after getting the hits, the if looks like this:

if (hits.Intersect(controlElem1.Children).Count() > 0)

and

if (hits2.Intersect(controlElem2.Children).Count() > 0)

Admittedly this will be a bit slower, but I think it gives more versatility for the user control graphics. What do you think?

Re: Using HitTest Method in Silverlight 2 for Collision Detection    By Anonymous on 12/12/2009 8:33 AM
Sorry bout the double post. Just wanted to mention that the posted code requires you to pass in the root canvas to the CheckCollision method (rather than the path for the ship).


Title:
Comment:
Add Comment   Cancel 
Module Border Module Border
Module Border
  Subscribe
Module Border
RSS   Twitter
Module Border Module Border
Module Border
  Diversions
Module Border


PHYSAMAJIG
This Windows app was created using Physics Helper XAML, and the Farseer Physics Engine.
DOWNLOAD

MORE INFO



TALKING RAGDOLL
This Windows Phone 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



BOSS LAUNCH
This physics game won first place in the Server Quest Contest. Created using Silverlight , 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.
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 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 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 and the Farseer Physics engine.
PLAY IT

MORE INFO



SILVERLIGHT ROCKS!
Destroy the asteroids before they destroy your ship! Created using Silverlight.
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) 2014 andy.beaulieu.com - Login
toms outlet cheap toms jordan pas cher Timberland Boots mulberry outlet portafoglio prada hollister soldes hogan scarpe mbt hogan jordan pas cher louboutin soldes jordan Homme louboutin pas cher Gucci Borse louboutin pas cher jordan pas cher lancel pas cher cheap ray ban sunglasses ray ban outlet toms outlet toms outlet scarpe mbt occhiali da sole a basso costo Louboutin Chaussures basket louboutin hollister pas cher jordan shoes sale