I have a game in which the player moves around a sprite by tapping on various sections of the screen (left, right, up, down). So far, each tap moves the sprite one tile (I use a tile system for movement, among other things), so to move the sprite a long distance the player has to tap in the direction they want for a while. Is there a way to combine a tap gesture recognizer and a long hold gesture recognizer so that if the player taps once, the sprite moves one tile in the direction tapped and if the player holds, the player moves in that direction until the player stops holding?

Here's my code for a single direction just as an example of what I have:

-(void)handleRightTap {

    self.player.direction = RIGHT;
    float currentSpriteX = self.playerSprite.center.x;
    float currentSpriteY = self.playerSprite.center.y;

    //If the animation is not already happening and the destination is accessible...
    if(!self.isAnimating && self.toTile.isWalkable) {
        self.isAnimating = YES;    

        //If the player has reached the edge of the screen...
        if([self checkIfPlayerHasReachedEndForPoint:toPoint]) {        
            self.isAnimating = NO;
        CABasicAnimation *moveAnimation = [CABasicAnimation animation];
        moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(currentSpriteX + TILE_WIDTH, currentSpriteY)];
        [moveAnimation setDelegate:self];
        [moveAnimation setFillMode:kCAFillModeForwards];
        [moveAnimation setRemovedOnCompletion:NO];
        [moveAnimation setDuration:MOVE_ANIMATION_DURATION];
        [self.playerSprite.layer addAnimation:moveAnimation forKey:@"position"];

The way to deal with this is to set a timer once the person taps the phone. The most user friendly scenario that you'd implement would look something like this:

  1. When you detect a tap, set a timer (t = timeToRepeat)
  2. On each frame, decrease the timer by dt
  3. If the timer reaches zero, move the sprite a tile and reset the timer
  4. If the user releases their finger before the first cycle of the timer, move the sprite one tile

Obviously the amount of time that you set your timer to will determine how fast your sprite moves. There are a few variations on this theme depending on the kind of behavior you want as well. For example, you can move the sprite once immediately upon detecting a tap and ignore step #4.

  • \$\begingroup\$ I like this way of accomplishing my goal, but I was wondering if there was a way of doing it that was part of Cocoa. \$\endgroup\$ – pasawaya Apr 28 '13 at 16:27
  • \$\begingroup\$ Perhaps you are looking for UILongPressGestureRecognizer and UITapGestureRecognizer... The logic to get your desired behavior will be similar, however. \$\endgroup\$ – Mokosha Apr 29 '13 at 14:49
  • \$\begingroup\$ Thank you so much. I implemented this logic today and it worked out fine. \$\endgroup\$ – pasawaya May 3 '13 at 5:26

Measure the time between the user started to touch the screen and until he release it. If the measured time is below a certain threshold ( 1 sec?! ) it's a tap, otherwise it's a long hold.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.