Cocos2d iPhone - Sprite Non-Rectangular Touch Detector

You have a project with a TRIANGLE graphic in a sprite. I place these sprites on the grid so that their rectangles overlap. As the sprites touch, their z-order changes (by me) to place them at the top of the zOrder.

I am using Cocos 0.8.1 and touch dispatcher method. I am working, but obviously "hidden" sprites that are overlapped by other sprites cannot be touched.

The problem is that the Touch in My Rectangle method is based on the sprite rectangle, but the image is a triangle, and I would like to ask if anyone knows a Coconut compatible method to check if the image itself is being hit.

I seem to remember that this was a popular testing method for testing the same day, but I cannot find any link on how this can be done on Cocos / iPhone Land.

The goal is to only respond to touches when a pixel in the image is touched, not just the rectangle containing the sprite.

+2


source to share


3 answers


Instead of testing the box, you can of course test whatever shape you want.

I originally posted you can use NSBezierPath, but apparently this is not available with iPhones, only on Macs. On iPhone, you can use CGPath instead.

Create a new path using CGPathCreateMutable()

which returns const CGPath *

(also known as CHPathRef


Then use CGPathAddRect

or CGPathAddLines

to create our path.
CGPathContainsPoint

Will check if your point was in shape.

Alternatively, you can create a client function that (since you are using triangles) just does a simple calculation to check if your point is inside the triangle shape. A bit of math should do the trick (although when you rotate the shape it gets a bit tricky. I write a bit since you can just rotate the touch point relative to the origin and detect a hit)

For a triangle:

   C
  /\
 /__\
A    B
point of touch is P

      



With the following algorithm, you will 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 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 side BC

return true; // the point must be in the triangle, so return true.

      

The above is coded dry but should be correct.

The above only works against the triangle in the shape when I drew it (where Cx is between Ax and Bx and A and B are at the same height but below C). You can of course change this to test any shape, however you should weigh it against using it only CGPath

.

If you don't understand this, or if this is a bug, please let me know!

+4


source


I found this great tutorial which explains how to use two great and indispensable utilities along with Cocos2d and Box2d to detect conflicts (you can also use Chipmunk). You can use them to configure your program for touch detection in the same way it detects collisions.

http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone

Here's a link to Zwoptexapp - Helps to set up plist files for sprites / sprites.

http://www.zwoptexapp.com/



Here's a link to VertexHelper - lets you 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 and the Ray Tutorials have been very helpful to me. Hope they help you too!

+1


source


I've seen several slice editing tools, including one offered by developer Cocos2D, which allows you to use a Bezier curve to directly delineate an accurate image versus a rectangle. When used with Box2D Physics, it seems very simple according to the video tutorials and examples I've seen on the Cocos2D site and youtube. Google Tile or Map Editor and Cocos2d on youtube, it should show you a few tools that you could use and there would be no need to program any complex geometric collision - it should be WYSIWYG.

Greetings,

Matthew

0


source







All Articles