[Source code] Collision Detection of Irregular Objects in Silverlight 4 (whether to collide with the boundary of monsters is often used in Games)

Source: Internet
Author: User
In the previous Silverlight, there was an hittest method that could be used to perform collision detection. But, older versions (pre 3.0) did have a hittest method! The hittest method cannot be used in silverlight4. So what should we do?

Next I will explain a foreign Source code To let everyone know how to perform collision detection. A findelementsinhostcoordinates method is used to detect collision without hittest. Another method is the Intersect method, which is used to establish the intersection range.

Demo: http://www.andybeaulieu.com/silverlight/2.0/hittest/clientbin/testpage.htmloriginal blog address (downloadable source code): http://www.andybeaulieu.com/Default.aspx? Tabid = 67 & entryid = 95

Collision principle: We use rectangular boxes to frame the irregular two elements to represent the maximum range. When the two rectangular boxes want to collide, we take out the intersection range and use the intersect method, however, the intersection of rectangles does not mean that the actual objects are intersecting. Therefore, we also need to traverse each vertex pixel in the intersection range to check whether the intersection two objects are on this vertex pixel, use findelementsinhostcoordinates. If both are present, it indicates a collision. CodeDisplay (I have added a Chinese note and added a comment based on the principle to help me easily understand the following code ):
Using  System;
Using System. Collections. Generic;
Using System. LINQ;
Using System. net;
Using System. windows;
Using System. Windows. controls;
Using System. Windows. documents;
Using System. Windows. input;
Using System. Windows. Media;
Using System. Windows. Media. animation;
Using System. Windows. shapes;

Namespace Hittest
{
Public Partial Class Page: usercontrol
{
Public Page ()
{
Initializecomponent ();


}

Private Void Usercontrol_mousemove ( Object Sender, mouseeventargs E)
{
Point PT = E. getposition (cnvhittest );

Ship. setvalue (canvas. leftproperty, Pt. X );
Ship. setvalue (canvas. topproperty, Pt. y );

// Lets get pointers to the actual UI elements we care about:
// Obtain the path coordinates of the spacecraft.
Path shipshell = Ship. findname ( " Shipshell " ) As Path;
// Obtain the path coordinates of the meteorite.
Path cnvasteroid = Asteroid. findname ( " Asteroidbig " ) As Path;

// Collision Detection
// Ship ship user control (large rectangle range)
// Path coordinates of the shell of the shipshell ship
// User Control of asteroid meteorite (large rectangle range)
// Path coordinate of the shell of cnvasteroid Meteorite
If (Checkcollision (ship, shipshell, asteroid, cnvasteroid ))
Txtstatus. Text = " Collision! " ;
Else
Txtstatus. Text = " No collision " ;
}

Private Bool Checkcollision (frameworkelement control1, frameworkelement controlelem1, frameworkelement control2, frameworkelement controlelem2)
{
// First see if sprite rectangles collide
// The user control uses canvas. Now we want to convert the canvas of the user control into a rectangle.
// Usercontrolbounds () is used to convert to a rectangle for editing.
// Rect1 is the spacecraft rectangle
// Rect2 is the meteorite rectangle
// Control1 is a ship user control (rectangle)
// Control2 is a user control (rectangle)
Rect rect1 = Usercontrolbounds (control1 );
Rect rect2 = Usercontrolbounds (control2 );

// Intersect (rect) searches for the intersection of the current rectangle and the specified rectangle, and stores the result as the current rectangle.
Rect1.intersect (rect2 );
If (Rect1 = Rect. Empty) // There is no intersection between the spacecraft and the meteorite when the sky is a rectangle.
{
// No collision-get out!
Return False ;
}
Else // It is not empty. If there is an intersection, it returns an intersection, but it does not mean that the ship will have a collision with the meteorite, and more careful judgment is required.
{
Bool Bcollision = False ; // Collision?
Point ptcheck = New Point (); // Point Detection

// Now we do a more accurate pixel hit Test
// Perform accurate Point Testing
// Cyclically scans each vertex in the rectangle in the unit of action.
// Here, rect1 is the rectangle with the intersection
For ( Int X = Convert. toint32 (rect1.x); x < Convert. toint32 (rect1.x + Rect1.width); x ++ )
{
// Traverse each vertex in a row
For ( Int Y = Convert. toint32 (rect1.y); y < Convert. toint32 (rect1.y + Rect1.height); y ++ )
{
// Add row

// Set the coordinates of the detection point
Ptcheck. x = X;
Ptcheck. Y = Y;

// Use findelementsinhostcoordinates to find the element on the point ptcheck in the spacecraft user control.
List < Uielement > Hits = System. Windows. Media. visualtreehelper. findelementsinhostcoordinates (ptcheck, control1) As List < Uielement > ;
// Controlelem1 is the actual spacecraft
If (Hits. Contains (controlelem1 )) // Hits contains all the elements in the point ptcheck in the ship user control to check whether the actual ship is in it.
{
// We have a hit on the first control ELEM, now see if the second ELEM has a similar hit
// We need to check whether the spacecraft we are detecting is in the meteorite.
// Obtain the hits from the preceding method to find the element on the point ptcheck In the meteorite control.
List < Uielement > Hits2 = System. Windows. Media. visualtreehelper. findelementsinhostcoordinates (ptcheck, control2) As List < Uielement > ;
// Controlelem2 is the actual Meteorite
If (Hits2.contains (controlelem2 )) // Hits2 contains all the elements in the point ptcheck of the meteorite user control to check whether the actual meteorite is in it.
{
// Collision is sufficient
Bcollision = True ;
Break ;
}
}
}
If (Bcollision) Break ;
}
Return Bcollision;
}


}




Public Rect usercontrolbounds (frameworkelement Control)
{
Point pttopleft = New Point (convert. todouble (control. getvalue (canvas. leftproperty), convert. todouble (control. getvalue (canvas. topproperty )));
Point ptbottomright = New Point (convert. todouble (control. getvalue (canvas. leftproperty )) + Control. Width, convert. todouble (control. getvalue (canvas. topproperty )) + Control. Height );

Return New Rect (pttopleft, ptbottomright );
}


}
}
There are few codes, but when you understand the collision principle and the core method used, you can make complicated collision detection as long as you have an idea.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.