I wouldn't bother with pixel-perfect collision if you only need to detect clicks on triangles and circles.
For circles you can use a basic distance check from the center of the button.
if ( radius >= Math.sqrt( Math.pow( clickX - centerX, 2 ) + Math.pow( clickY - centerY, 2 ) ) )
// we have been clicked
And for triangles you can use a point-in-triangle test. If you have a triangle with vertices A, B, and C:
* Return true if p1 and p2 are on the same side of BA
public static boolean SameSide(Vector2 p1, Vector2 p2, Vector2 A, Vector2 B)
// Convert points to Vector3 for use the Cross product, which is Vector3-only
Vector3 cp1 = Vector3.Cross(new Vector3(B-A, 0), new Vector3(p1-A, 0));
Vector3 cp2 = Vector3.Cross(new Vector3(B-A, 0), new Vector3(p2-A, 0));
return Vector3.Dot(cp1, cp2) >= 0;
* Return true if the point p is in the triangle ABC
public static boolean PointInTriangle(Vector2 p, Vector2 A, Vector2 B, Vector2 C)
return SameSide(p,A, B,C) && SameSide(p,B, A,C) && SameSide(p,C, A,B);
There is also the Barycentric technique, which increases computational efficiency at the expense of clarity. XNA provides a
Vector2.Barycentric method which can help alleviate that issue.