views:

1134

answers:

3

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-order is being changed (by me) to put them on the top of zOrder.

I am using Cocos 0.8.1 and the touch dispatcher method. I have touches working but obviously the "hidden" sprites which are overlapped by other sprites are not able to be touched.

The problem is that the "Is the touch in my rect" method is based on the rectangle of the sprite, but the image is a triangle, and I would like to ask if anyone knows a Cocos-friendly method of testing whether the image itself is being hit.

I seem to remember this was a popular method of hit testing back in the day but I can't find any reference to how it might be done in Cocos/iPhone Land.

The goal is to only respond to touches when an image pixel is touched, not just the rect containing the sprite.

A: 

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

TouchGameDev
+1  A: 

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!

nash
A: 

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!

Mark7777G