Search code examples
ioscocos2d-iphonespritebuilder

Make a sprite only jump once


Working with Xcode, Spritebuilder and Cocos2d, I am trying to let the players sprite only jump 1 single time. So when the player taps the screen, the sprite jumps, and only when it has landed, the player should again be able to jump again. I haven't found any clear explanations so far, so hence my question.

Here's my code

Edit so that the code only lets the sprite jump once:

static const CGFloat scrollSpeed = 0.4;
BOOL isInAir;
@implementation GameScene
{
    CCSprite *player1;
    CCPhysicsNode *physicsNode1;
    CCNode *ground1;
    CCNode *ground2;
}

- (void)didLoadFromCCB
{
    self.userInteractionEnabled = TRUE;
    grounds = @[ground1, ground2]    
}

- (void)update:(CCTime)delta
{
    // moves the player to the right
    player1.position = ccp(player1.position.x + delta * scrollSpeed, player1.position.y);

    // move the  camera with the player
    physicsNode1.position =  ccp(physicsNode1.position.x - (scrollSpeed *delta),     physicsNode1.position.y);

    // loop the ground
    for (CCNode *ground in grounds)
    {
        // get the world position of the ground
        CGPoint groundWorldPosition = [physicsNode1 convertToWorldSpace:ground.position];
        // get the screen position of the ground
        CGPoint groundScreenPosition = [self convertToNodeSpace:groundWorldPosition];
        
        // if the left corner is one complete width off the screen, move it to the right
        if (groundScreenPosition.x <= (-1 * ground.contentSize.width))
        {   
            // puts the ground piece that is about to leave the screen behind the last one
            ground.position = ccp(ground.position.x + 600, ground.position.y);
            //NSLog(@"player1 pos: %@", NSStringFromCGPoint(ground.position));
        }
    } 

    // clamp velocity
    float yVelocity = clampf(player1.physicsBody.velocity.y, -1 * MAXFLOAT, 200.f);
    player1.physicsBody.velocity = ccp(0, yVelocity);
}

- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    if (isInAir == NO)
    {
        [player1.physicsBody applyImpulse:ccp(0, 150)];
        isInAir = YES;
    }
}

- (BOOL) ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair player1:(CCNode *)player1 ground:   (CCNode *)ground
{
    NSLog(@"player is touching the ground");
    isInAir = NO;
    return YES;
}
@end

Solution

  • You can use a BOOL. Here is my code for a jump on touch:

    BOOL isInAir;//Make this global.
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        /* Called when a touch begins */
        UITouch *touch = [touches anyObject];
        SKSpriteNode *node = [self nodesAtPoint:[touch locationInNode:self]];
    
                    if (isInAir == NO)
                    {
                        CGFloat impulseX = 0.0f;
                        CGFloat impulseY = 600.0f;
                        [node.physicsBody applyImpulse:CGVectorMake(impulseX, impulseY) atPoint:node.position];
                        isInAir = YES;
                        //other stuff
                    }
    }
    

    Then when you contact ground, set isInAir to NO.