I got this question the other day, how to track individual touches if you are using a couple of fingers for a game?
Actually it’s pretty easy if you can access the touch previous position and it’s current position.
Let’s start with a small class to store the information
class Touch { public: Touch(); ~Touch(); void update_position(float x, float y){ _current_position.x = x; _current_position.x = y; } bool is_same_touch(float x, float y) { if(_current_position.x == x && _current_position.y == y) return true; return false; } protected: CGPoint _current_position; }; |
Let’s a assume the “move” movement
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { // Loop all touches for (UITouch *touch in touches) { // Get current position in view CGPoint touchPoint = [touch locationInView:self]; // Get previous position CGPoint prevPoint = [touch previousLocationInView:self]; // compare with your stored touch if(stored_touch->is_same_touch(prevPoint.x, prevPoint.y)) { // Do stuff with the movement // Update stored_touch->update_position(touchPoint.x,touchPoint.y); } } } |
As you can see you now have for each touch it’s current and previous position. So by storing each touch you can later compare it’s current position with the new touch old position.
elegant solution!
I tought about this method some time ago, but upon implementation it didn’t worked as expected. It seems you cannot rely on the last position, as sometimes it doesn’t match the previous position.
I found the best solution was to store the UITouch and check that the one you receive matches the one you stored, as the UITouch instance is kept alive during the entire touch. I’m still to find an error case with this method.
In order to use this method in C++ only classes I collect the info and then cast the UITouch to a void* prior to storing or passing it to my classes, and from then on using it only as a refence to compare its pointer. Of course upon finishing the TouchesEnded method, the UITouch becomes unreliable.