cocos2d addChild fails every second time - iphone

I have a small game that works perfectly when compiling, howevery every second time I
compile it, it gives me the error:
-(void) addHeroCar{
CGSize screenSize = [CCDirector sharedDirector].winSize;
sprite = [CCBodySprite spriteWithFile:#"carNew.png"];
sprite.world = self;
sprite.physicsType = kDynamic;
sprite.collisionType = kBoxCollisionType;
sprite.collidesWithType = kBoxCollisionType | kWallCollisionType;
sprite.position = ccp(screenSize.width / 2, [sprite boundingBox].size.height / 2);
sprite.density = 0.7f;
sprite.friction = 0.3f;
[sprite addBoxWithName:#"box"];
[self addChild:sprite z:1 tag:HERO_TAG];
sprite.fixed = YES;
}
and the debugger shows me the following errors:
-(void) addChild: (CCNode*) child z:(int)z tag:(int) aTag
{
NSAssert( child != nil, #"Argument must be non-nil");
Im using a cocos2d + box2d wrapper from an other developer, just FYI.
Any suggestions?
Regards,
Mirza

Related

How to set two different splash screen in cocos2d v3.x in ios

I'm working with the cocos2d 3.x and Xcode 5.1.1.I'm having two images image1.png and image2.png.In my game i already change the default image (splash screen) to my image(image1.png).Here i need to display image1.png for 2 seconds and the image2.png to display for next 3 seconds as a splash screen of my game...Thanks in advance..
This is how i do this (to fade in and out a logo, after the default image has been served by iOS. I have a SplashLogo class (a scene). It is my startup scene, it puts up the logo, fades it out, then replaces itself as the running scene with my game controller.
- (void)onEnter {
[super onEnter];
self.positionType = CCPositionTypePoints;
// todo : test this background seed, GL side effects, timing, etc ...
// [self performSelectorInBackground:#selector(seedGameSequencer) withObject:nil];
[self seedGameSequencer];
CCColor *color = [CCColor colorWithRed:0 green:0.f blue:0.f alpha:0.f];
CCNodeColor *black = [CCNodeColor nodeWithColor:color];
black.positionType = CCPositionTypePoints;
black.position = ccp(0, 0);
black.anchorPoint = ccp(0, 0); // bottom left
[self addChild:black];
[GESprite mediumPixelFormat];
CCSprite *logo = [CCSprite spriteWithImageNamed:#"maxPowerStudiosLogo.png"];
logo.positionType = CCPositionTypePoints;
logo.anchorPoint = ccp(.5, .5);
logo.opacity = 0;
logo.positionInPoints = ccp(black.contentSizeInPoints.width / 2, black.contentSizeInPoints.height / 2);
[GESprite defaultPixelFormat];
id fadein = [CCActionFadeIn actionWithDuration:3 * K_FADE_TIME];
id taponne = [CCActionDelay actionWithDuration:.95];
id fadeout = [CCActionFadeOut actionWithDuration:2 * K_FADE_TIME];
id swapSceneAction = [CCActionCallFunc actionWithTarget:self selector:#selector(swapScene)];
id seq = [CCActionSequence actions:fadein, taponne, fadeout, swapSceneAction, nil];
// add the label as a child to this Layer
[self addChild:logo];
[logo runAction:seq];
}
- (void)seedGameSequencer {
mainScene = [MPGameSequencer scene];
}
- (void)swapScene {
[[CCDirector sharedDirector] replaceScene:mainScene];
}
and in AppDelegate :
- (CCScene *)startScene {
// This method should return the very first scene to be run when your app starts.
return [SplashLogo scene];
}

Apply Angular Impulse

Here is my code for the player and the ball that interact with each other. What I want to do is to apply force to the ball like if my player is shooting it. I want the ball to move away from my player with force. how can I apply Impulse or force to this. I have tried many times but I am a newbie with Sprite Kit.
- (void) Player {
_Player = [SKSpriteNode spriteNodeWithImageNamed:#"player1"];
_Player.xScale = 0.09;
_Player.yScale = 0.09;
_Player.position = CGPointMake(self.size.width/4, self.size.height/2);
_Player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_Player.size];
_Player.physicsBody.dynamic = NO;
[self addChild:_Player];
}
- (void) TheMethodForBall {
SKSpriteNode *sprites = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
sprites.xScale = 0.19;
sprites.yScale = 0.19;
sprites.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:sprites.size];
sprites.physicsBody.dynamic = YES;
sprites.physicsBody.affectedByGravity = NO;
sprites.physicsBody.allowsRotation = YES;
sprites.physicsBody.restitution = YES;
sprites.physicsBody.angularVelocity = 4;
sprites.physicsBody.usesPreciseCollisionDetection = YES;
[self addChild:sprites];
}
I think you want to apply an impulse like a kick ?
You need the following, maybe when you touch the screen / or a button
[_myBall.physicsBody applyImpulse:CGVectorMake(somePowerX, somePowerY)];
Here is another post that will help get you started
Also, this is a good tutorial for beginners.

Parallax Scrolling for the Endless Game background using cocos2D

I am newbie programmer in cocos2D.... I wanted to create the Endless Background using the Parallax Scrolling.. I am trying to learn the Parallax but it doesn't update with the time and sprites doesn't keep on rotating from top to bottom! The snippet i tried is as below
-(id) init
{
if((self = [super init]))
{
CGSize wSize = [CCDirector sharedDirector].winSize;
self.isTouchEnabled = YES;
CGPoint topOffset = CGPointMake(wSize.width, 0);
CGPoint midOffset = CGPointMake(wSize.width/2,0);
CGPoint downOffset = CGPointZero;
CCSprite *para1 = [CCSprite spriteWithFile:#"Default.png"];
CCSprite *para2 = [CCSprite spriteWithFile:#"Icon.png"];
CCSprite *para3 = [CCSprite spriteWithFile:#"Default.png"];
CCSprite *para4 = [CCSprite spriteWithFile:#"Icon.png"];
paraNode = [CCParallaxNode node];
[paraNode addChild:para1 z:1 parallaxRatio:CGPointMake(0.5f, 0)
positionOffset:topOffset];
[paraNode addChild:para2 z:2 parallaxRatio:CGPointMake(1, 0) positionOffset:topOffset];
[paraNode addChild:para3 z:4 parallaxRatio:CGPointMake(2, 0) positionOffset:midOffset];
[paraNode addChild:para4 z:3 parallaxRatio:CGPointMake(3, 0) positionOffset:downOffset];
[self addChild:paraNode z:0 ];
[self scheduleUpdate];
}
return self;
}
-(void) update : (ccTime) dt
{
//Need to move the Parallax Node with the repetition of the background
}
This is the Implementation file... I am stuck here for moving the contiunous moving of the background in the Horizontal or Portrait mode.
Thanks for the Help in Advance
CCParallaxNode doesn't support endless scrolling, unless you modify its code. I have an example for endless parallax scrolling in my Learn Cocos2D book. From that link you can also download the book's source code where you'll find the parallax class in chapters 6 to 8.
I have created a simple class named ParallaxManager which is capable for creating infinite parallax effect for both small sprite like small cloud
as well large layer sprite like grass.
You can find out the complete project from GitHub.

cocos2d gives slow animation?

i have used cocos2d for game development.but when i use a sprite in CCLayer(inherited) to move through ccTime.but it moves very slowly.i have set in appgelegate CCDirector setAnimationInterval for (1.0/60) The code is as following:
-(id) init
{
if ((self = [super init]))
{
danceSprite = [CCSprite spriteWithFile:#"images.png"];
[self addChild:danceSprite];
// position the sprite in the center of the screen
CGSize s = [[CCDirector sharedDirector] winSize];
danceSprite.position = ccp(s.width/2,s.height/2); //CCSprite
bg_pos.x = danceSprite.position.x;
bg_pos.y = danceSprite.position.y;
[self scheduleUpdate];
}
return self;
}
-(void) update:(ccTime)delta
{
CGPoint pos = danceSprite.position;
bgX = pos.x;
//bgX -= 30.0;
int newX;
newX = bgX + 1.0 * GAME_SPEED_ADJUSTMENT;
pos.x = bgX;
}
GAME_SPEED_ADJUSTMENT
variable/constant
to multiply with delta to get a faster movement. My start setting is always a
minimum of 10
, in your case it's 1, so I would expect it to move rather slowly.
So it looks like
newX = oldX + delta *
GAME_SPEED_ADJUSTMENT
Try this first - one might also use this to increase the difficulty of the game and globally move things faster.
If this doesn't work, just come back....

AtlasSpriteManager animation

I am using AtlasSpriteManager and AltasSprite to create frame by fram animation with 1 one file. I wanna write something that at first show a simple picture, without any animation and for example when I touch it, it shows some animation and return to the first position and frame. I just can't show the first frame without animation using this code :
Sprite *checker = [Sprite spriteWithFile:#"test.png"];
float frameWidth = [checker boundingBox].size.width / frameNumber;
float frameHeight = [checker boundingBox].size.height;
AtlasSpriteManager *mgr = [AtlasSpriteManager spriteManagerWithFile:fileName];
AtlasSprite *sprite = [AtlasSprite spriteWithRect:CGRectMake(pos.x, pos.y, frameWidth, frameHeight) spriteManager:mgr];
sprite.position = ccp(pos.x, pos.y);
[mgr addChild:sprite];
[layer addChild:mgr];
AtlasAnimation* animation = [AtlasAnimation animationWithName:#"Animation" delay:delay];
assert( animation != nil );
for(int i = 0; i < frameNumber; i++){
[animation addFrameWithRect:CGRectMake(i * frameWidth, 0, frameWidth, frameHeight)];
}
id action = [Animate actionWithAnimation:animation];
assert( action != nil );
id repeatAction;
if(repeatNumber == 0){
repeatAction = [RepeatForever actionWithAction:action];
}else{
repeatAction = [Repeat actionWithAction:action times:repeatNumber];
}
[sprite runAction:repeatAction];
any idea how to do that?
thanx in advance
Updated Answer
I don't think I understood your question as you intended it.
As I understand now, you have a sprite whih you have an animation for. But when the animation is finished, it doesn't return to the frame that you want the sprite to be set to when standing still.
In our code you use actionWithAnimation:, have you tried setting that to actionWithAnimation:restoreOrigionalFrame: and then set restoreOrigionalFrame part to YES?
That should render the animation, but then when it stops, return to the frame it was before the animation.
Alternatively, you can make the action run, then when it stops, return to a certain frame manually by calling setTextureRect: on the AtlasSprite.
[sprite setTextureRect:CGRectMake( x, y, width, height )];
below this marker is my old answer:
The code that you have now will animate it immediately.
If you want the animation to start on touch, you'll have to check for touches. Then add the code to start the animation in the method that receives the touch.
There is sample code on how to use touches in the cocos2d download.
Basically: make your sprite a TargetedTouchDelegate (or create a new object to do that, but that's a bit of a hassle) and implement -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
I think that you need CallFunc action combined with Sequence action.
From your code:
}
.....
.....
id action = [Animate actionWithAnimation:animation];
assert( action != nil );
id repeatAction;
if(repeatNumber == 0){
repeatAction = [RepeatForever actionWithAction:action];
}else{
repeatAction = [Repeat actionWithAction:action times:repeatNumber];
}
id actionCallFunc = [CallFunc actionWithTarget:self selector:#selector(resetSprite)];
id actionSequence = [Sequence actions: repeatAction, actionCallFunc, nil];
[sprite runAction:repeatAction];
....
}
-(void)resetSprite{
[sprite runAction:repeatAction];
}
First will be executed your repeatAction and when it ends the actionCallFunc will be executed calling resetSprite method where you can do what you want with your sprite.