CCParallaxNode adding childs while scrolling - cocos2d-iphone

I'am using a CCParallaxNode to scroll 3 backgrounds along with Ray Wenderlich's category to move the backgrounds when they go out of the screen.
It is working just fine, my problem is that i want to add childs (enimies) on the fly, like every 5 seconds. Normally i would just add the enemies to the parent layer using a CCMoveTo action to animate him over the screen but I want my enimies to follow the foreground of the parallax layer.
I'am increasing the scroll speed slowly as the game progresses.
I can't seem to figure out the right offset when calling
CGFloat offset = self.gameBackground.position.x;
[self.gameBackground addChild:enimy z:5 parallaxRatio:ccp(0.1, 0.1) positionOffset:ccp(offset, 85)];
Can someone help me out with this?
edit:
I'am doing this to move the background:
- (void)update:(ccTime)delta
{
self.speed -= 0.5f;
CGPoint backgroundScrollVel = ccp(self.speed, 0);
self.gameBackground.position = ccpAdd(self.gameBackground.position, ccpMult(backgroundScrollVel, delta));
}
Thanks
Rays article: http://www.raywenderlich.com/3611/how-to-make-a-space-shooter-iphone-game
Final solution:
I ended up just adding the enimies to the CCLayer instead of the Parallax. To move the enimies in the same speed as the foremost layer child in Parallax i did the following:
in update:(ccTime)delta:
CGFloat parallaxRatio = 0.1f;
CGPoint backgroundScrollVel = ccp((self.backgroundSpeed * - 1) * parallaxRatio, 0);
for(WKEnimy *enemy in self.enimies)
{
enemy.position = ccpAdd(enemy.position, ccpMult(backgroundScrollVel, delta));
}

You could add your enemy CCSprites to your foreground CCLayer (instead of directly adding them to your CCParallaxNode). Besides, I wouldn't recommend using actions (such as CCMoveTo) for this particular case; you may update your sprites positions as your doing with your gameBackground, and 'manually' check wether or not they're off the screen.

Related

Cocos2D: CCPhysicsNode and child sprite move with different speed

I'm following the tutorial here to mimic Flappy Bird. At the part to scroll the game scene:
- (void)update:(CCTime)delta {
_hero.position = ccp(_hero.position.x + delta * scrollSpeed, _hero.position.y);
_physicsNode.position = ccp(_physicsNode.position.x - (scrollSpeed *delta), _physicsNode.position.y);
...
}
Ideally the whole world will scroll left, and _hero (which is a child node of _physicsNode) move right with the same speed it would stay still on the screen. But when I run the code on simulator the _hero sprite just blast off to the right at the speed of light (about 10~20 times faster than the scrolling speed of _physicsNode). The _physicsNode and every other things inside it is scrolling left at normal speed as intended.
If I don't give _hero any movement it would scroll along with _physicsNode normally.
I have tried other method like using CCAction at game start:
CCAction *moveAction = [CCActionMoveBy actionWithDuration:1 position:ccp(-scrollSpeed,0)];
CCActionRepeatForever *repeatAction = [CCActionRepeatForever actionWithAction:(CCActionInterval *)moveAction];
[_physicsNode runAction:repeatAction];
And still get the same result. The speed value that _hero receive is always different from the speed that _physicsNode receive.
Could anyone explain to me why this is happening and how to fix it?
I'm using cocos2d 3.3 if it helps.
I finally figured it out.
The _hero node had its positionType set to CCPositionTypeNormalized (because I was trying to center him on the screen) while the _physicNode has its positionType as CCPositionTypePoints. Any change to the node's position (including movement actions) are based on the node's positionType. The result is that when I move the _hero node by 2, it doesn't move 2 points but 2% of the parent node's width instead.
I fixed it by aligning the _hero on SpriteKit using CCPositionTypeNormalized, then switching it to CCPositionTypePoints at game start.

Zooming in and out of Scene in Cocos 2D-X 3.2

I'm pretty new to Cocos 2D-X but have some decent background in C++. I have a sprite _rocket (tied to a Box2D body) that occasionally moves outside the visible view of my screen. I'd like for the view to automatically zoom out as the sprite approaches the edge of the screen, so that the sprite is always in the view. When the sprite returns to the original view frame, the view should scale back to its original size.
I was able to zoom out with the following code in the update function:
Size winSize = Director::getInstance()->getWinSize();
if ((_rocket->getPosition().x - _rocket->getContentSize().width/2 < 10.0) ||
(_rocket->getPosition().x + _rocket->getContentSize().width/2 > winSize.width - 10.0) ||
(_rocket->getPosition().y - _rocket->getContentSize().width/2 < 10.0) ||
(_rocket->getPosition().y + _rocket->getContentSize().width/2 > winSize.height - 10.0))
{
this->setScale(this->getScale()-0.005);
}
However, because winSize isn't updated, this essentially scales forever, until the sprite returns to the original view. I am not sure how to update winSize so that it can be used iteratively to find the screen's edge. There may also be a much easier way of approaching this.
i don't understand why the winSize should change.
if you mean the _rock's contentsize not change
you should use
auto size = _rocket->getBoundingBox().size;
They removed some useful camera functions in cocos2d-x 3.+
The workaround is to scale/move the layer containing the game instead of trying to move the camera.

Side scrolling game background

I am working in Cocos2d and xcode to create a side scrolling game.
I have an issue with my coding for adding a background to the levelscene.
I tried to implement a parallax background to no avail so have opted to just have a background the player will scroll across.
But at the moment the background follows the player across the screen, which frankly looks rubbish.
The code I have is
(void)setupParallax {
NSString *backgroundName = [self.tilemap propertyNamed:#"BackgroundImage"];
CCSprite *background = [CCSprite spriteWithFile:[AssetHelper getDeviceSpecificFileNameFor:[NSString stringWithFormat:#"background-noon.png]]];
background.anchorPoint = ccp(0,0);
background.position = CGPointMake(0, 0);
[self addChild:background z:0];
}
I know it must be something with either the position or anchorPoint but these values only change with reference to the screen they are loaded on.
Have you looked at this tutorial on doing parallax scrolling in cocos2d-x?
You an do parallax scrolling by hand...but it will probably easier, at least if you are just starting out, to do it using the CCParallaxNode and let the framework do the heavy lifting for you.

Stars for scrolling shooter with CCParticleSystemQuad?

My code for init function:
NSArray *starsArray = [NSArray arrayWithObjects:#"Stars1.plist", #"Stars2.plist", #"Stars3.plist", nil];
for(NSString *stars in starsArray) {
CCParticleSystemQuad *starsEffect = [CCParticleSystemQuad particleWithFile:stars];
[self addChild:starsEffect z:-1];
}
The problem is that these particles appear and fully fill the screen rectangle during few seconds. But I need the sky full of stars from the beginning.
According to the answer at cocos2d starting particles from a specific time in the future , you can manually update the particle system. Example in cocos2d-x:
CCParticleSystemQuad *particle = CCParticleSystemQuad::create("res/Particles/Stars1.plist");
for (int i = 0; i < 10; ++i) {
particle->update(.1);
}
You may need to change the interval to suit the particles.
Add them to a layer, hide the layer, then unhide the layer after everything is done loading. That way you can set stuff up and not have it display right away.
That's just one approach. Another idea is to load all your images into Cocos before game play and game logic processes begin. That way there is no pause and delay while images are loading.

Cocos2d iPhone. Scrollayer contentSize. Layers

I want to set the contentsize of scrollayer.
I have a scrollayer, it's CCLayer type and moving is set by ccTouchMove. I have one schedule for smoothing. BUT.
Problem is that scrolling layer is big like the whole display. I want to set the contentsize of scrollayer. Content in this layer will be scroll and showing ONLY in this layer. Not taking up the whole display. Something like this
Scrolling just in gray CCLayer (scrollayer) ....NOT WHOLE SCREEN.
Can you help me?
P.S.: Setting CCLayerColor and initWithColor:Width:Height: is not working. It just makes some stupid color box and it's moving too.
ok, honestly i would put the window frame at a higher z than the scrolling object ... if you dont you may have to crop and change sprite on the fly for the window content, nasty (at least that is the one way i could do this, without further research).
so :
// initialize this logic somewhere useful
CCNode scrollableContent;
CCSprite windowFrame;
BOOL isScrollPossible;
[self addChild:scrollableContent z:0];
[self addChild:windowFrame z:1];
// and in the touch delegate methods
-(void) ccTouchBegan:{
check if the touch happened in the window, if yes, scrolling is possible
}
-(void) ccTouchMoved:{
if (isScrollPossible) {
compute displacement
compute nextPosition for scrollableContent node;
if ( nextPosition in window ) {
// make scrollableContent follow touch
scrollableContent.position=nextPosition;
} else {
// stop any further scrolling until the next 'touch began'
isScrollPossible=NO;
}
} else {
// scroll not possible, do nothing
}
}
This is the basic idea. You may need clamping logic to prevent the creeping of scrollableContent beyond the edges of the window.
Edited for typos.
After trying desperately with masking and GL_SCISSOR, I settled on cutting a hole in the foreground and only moving the background object when onTouchMoved updated.
To see it in action, have a look at the Stats page of Angry Gran.