CocosBuilder Animations not running - ios

I'm creating a simple animation with CocosBuilder that just moves a CCLayerColor from top right to bottom left and for some reason the animations will not perform. I have the timeline set to auto play and over a duration of 2 seconds. I have a class that splits up all layers and then adds those layers to a CCScrollLayer. I'm just wondering if the problem is when i remove the layers from the scene and add then to the CCScrollLayer that the animations are removed and in turn not performed.
CCScene* scene = [CCBReader sceneWithNodeGraphFromFile:#"Untitled.ccbi"];
self.scrollLayer = [[CCScrollLayer alloc] init];
CCLayer* child = [[scene children] objectAtIndex:0];
for (CCNode* layer in [child children]) {
[layer removeFromParent];
[self.scrollLayer addChild:layer];
[layer resumeSchedulerAndActions];
}
[self.scrollLayer updatePages];
self.scrollLayer.delegate = self;
[self addChild:self.scrollLayer];
I can see the CCLayerColor object added to the screen but its just not animating.
i've added some custom code to the CCScrollLayer to deal with the situation but i'm just confused as to why the animations are not performing. any help would be great!
EDIT: Maybe a better question would be in CocosBuilder are the actions on the timeline directly linked to the object performing the action or somehow linked through the scene to that object?

Perhaps you forgot to add the scrollLayer as child?
[self addChild:self.scrollLayer];
In the sample code the node created from a ccbi is not referenced either. Maybe you aren't actually using it?

Related

GetSublayers by Hit test ios

I can get a sublayer at any point through hittest at that point by coding. But i want to get all the layers at that point.
The problem is:
By hit test i can only get the top most layer at hat point, it does not give any information about the layers beneath that top layer at that point.
Is there any way to find all the layers at a specific point in ios?
Hit testing is used for the purpose of delivering events. Since events are always delivered to the topmost view it makes no sense for hit test to continue testing the ones below.
However if you do want to find all the layers at a point you can write your own version of hitTest as a category on CALayer that does this :
-(NSMutableSet*)allLayersAtPoint:(CGPoint)aPoint
{
NSMutableSet *layers = [[NSMutableSet alloc] init];
if(! CGRectContainsPoint([self frame],aPoint))
{
return layers;
}
[layers addObject:self]
for(CALayer *layer in self.sublayers) {
CGPoint converted = [self convertPoint:aPoint toLayer:layer]
[layers unionSet:[layer allLayersAtPoint:converted]]
}
return layers
}
Beware of layers with sublayer transforms though. Not sure how to handle that. Usually this is done on UIViews , I'm not sure why you're doing this on layers. Just implement this as a category on UIView instead of CALayer if you want this to work on UIViews.

iOS Cocos3D adding .pod files outside initializeScene method

#All Hello,
I am trying to add and display .pod files outside initializeScene method. I can add them and display them properly inside initializeScene method but i need to show some of the .pod files dynamically after initializing scene.
I checked there is method onOpen but i tried adding there but it does not show up.
I am trying with below methods:-
-(void) initializeScene {
_autoRotate = TRUE;
[self setTouchEnabled:YES];
// Create the camera, place it back a bit, and add it to the scene
cam = [CC3Camera nodeWithName: #"Camera"];
cam.location = cc3v( 0.0, 0.0, 8.0 );
_cameraAngle = M_PI / 2.0f;
_cameraAngleY = M_PI / 2.0f;
_cameraHeight = INIT_VIEW_HEIGHT;
_cameraDistance = INIT_VIEW_DISTANCE;
_swipeSpeed = 0.0f;
[self addChild: cam];
// Create a light, place it back and to the left at a specific
// position (not just directional lighting), and add it to the scene
CC3Light* lamp = [CC3Light nodeWithName: #"Lamp"];
lamp.location = cc3v( -2.0, 0.0, 0.0 );
lamp.isDirectionalOnly = NO;
[cam addChild: lamp];
[self createGLBuffers];
[self releaseRedundantContent];
[self selectShaderPrograms];
[self createBoundingVolumes];
LogInfo(#"The structure of this scene is: %#", [self structureDescription]);
// ------------------------------------------
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(void) onOpen {
[self.viewSurfaceManager.backgrounder runBlock: ^{
[self addSceneContentAsynchronously];
}];
}
-(void) addSceneContentAsynchronously {
[self addContentFromPODFile:#"myObject.pod" withName:#"Mesh1"];
CC3MeshNode *meshNode = (CC3MeshNode *) [self getNodeNamed:#"Mesh1"];
[self addChild:meshNode];
self.activeCamera.target = meshNode;
self.activeCamera.shouldTrackTarget = YES;
[self.activeCamera moveWithDuration: 0.5 toShowAllOf: self withPadding: 2.5f];
}
I have .pod models separately so i just need to add them into scene and show them in camera. But asynchronously and dynamically.
Also if i add .pod files in initializeScene method it all works fine.
In cocos3d, when you load assets on the background thread, each occurrence of the addChild: method actually dispatches back from the background thread to the rendering thread to actually add the node to its parent.
The reason for this is to synchronize the thread activity, specifically, to avoid the new node being added into the node structure while the renderer is iterating that same structure to draw the nodes. Review the implementation of the CC3Node addChild: method if you want to see the ugly details.
Because of this double-dispatch, in your addSceneContentAsynchronously implementation, your node has probably not actually been added to the scene yet when the moveWithDuration:toShowAllOf:withPadding: runs.
The moveWithDuration:toShowAllOf:withPadding: method surveys the scene once, at the beginning of the method, to determine where the camera should move to. So, the result is that the camera likely doesn't know of the existence of your newly added node when it performs that survey.
You can likely resolve this by placing a short sleep into the background thread just before invoking moveWithDuration:toShowAllOf:withPadding:.
[NSThread sleepForTimeInterval: 0.1];
Another option would be to override the addChildNow: method in your custom CC3Scene implementation, so that it invokes the superclass implementation, and then moves the camera. The addChildNow: method is what runs on the rendering thread, as a result of the double-dispatch, to actually add the node to its parent.
However, that might get cumbersome if you're adding a lot of content to your scene, as it will cause the camera to bounce around each time something new is added. But then again, maybe that will make sense in your app.

Slow down in iOS 7 in Cocos2D with transparent background

I've been developing a game in Cocos2D for about 3 years which utilizes a transparent background to show a UIView. The reason for this is to have the parallax background still run as Cocos2D does scene transitions.
I'm having a new issue that started when I updated to iOS 7. Slow down occurs in combination of these circumstances:
-ONLY if the parallax background's frame position has changed.
-If I destroy an enemy which emits small sprites and a particle effect.
So it's the combination of those two things and it only happens sometimes. The debug value of the frame rate does not dip when the slow down happens. If I load a new scene it goes back to normal. Sometimes when I destroy another enemy the slow down disappears as well.
I have code in my parallax UIView that runs just about every frame of in-gameplay. I summed down the issue to one line:
-(void)updateImagePosWithPos:(CGPoint)pos{ // in game
// create vel based on last currentPos minus new pos
CGPoint vel = CGPointMake(currentPos.x-pos.x, currentPos.y-pos.y);
// init variables tmpVel and tempTotalImages
CGPoint tmpVel = CGPointZero;
int tmpTotalImages = 0;
// create indexLayerArr
NSMutableArray *indexLayerArr = [NSMutableArray array];
// for every parallax layer, add the number of images horizontally minus 1 to indexLayerArr
for (int j=0; j<totalLayers; ++j){
[indexLayerArr addObject:[NSNumber numberWithInt:[[totalImagesArr objectAtIndex:j] intValue]-1]];
}
int i = 0;
for (UIImageView *imageView in self.subviews) {
CGRect tmpRect = CGRectZero;
NSMutableArray *tmpRectArr = [rectContainer objectAtIndex:imageView.tag];
float speed = 0.00;
tmpTotalImages = [[totalImagesArr objectAtIndex:imageView.tag] intValue];
speed = [[speedArr objectAtIndex:imageView.tag] floatValue];
tmpVel = CGPointMake(vel.x*speed, vel.y*speed);
i = [[indexLayerArr objectAtIndex:imageView.tag] intValue];
tmpRect = [[tmpRectArr objectAtIndex:i] CGRectValue];
if(tmpRect.origin.x - tmpVel.x > wins.width){
tmpRect.origin.x -= (tmpTotalImages)*tmpRect.size.width;
}
else if(tmpRect.origin.x - tmpVel.x < -tmpRect.size.width){
tmpRect.origin.x += (tmpTotalImages)*tmpRect.size.width;
}
tmpRect.origin.x -= tmpVel.x;
tmpRect.origin.y += tmpVel.y;
[tmpRectArr replaceObjectAtIndex:i withObject:[NSValue valueWithCGRect:tmpRect]];
imageView.frame = [[tmpRectArr objectAtIndex:i] CGRectValue]; // <-- slow down cause
i--;
[indexLayerArr replaceObjectAtIndex:imageView.tag withObject:[NSNumber numberWithInt:i]];
}
currentPos = CGPointMake(pos.x, pos.y);
}
See commented line imageView.frame = [[tmpRectArr objectAtIndex:i] CGRectValue];
So if I comment that line out, the problem will never happen. If I keep the line and as well as don't change the values of tempRect, the problem also won't happen.
It looks like there's an issue in iOS 7 in changing the UIImageView's frame position, but only sometimes. Just wondering what other alternatives could I use? Or am I doing something definitely wrong in iOS 7?
Not a solution to your problem but workarounds. I'll start with the one that's probably requires the most code changes.
You don't actually have to have a UIView in order to keep background with transitions. Instead if you implement the background entirely in cocos2d (as part of the scene), you can achieve the same effect if instead of replacing scenes you transition layers in and out. Scene transitions for the most part use the same actions that also work on nodes.
Implement the background using cocos2d nodes, and have one parent node acting as the container (ie "layer") of the background nodes. You can do one of two things with that node:
a. Edit CCDirectorIOS's code and add a reference to your background node. Update the node before all other nodes in the drawScene method, by calling visit on the background node just before [_runningScene visit].
b. When transitioning to a new scene, either remove the background node from the current scene and add it to the new scene, or create a copy of the background with all the same settings and add it to the new scene. Ensure the copy starts with the exact same state as the original. Though this won't work with most transitions due to the nature of their animation (ie move/flip/zoom).
If you need the background to animate while a transition is running, there's a simple trick. Schedule update on a non-CCNode object that has global lifetime (ie AppDelegate). Then manually send the update to all nodes that should continue to update their state during a transition, and only during a transition.
You can register updates on non-node objects like this:
[_director.scheduler scheduleUpdateForTarget:self priority:0 paused:NO];
This update method will be called even during scene transitions. Alternatively it should also be possible to continue updating nodes by changing their paused state and thus resuming scheduler and actions, either by overriding the paused property or by explicitly unpausing specific nodes when a transition occurs.

Add Action on CCLayer in cocos2d iOS

I have a CCLayer class which i'm using for pause menu and inside that class i have menuitems . I've just added menu and it shows on screen but no animation in it. I want to add transition effect on layer as we can do it in scene. or add action as we do in sprite. I just want my pause menu to animate from up to down.
Here how i am adding my CClayer class.
menuLayer = [[PauseMenu alloc] initWithParent:self];
[self addChild:menuLayer z:99];
I have tried this code for action but it doesn't work
menuLayer = [[PauseMenu alloc] initWithParent:self];
[self addChild:menuLayer z:99];
id move=[CCMoveTo actionWithDuration:5.1 position:ccp(240,120)];
[menuLayer runAction:move];
Following your comment I'll recommend you not to use [[CCDirector sharedDirector] pause] as it does not really will pause your game logic (only actions and schedulers) but if you have some thread doing game logic (like moving objects or calculating some stuff) it will still keep running.
If you want to pause your game you should keep an internal state of your game. So for example in your update method you could do :
if (gameState == GAME_PAUSE)
return;
This way it will be easy for you to decide what continues to be done and what not until the game returns to play.

animated sprite won't stop animation - cocos2d

I have an animated sprite using two pngs. The animation works fine. I have another method that is run when the game is over.
//Grey mouse with Pompom
greyMousePomPom = [CCSprite spriteWithFile:#"pink_mice_pom_anime_01.png"];
greyMousePomPom.tag=132;
[self addChild:greyMousePomPom z:6];
greyMousePomPom.position = CGPointMake(550, 70);
//Grey Pom Pom Mouse animation
CCAnimation *greyMousePomPomAnimate = [CCAnimation animation];
[greyMousePomPomAnimate addFrameWithFilename:#"gray_mice_pom_anime_01.png"];
[greyMousePomPomAnimate addFrameWithFilename:#"gray_mice_pom_anime_02.png"];
id greyMousePopPomAnimationAction = [CCAnimate actionWithDuration:1.3f animation:greyMousePomPomAnimate restoreOriginalFrame:NO];
repeatAnimationPomPom2 = [CCRepeatForever actionWithAction:greyMousePopPomAnimationAction];
[greyMousePomPom runAction:repeatAnimationPomPom2];
When I run my method to change the animated sprites texture and to stop them the animation continues behind the new texture.
-(void) changePomPomMiceToSadFaceForFreeFall
{
NSLog(#"making the mice sad");
[self stopAllActions];
[greyMousePomPom setTexture:[[CCTextureCache sharedTextureCache] addImage:#"gray_mice_pom_anime_03.png"]];
}
I know this method is working because it is NSLogging and the textures are changing. But why aren't the animations stopping? I have tried to remove it by tag and by declaring the action but no success.
I know there are a lot of people out there that are smarter than me.. can you help?
What you're doing right now is stop all animations added to the current node:
self
If you added any action to self, this command would be perfectly fine to stop all of them.
Instead what you need to do is, you need to call the stopAllActions method on the object you added the actions to:
[greyMousePomPom stopAllActions];
HTH

Resources