I’ve been dealing with this problem for quite some time.
What I am trying to do is have a CCSprite’s right/left movement controlled by touches on either the left side of the screen or the right.
Doing this is no problem if you lift your finger after each touch. But what I want is best described by an example:
The player touches the left side of the screen and the sprite moves to the left. Now the player (while still touching the left side) touches the right side…the sprite should now move right. Now the player has one finger on the left and one on the right side, if he now lifts the touch off the right side the sprite should again move to the left.
This is what I have now:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
//Swipe Detection Part 1
firstTouch = location;
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//Swipe Detection Part 2
lastTouch = location;
float swipeLength = ccpDistance(firstTouch, lastTouch);
if (firstTouch.y < lastTouch.y && swipeLength > 60) {
[player jump:kkJumpUp];
} else if (firstTouch.y > lastTouch.y && swipeLength > 60){
[player jump:kkJumpDown];
}
[player endWalk];
}
I’d appreciate it if someone could tell me how to go about this. Thank you .
UPDATE MY SOLUTION:
//1. Enable multitouch in the appDelegate
[glView setMultipleTouchEnabled:YES];
//2. Create an Array to keep track of active touches
touchArray = [[NSMutableArray alloc] init];
//3. Touch Methods
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
if (![touchArray containsObject:touch]) {
[touchArray addObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"start: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
[touchArray removeObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"end: %f", location.x);
}
for (UITouch *touch in touchArray) {
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"still: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
if ([touchArray count] == 0) {
[player endWalk];
}
}
If I understand correctly your problem, what you should do is:
in
ccTouchesEnded, instead of simply callingendWalk, check to see is any touch is still present (to do so, you could iterate overallTouches);in the appropriate case (i.e., a touch is still activating the player), call
startWalk.if no touch is present, call
endWalk.The code would be similar to what you have in
ccTouchesBegan, only you iterate (I am not sure whatallTouchescontains at index 0 in touchesEnded).OLD ANSWER:
You are not saying anything about how you are handling touches right now. In any case, the way to go is defining
ccTouches*methods (vs.ccTouch*), where * can be:Began,Moved,Ended.Keep in mind that touchesBegan is fired at each new touch that is detected. So, if you want to know the status of all touches currently active, you have to use
allTouches.Have also a look at this post from iphonesdk which I found insightful as to the semantics of touches in those methods.