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…