Contains Touch on Unusual sprite Texture?

We alway rectangular sprite notion everywhere.
See the below image. Assume it is my mobile screen having cocos2d0x green layer covering the screen. Now, I add a sprite, which is not rectangular but any shape.

How to see whether my touch is in white area!!
I cannot do sprite->getBoundingBox().containsPoint() because the by notion sprite are always rectangular even though its texture may not be rectangle.

Thanxx :smile:

Wait for 4.0 to arrive with its planned mesh/polygon sprite :smiley: … just kidding. Unfortunately I don’t believe there’s an out-of-box solution at hand just yet, though using the physics system would be close.

  1. You could add invisible touch nodes.
  2. You could use the physics engine and give the sprite a polygonal physics body
  3. You can look into pixel-perfect collision detection using either render textures or storing the image data in a regular byte[][] array.
  4. Other?

To start I would focus on simplicity, by either using a scaled down rect based off its boundingbox (say add 1/4 width and height to the rect.origin and multiply size by .5f), or maybe #1 or #2 if you’re using physics engine. You can always attach your own polygon or shape and do your own touch inside point detection.

@stevetranby
I took that seriously :smiley: :smiley:

Ok… even if I use the physics polygon body to that irregular shape textured sprite then how will I detect whether my touch is inside that sprite?

I can check collisions but how to check touch is my main motive of asking!!

Thanxx :smiley:

and thanx again for making my eyes glimmer with planned mesh/polygon sprite!! :smiley:

I’ll reply with a bit more, but checkout the physics test in the cocos2d-x engine test project.

Here is an iOS Objective-C method to see if a touch is inside a polygon. You can convert and use as needed.

- (BOOL)touchInsidePolygonWithPoint:(CGPoint)touch
{
    BOOL oddNodes = NO;
    
    CGFloat x = touch.x;
    CGFloat y = touch.y;
    
    // cache points for faster access
    JVPolyPoint *iPoint = nil;
    JVPolyPoint *jPoint = nil;
    CGFloat i_x, i_y, j_x, j_y;
    
    int j = polygonPointArrayCount_ -1;
    
    for ( int i = 0; i < polygonPointArrayCount_; i++)
    {
        iPoint = [polygonPointArray_ objectAtIndex:i];
        i_x = iPoint.x; i_y = iPoint.y;
        jPoint = [polygonPointArray_ objectAtIndex:j];
        j_x = jPoint.x; j_y = jPoint.y;
        
        if ((( i_y < y && j_y >= y ) || ( j_y < y && i_y >= y )) && ( i_x <= x || j_x <= x ))
        {
            oddNodes^= ( i_x + ( y - i_y ) / ( j_y - i_y ) * ( j_x - i_x) < x );
        }
        j = i;
    }
    
    return oddNodes;
}

If you go the physics route it’s probably easier to just look at the code in cpp-tests/Classes/PhysicsTest/PhysicsTest.cpp for example. Look at the code for touch handling. PhysicsDemo::onTouchBegan/Moved/Ended. They set a tag on draggable (touchable) physics bodies and then detect touches on them if the tag is set.

Otherwise @Javy has a good code to use if you setup your CustomSprite : public cocos2d::Sprite with an extra boundingPolygon. You’ll have to define the polygon points somewhere using PhysicsDesigner, or in code. This way you could also first test the boundingBox if you want as a first “pass” and then check intersection with polygon after.