How to start CCBFile animation on call in cocos2d? - ios

I ceated the CCBFile in Sprite Builder and added in a main scene, now when i run the project that CCBFile animation start automatically. I want to start or call it after some delay... any idea?
here is my code...
#implementation MainScene {
CCPhysicsNode *_physicsNode;
CCNode *playerbackwardshort;
}
// is called when CCB file has completed loading
- (void)didLoadFromCCB {
//For Delay
[self performSelector:#selector(Upgrade) withObject:nil afterDelay:0.6];
}
-(void)Upgrade{
CCBAnimationManager* am = self.userObject;
[am runAnimationsForSequenceNamed:#"playerbackwardshort"];
}

The CCBAnimationManager is used for this. Let's say that you named your animation 'AnimationTest`. To stop it from running automatically, there's an option for it in the timeline properties (see here)
// in the loaded ccb file's class
CCBAnimationManager* animationManager = self.userObject;
[animationManager runAnimationsForSequenceNamed:#"AnimationTest"];

Related

Can't seem to make my scene scroll horizontally automatically

I am trying to make a game that consist of a "hero" that runs endlessly and basically has to avoid obstacles and as he avoids these obstacles he receives point and I am trying to make this game in Sprite Builder which I am not so good in yet and having a hard time coding for it.
Basically this is what I have so far:
static const CGFloat scrollSpeed = 0.1;
#implementation level
{
CCPhysicsNode *_physicsNode;
CCSprite *_guy;
}
- (void)update:(CCTime)delta
{
_guy.position = ccp(_guy.position.x + delta * scrollSpeed, _guy.position.y);
_physicsNode.position = ccp(_physicsNode.position.x - (scrollSpeed *delta), _physicsNode.position.y);
}
- (void)didLoadFromCCB
{
// tell this scene to accept touches
self.userInteractionEnabled = TRUE;
}
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
//whenever the screen is tapped, this will happen
[self guyJump];
}
- (void)guyJump {
//makes the guy jump
}
But then I am also receiving this error in the console:
CCBReader: Couldn't find member variable: _physicsNode
CCBReader: Couldn't find member variable: _guy
HOW I SOLVED IT !
Make sure that in SpriteBuilder:
level is the custom class of your CCScene root node
Your CCSprite and CCPhysicsNode is marked as Doc root var and the correct name is
marked, also it should not be a custom class
Do a File->Clean Cache
Press the Publish button
Make sure that in XCode
You have a custom class called level
In level you have an ivar declared
#implementation level
{
CCPhysicsNode *_physicsNode;
CCSprite *_guy;
}
Do a Product->Clean
Run your project
Try to replace these lines of code:
#implementation level
{
CCPhysicsNode *_physicsNode;
CCSprite *_guy;
}
with:
#interface level ()
{
CCPhysicsNode *_physicsNode;
CCSprite *_guy;
}
#implementation level
Make sure that in SpriteBuilder:
level is the custom class of your CCScene root node
Your CCSprite and CCPhysicsNode is marked as Doc root var and the correct name is
marked, also it should not be a custom class
Do a File->Clean Cache
Press the Publish button
Make sure that in XCode
You have a custom class called level
In level you have an ivar declared
#implementation level
{
CCPhysicsNode *_physicsNode;
CCSprite *_guy;
}
Do a Product->Clean
Run your project

Cocos2d v3 modal pause view implementation

I am trying to make my pause screen in my game. I am using the framework Cocos2d V3 RC4 in IOS and XCODE and SpriteBuilder. I read a lot of post and i think that i have two aproachs posible:
1º Push a total scene foward the main scene. (THIS WORK FINE TO ME)
In the MAIN SCENE i call this to pause the game
CCScene *pausa = [CCBReader loadAsScene:#"Pausa"];
[[CCDirector sharedDirector] pushScene:pausa];
and then in the Pause class i call this to pop the pause scene and take back the Main scene:
[[CCDirector sharedDirector] popScene];
2º Take a CNode in front of the MAIN SCENE, making it with transparency, opaque, and disableing the main scene touch, animations, actions, etc… (THIS DOESN’t WORK FOR ME AND I WHANT THIS !!!)
I doit in this way:
In the main Scene:
CCScene *pausa = [CCBReader loadAsScene:#"Pausa"];
[self addChild:pausa];
AND I TRY with ALL THIS METHODS:
// [self unscheduleAllSelectors];
// [self stopAllActions];
// [self setPaused:TRUE];
// [self setUserInteractionEnabled:FALSE];
The node is added but Have not Touch exclusively… The Node that is behind I can touch it…
I try olso with :
[[CCDirector sharedDirector] pushScene:pausa];
(in the main scene) with result obviosly bad, and i try with
[self setExclusiveTouch:TRUE];
in the pause didLoadFromCCB method but also I cant make it have a Exclusive touch. i Can STILLPRESS buttons and sprites from the back Node…
What I am doing Wrong, And how is the correct code/aproach tu use to handle a pause node like I want for method 2??
Resuming... I only want a Modal Window... (like in zk framework, in java, the Window (CNode in Cocos2d) come in front and the background keep disabled and in grey)
Thanks for read and hope someone can help
Here is my implementation from a game that I am doing
- (void) pauseGame
{
CCLOG(#"Pause game");
_contentNode.paused = YES;
_contentNode.userInteractionEnabled = NO;
_gamePausedNode = (GamePausedNode *)[self loadCCBWithNameAndPositionInCenter:#"PausedNode"];
[self addChild:_gamePausedNode];
}
gamePausedGame is a CCNode, but it could be CCSprite as well. It is not actually a CCScene, nor is it loaded by one because a modal view like this is not really a scene.
You usually want to group the CCNode objects together in one CCNode like my _contentNode so you can pause them with one click.
Update : I have edited the code to the bare minimals
CCPhysicsNode *_physics;
_physics.paused = true;// It will pause your game but not actions.
_physics.paused = false;// It will resume your spinning and falling of sprites while button is pressable like during pause game.

Dynamically allocate a parameter for action when running a sequence

I stumbled upon a problem and I can't find the answer for it. I am working with the SK template from Xcode to create an iOS game. I am a beginner, so bear with me.
Basically I have this code:
SKAction *releaseBubbles = [SKAction sequence:#[
[SKAction performSelector:#selector(createBubbleNode)onTarget:self],
[SKAction waitForDuration:speed]]];
[self runAction: [SKAction repeatAction:releaseBubbles
count:300]];
which executes in
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
I change the level to my game in -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { and when I change the level it should also change that speed parameter. Of course, this doesn't work because I believe that my action is starting when the scene is initialised and I never get to switch the parameter.
What I need to do is populate the screen continuously with bubbles appearing at a certain pace (relative to the level).
I really have no clue how to fix this, because it seems to me like I need to stop and restart the action sequence somehow...
Looking forward to your valuable input.
To continuously populate the screen with bubbles you can use the update: method of your SKScene. Here is how to do it.
First, add a property that will store a date when you last added a bubble.
#property(nonatomic, strong) NSDate *lastBubbleCreationDate;
Then, change your update: method to:
-(void)update:(CFTimeInterval)currentTime
{
// Create new bubble every 5s.
if (ABS([_lastBubbleCreationDate timeIntervalSinceNow]) > 5)
{
[self createBubbleNode];
}
}
Finally, in your createBubbleNode method you have to store the time when you created last bubble:
-(void)createBubbleNode
{
// Your code here
// Set the date to now.
_lastBubbleCreationDate = [NSDate date];
}
You also need to call createBubbleNode to set the initial value of the _lastBubbleCreationDate. You can do this in didMoveToView: method. Just add this method to your scene implementation:
- (void)didMoveToView:(SKView *)view
{
// Creates first bubble and sets the initial value of the _lastBubbleCreationDate
[self createBubbleNode];
}
In next levels you can just change the 5s value to create bubbles more often which will make the game more difficult.

Why I can't reset my CCParticleSystemQuad from the parent CCLayer?

I've added an additional CCLayer to my "GameScene" that becomes visible ([self addChild:_congratsScreen]) whenever my character collects a given amount of objects on the screen.
Within my GameScene.h I've declared my child layer (CClayer *congratsScreen) and I'm synthesizing it on my GameScene.m. I'm allocating the child CCLayer in the GameScene's init method so it is holding the reference to the child layer in this instance variable.
On my GameScene I have a few CCParticleSystemQuad instances, and it's super simple to invoke both stopSystem and resetSystem to replay my particles animation, but if I try to do the same thing on the CCParticleSystemQuad that was initialized on the child layer, the resetSystem doesn't work after I remove the child from my GameScene and add it back again. Does something happens with the CCLayer's components once it is removed from a parent layer's scene?
I don't have the code at the moment so I will try to write some pseudo-code to illustrate how it's being done:
How it is being initialized on ChildLayer.m:
_sparkling= [CCParticleSystemQuad particleWithFile:#"sparkling.plist"];
Then, somewhere on GameScene.m I have:
- (void) showCongrats {
//pathetic way to create a modal panel
[self setTouchable = NO];
[[[self _congratsLayer] _sparkling] resetSystem];
[self addChild:_congratsLayer];
}
- (void) hideCongrats {
//let them continue playing
[self setTouchable = YES];
[[[self _congratsLayer] _sparkling] stopSystem];
[self removeChild:_congratsLayer];
}
So, it works on the first time I invoke showCongrats, the reference is good and I can manipulate the particles, but once I hide the layer, continue playing the game and show the congratulations panel again, it shows a frozen animation of the particles from the last invocation, the resetSystem no longer works. Any ideas?
I would add some breakpoints in the code and walk through it but if I had to guess I would say that when you are calling removeChild you are losing the data that you had in your init method and something funky is happening.

Implementing CCSprite class into my game

In my game, which is using cocos2d, there is going to be many different types of enemies, which all look different, and move all in different ways. Also, there is going to be a couple of different gamemodes, which both use the same enemies. As there will be different gamemodes, I decided to make each of my enemies have their own CCSprite class. In those there will be the way that the sprites move, the animation, etc. When one of these sprite is needed in my game, they will be spawned in to the scene. The only thing is, how do I do this? How do I call for one of the sprites to be create on the screen when they are using a class of their own?
If you want to tell me another way than having these sprites having their own classes, that is fine, but keep in mind that I will be having a couple of different gamemodes. If I do the code for the sprites in the CCLayer class of that gamemode, well I will have to write the code twice, which will take time.
Thanks.
You can just subclass CCSprite and override the default initializer initWithTexture:rect:
example taken from here
#implementation MySprite
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
if( (self=[super initWithTexture:texture rect:rect]))
{
// initialize your ivars here
//ivar1 = xxx;
//ivar2 = yyy;
//ivar3 = zzz;
}
return self;
}
#end
// And to create an instance of MySprite you simply do:
MySprite *sprite = [MySprite spriteWithFile...];
// or any of the supported CCSprite methods.
you can have a super class say EnemySprite that looks like this
#interface EnemySprite : CCSprite
- (void)addToLayer:(CCLayer *)layer;
- (void)removeFromLayer:(CCLayer *)layer;
#end
than create a subclass for each type of enemy for example:
#inteface BigEnemySprite : EnemySprite
#end
#implementation BigEnemySprite
- (void)addToLayer:(CCLayer *)layer {
[layer addChild:self];
// animation code for your big enemy
}
- (void)removeFromLayer:(CCLayer *)layer {
[layer removeChild:self];
// animation code
}
#end
than you can use them like
EnemySprite *enemy = [BigEnemySprite spriteFromFile:file];
[enemy addToLayer:self];

Resources