Have a project with a TRIANGLE shaped graphic in a sprite. I am arranging these sprites in a grid so that their rectangles are all overlapping. As sprites get touched their z-or
I found this great tutorial that explains how to use two wonderful and indispensable utilities along with Cocos2d and Box2d to detect collisions (you could similarly use Chipmunk as well). You could use them to setup your program to detect touches in the same way he detects collisions.
http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone
Here's the link to Zwoptexapp - Helps you setup the plist files for your sprites/spritesheet.
http://www.zwoptexapp.com/
Here's the link to VertexHelper - Allows you to trace the outline of your sprite and then translates the outline into code that you can paste into your project and use with Box2d, Chipmunk, etc.
http://www.springenwerk.com/2010/02/introducing-vertexhelper-for-box2d.html
I am still learning Cocos2d and Box2d myself and Ray's Tutorials have been immensely helpful to me. I hope they help you too!
I have seen several tile editor tools out there including the one offered by the developer of Cocos2D that allows you to use a bezier curve in order to directly outline the exact image versus the rect. When using with Box2D Physics this seems super simple as per the video tutorials and examples I saw on the Cocos2D site and youtube. Google Tile or Map Editor and Cocos2d on youtube it should show you a few tools you could use and there would not be any need to program any complicated geometric collision - should be WYSIWYG.
Cheers,
Matthew
Instead of testing against a box you can of course test against any shape that you wish.
I initially posted you can use an NSBezierPath, but appearantly that ins't available on the iPhone kit, only on Macs. Instead, on the iPhone you can use CGPath.
Create a new path by using CGPathCreateMutable()
which returns a const CGPath *
(also known as CHPathRef
Then use CGPathAddRect
or CGPathAddLines
to create our path.
CGPathContainsPoint
will test if your point was in the shape.
Alternatively, you can create a customer function that (since you use triangles) just does a simple calculation to check whether your point is inside the triangle shape. Bit of math should do the trick (though when you rotate the shape it'll be slightly more complicated. I write slightly, as you can then just rotate the touch point relative to the shape's origin and do the hit detection)
For a triangle:
C
/\
/__\
A B
point of touch is P
With the following algorithm you should be able to find the touch:
/* first test against a box, for performance */
if( P.y > C.y || P.y < A.y || P.x < A.x || P.X > B.x )
return false; // false if P falls outside "the box"
/* then check if its within the shape */
/* split the triangle into 2 parts, around the axle of point C */
if( P.x < C.x ) // if the x value of point P is on the left of point C
if( P.y > ((C.y -A.y) / (C.x - A.x)) * P.x )
return false; // the point is above the triangle's side AC
else // if the x value of point P is greater than or equal to point C
if( P.y > C.y - ((C.y - B.y) / ( B.x - C.x )) * ( P.x - C.x ) )
return false; // the point is above the triangle's side BC
return true; // the point must be in the triangle, so return true.
The above is dry coded, but should be correct.
The above only works against a triangle in the shape as I drew it (where C.x is between A.x and B.x, and A and B are on the same height, but below C). Of course you can modify this to test against any shape, however, you have to weigh this against just using the available CGPath
.
If you don't get it, or if it's faulty, let me know!