Detect which sprite user touched

Hello,

I have background sprite and player sprite and both are physics object…Player sprite is above the user sprite…

I want to determine which physics object user touched?

my ontouchmethod -

if(playerSprite->getBoundingBox().containsPoint(location))
{
  log("touched player");
}

if(back->getBoundingBox().containsPoint(location))
{
        log("touched background");
    
}

But when i touch the player sprite both sprites are touched…So how to prevent this…

My Log is : touched background
touched player

In this case you could just add an else to ensure the player is always picked over the background.

if(playerSprite->getBoundingBox().containsPoint(location))
{
  log("touched player");
}
else if(back->getBoundingBox().containsPoint(location))
{
        log("touched background");
}

However a better approach would be store your objects by priority and test them in order

Off the top of my head this might look something like:

//map of node lists where key represents priority. 
//Lower the key higher the priority. 
//std::map is implicitly sorted.
std::map<int, std::vector<Node*>> touchables;
touchables[0].push_back(player);
touchables[1].push_back(background);

Node* getTouched(const cocos2d::Vec2& location, const std::map<int, std::vector<Node*>>& touchables)
{
   for(auto it : touchables)
   {
      auto& priorityList = it->second;
      for(auto& node : priorityList)
      {
         if(node->getBoundingBox().containsPoint(location))
         {
            return node;
         }
      }
   }
}

Hope this helps

1 Like

Thanks man, it worked…

What i am trying to achieve is, i have a background and when i touch the background a sprite(player) is created and placed in that position, and when i touch the player i want to redirect it to new scene depending on the tag of the player…

So i am giving tags to each sprite that is created when user touch the background, like this - .

if(tSprite->getBoundingBox().containsPoint(location))
{
    
    log("touched %i" ,tSprite->getTag());
    
  // some code to redirect it to new scene 5 , if tag 5 is found..
           
}

else if(fback->getBoundingBox().containsPoint(location))
{
    log("back touched");
    tSprite = Sprite::create();
    tSprite->setTexture("player.png");
    tSprite->setPosition(Point(touch->getLocation().x + origin.x, touch->getLocation().y + tSprite->getContentSize().height/2 + origin.y));
    tSprite->setTag(i);
    i++;
    this->addChild(tSprite);
  
}

If i touch 5 times, five player are created at different location, and when i touch those player only the last created player is logged, touch is unable to detect all previously created players and log its tags…

Log output - touched 5

When i touch previously created players, it doesnt get selected and does not log the tag of that player…

What is wrong here? plz help…

ermmm, is tSprite a class variable?

If so, every time you create one you’re writing over your reference to the last.

Put them in a list so you can test all created sprites:

cocos2d::Vector<Sprite*> m_sprites; //class variable

bool spriteTouched = false;
for(auto& sprite : sprites)
{
    if(sprite->getBoundingBox().containsPoint(location))
    {
        log("touched %i" ,sprite->getTag());
        spriteTouched = true;
        break; //we found one so exit the loop
    }
}
//if no sprites were touched we should test the background
if(spriteTouched == false)
{
    if(fback->getBoundingBox().containsPoint(location))
    {
        log("back touched");
        auto sprite = Sprite::create("player.png");
        sprite->setAnchorPoint(0.5f,0.0f);
        sprite->setPosition(origin + touch->getLocation());
        sprite->setTag(m_sprites.size()); //tags will be in range (0,n-1)
        m_sprites.pushBack(sprite);
        this->addChild(sprite);
    }
}

although you’re much better off taking the prioritised map approach, it’s much more flexible when you start adding more and more objects types to your scene.

1 Like

thanks a lot, great solution… Liked the prioritised map approach, learned something new…