Getting touched sprites

Hi there,

just for clarification. I am working on a puzzle game like CandyCrush or TwoDots if you want and I was wondering if I am handling the touched sprites right.

What I do ->
I have a subclass of Sprite called GameTile. In the GameScene I create those GameTiles and add them to the layer. Standard procedure I guess.

GameTile* tile = GameTile::create(1);
tile->setPosition(Vec2(10, 10));
this->addChild(tile);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, tile);

GameTile* tile2 = GameTile::create(2);
tile2->setPosition(Vec2(20, 20));
this->addChild(tile2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), tile2);

I am wondering if I have to add the last line (_eventDispathcer…) for every Tile I am adding. The game has about 64 tiles per level.

This is for example how I get the touched GameTile

void GameScene::onTouchMoved(Touch *touch, Event *event)
{
     auto target = static_cast<GameTile*>(event->getCurrentTarget());

    Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
    Size s = target->getContentSize();
    Rect rect = Rect(0, 0, s.width, s.height);

    if (rect.containsPoint(locationInNode)) {
        CCLOG("%s", target->getName().c_str());
    }    
}

The “problem” here is that if I set swallowTouches true, only the last added sprite gets touched. In this case it would be GameTile2.

Thanks guys,
proudcastle

onTouchBegan is used to determine which node is touched. You should detect if a node is touched in there and return true if it is and false if it isn’t. Once you have done this, the correct node should always get the call to onTouchMoved.

Basically, rename your onTouchMoved function to onTouchBegan, because you are pretty much doing what needs to be done in there.

@grimfate

But some problem is here.
This will let player to touch multiple sprites together.
So, if he is making something like Two Dots or candy crush then if he is making one sequence at a time then he will also be able to make another and n number of sequence at the same time which the developer may not want.

So, how to avoid it. Can you tell us please?

Thanxx :smile:

Not sure if you mean you will be able to touch multiple sprites with a single touch, or multiple sprites with multiple touches.

If you set swallowTouches to true, each touch will only be assigned to one node. So whichever node returns true in onTouchBegan will get the calls to onTouchMoved for that touch.

If you mean you will be able to touch something with 1 finger and then something else with another finger, I am not sure the best way to handle this but what I do is I check the ID of the touch in onTouchBegan and if it isn’t 0, then I return false. So:

if (touch->getID() != 0) return false;

When you touch the screen, the first touch has an ID of 0. The next has an ID of 1. So if you ignore touches that don’t have an ID of 0, then the will only respond to 1 touch at a time.

Oh great… yes, I am asking the latter one which is actually single touch implementation but multiple sprite with multiple touches is what creates the trouble…

So, that is nice that I cannot check touch->getId().

Thanks a lot :smile:

Oops… I meanst I can check it :wink:

@grimfate Thank you very much. The code above is just a minimal sample but I wanted to make sure I am handling the touches right. Which I think I do now.

@code_game_chef If I understand your problem correct. What I do is I simply check the rows and colums of each GameTile and only connect them if they are direct neighbors. That way your second finger can never make a sequence itself somewhere else on in the level.

But what if I touch 2 different tiles at 2 different position and start making that sequence at both the places?
And in fact I’ve defined just one array to store that sequence in my code.
So, this will create some problem, don’t know what.

So, it is better to check whether I am noting touchMoved and touchEnded only for that first touch who id it 0. This is what suggested by @grimfate

Thanxx

You mean at the exact same time? I don’t think that this is even possible. First touch marks the initial GameTile. Then you have to move the touch to connect the GameTiles. If you didn’t end that touch you can’t begin a new touch. At least that is what I am doing.

onTouchBegan -> sequenceInitiated = true; add first GameTile to array
onTouchMoved -> if (sequenceInitiated) {connect stuff}
onTouchEnded -> sequenceInitiated = false; do some game stuff; clear array

See this problem even grimfate feels.

EXACT PROBLEM

Also, yes, exact same time is extremely rarely possible for touches but yes, even if you have not ended your first sequence and whenever(even after 1 min. can do but don’t raise your first finger while in the middle of the first sequence) you want to touch a tile at some other place and start making the sequence with the other finger then if you’re not handling this explicitly, then at both the places your sequence will start creating theoretically. But technically, it won’t happen!! Why?
Because you’ve just one array to hold that sequence so either of those sequence will get stored. So, in your case depending upon your implementation it might have implemened acccidentally without making you realize otherwise second possibility is that your second sequence might overright first sequence in the array giving you unexpected results which is why I am raising concern and grimfate is understanding this problem that is why he gave solution to me…
The second sequence is allowed to be created theoretically because you’ve attached touch event to every sprite individually.

I hope this touchbegan is related to the one which is attached to tiles and not the layer?
Otherwise, this issue you won’t realize on iOS but on android for sure!!