objective-ciphonecocos2d-iphoneccspritecocos2d-iphone-3

Cocos2D v3 CCParallaxNode scrolling can't keep player in focus


I am very fresher to game development and I need to develop a game like NinjaJump.

I have created a CCParallaxNode to setup scrolling background and added CCPhysicsNode to setup Physics world. I have created player object as shown below.

// Add a sprite
    _sprite = [CCSprite spriteWithImageNamed:@"Icon.png"];
    _sprite.position  = ccp(self.contentSize.width/2,100);
    _sprite.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){CGPointZero, _sprite.contentSize} cornerRadius:0.0];
    _sprite.physicsBody.friction = 0.0f;
    _sprite.physicsBody.collisionGroup = @"player";
    _sprite.physicsBody.collisionType = @"Player";
    //_sprite.physicsBody.collisionMask = 0;
    //[self addChild:_sprite];
    [foreground addChild:_sprite];

foreground is just a node added into CCScene to easily manage player in-focus.

// code for physics world
_physicsWorld = [CCPhysicsNode node];
    _physicsWorld.gravity = ccp(0,-100);
    _physicsWorld.debugDraw = YES;
    //_physicsWorld.collisionDelegate = self;
    [self addChild:_physicsWorld];

    _foreground = [CCNode node];
    //[self addChild: _foreground];
    [_physicsWorld addChild: _foreground];

To make player always visible we have implemented update method as

- (void) update:(CFTimeInterval)currentTime {
    // Calculate player y offset
    if (_player.position.y > 200.0f) {
        //_midgroundNode.position = CGPointMake(0.0f, -((_player.position.y - 200.0f)/4));
        _foreground.position = CGPointMake(0.0f, -(_player.position.y - 200.0f));
    }
}

I can't understand but the player scrolls off screen anyhow. The code is written in Cocos2d v3.

I have also setup a demo project to show what I implemented: https://www.dropbox.com/s/5s55d00kk80wun4/HumptyJump-Example.zip?dl=0

Any kind of help is appreciated. Thanks in advance.


Solution

  • I have implemented 2 fixed views changing their positions while physics body goes down ;).

    See the same in action

    @interface TestScene () {
        CCNode *_background;
        CCNode *_foreground;
    
        NSArray *grounds; // Keeps track of each of the 2 views
        CCPhysicsNode *_physicsWorld;
    }
    
    @implementation TestScene
    
    - (id)init {
        self = [super init];
        if (!self) return(nil);
    
        // Enable touch handling on scene node
        self.userInteractionEnabled = YES;
    
        // Physics world setup
        _physicsWorld = [CCPhysicsNode node];
        _physicsWorld.gravity = ccp(0,-100);
        _physicsWorld.debugDraw = YES;
        _physicsWorld.collisionDelegate = self;
        [self addChild:_physicsWorld];
    
        // Foreground node in which platforms are there and moves downwards as player goes up
        _foreground = [CCNode node];
    
        // Adding background images
        CCSprite *default1 = [CCSprite spriteWithImageNamed: @"Default.png"];
        [default1 setAnchorPoint: ccp(0, 0)];
        CCSprite *default2 = [CCSprite spriteWithImageNamed: @"Default.png"];
        [default2 setAnchorPoint: ccp(0, 0)];
        [default2 setPosition: ccp(0, default1.contentSize.height)];
        [_foreground addChild: default1];
        [_foreground addChild: default2];
    
        // Adding into array
        grounds = @[default1, default2];
        // Adding into physics world
        [_physicsWorld addChild: _foreground];
    
        // creating player
        _player = [CCSprite spriteWithImageNamed: @"Assets.atlas/Player.png"];
        [_player setPosition: ccp(160.0f, 160.0f)];
        _player.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){CGPointZero, _player.contentSize} cornerRadius:0]; // 1
        _player.physicsBody.collisionGroup = @"playerGroup"; // 2
        _player.physicsBody.collisionType = @"player";
        //[_physicsWorld addChild:_player];
        [_foreground addChild: _player];
    
        // Multiple platforms can be added into body, they are static entities only
        PlatformNode *platform = (PlatformNode *)[PlatformNode node];
        [platform createPlatformAtPosition:CGPointMake(110, 50) ofType: PLATFORM_NORMAL];
        [_foreground addChild: platform];
    
        return self;
    }
    
    - (void) update:(CFTimeInterval)currentTime {
        // Take background and physics world down, 163 was Y position of the player
        _physicsWorld.position = ccp(_physicsWorld.position.x, 163 - _player.position.y);
    
        // loop the ground
        for (CCNode *ground in grounds) {
            // Get the world position
            CGPoint groundWorldPosition = [_physicsWorld convertToWorldSpace: ground.position];
            // Get screen position
            CGPoint groundScreenPosition = [self convertToNodeSpace: groundWorldPosition];
            NSLog(@"Positioning ground ---> world: (%f, %f) & screen: (%f, %f)", groundWorldPosition.x, groundWorldPosition.y, groundScreenPosition.x, groundScreenPosition.y, nil);
            if (groundScreenPosition.y <= -ground.contentSize.height) {
                ground.position = ccp(ground.position.x, ground.position.y + 2 * ground.contentSize.height);
                break;
            }
        }
    }
    
    -(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
        // Take the player upside
        [_player.physicsBody applyImpulse: ccp(0, 215)];
    }
    
    @end
    

    This is how I coded the background :).