CCShaky3D turns the background black - iphone

I'm trying to make my sprite have a shake effect. However, while the sprite does shake, the entire background turns black. Can anybody help me with this?
Here's the code that I've written to add the sprite to my layer along with the action that I run right after.
CCSprite * picture = [CCSprite spriteWithFile:#"picture.png"];
picture.position = ccp(winsize.width/4,
picture.contentSize.height * 0.8);
[self addChild:picture];
CCShaky3D * shake = [CCShaky3D actionWithRange:4
shakeZ:NO
grid:ccg(12, 12)
duration:0.5];
[picture runAction:shake];
Can anybody help me?

Have you enabled depth buffering of the EAGLView? Most 3D actions require depth buffering (GL_DEPTH_COMPONENT16_OES or GL_DEPTH_COMPONENT24_OES) to avoid visual artifacts. You may also have to use a 32-Bit frame buffer with alpha channels by using the kEAGLColorFormatRGBA8 instead of kEAGLColorFormatRGB565.
EAGLView is initialized in the app delegate class:
EAGLView* glView = [EAGLView viewWithFrame:[window bounds]
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:GL_DEPTH_COMPONENT24_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:0
numberOfSamples:0];

Related

Small FPS with Background Image

I have a big problem with my app.
I am few steps before the end of my app and today I wanted to add a background image.
My normal FPS is 180 during black background and when I added my background for iphone 4 sized 960/640 my FPS changed to 20-30 so its impossible to play. And next thing what happens is, when my player and enemy has a collision they stop their actions, but only if there is my background. I am using SpaceManager so maybe its because of its shapes. So does anyone know how to add background in another way in SpaceManager to do not slow my FPS? Here is the way I try to add Background:
-(id) init
{
CCSprite *background = [CCSprite spriteWithFile:#"Background.png"];
background.anchorPoint = ccp(0, 0);
[self addChild:background z:-1];
}
the most likely cause for the drop in fps is because the picture is designed for the retina display, and since it is a large file it slows down the app. the device which you are using also has an effect on how fast the game works, so if its slow only on a 3gs or something like that just drop support for it.
So my Objects are statit mass, so I dont have there [sm addcollision] but I have there this code
-(void) KolizeHraceSProtiHracem
{
if (player.position.x - enemy.position.x < 40 )
{
[enemy stopAllActions];
[player stopAllActions];
[player runAction:[CCMoveTo actionWithDuration:0.2 position:ccp(player.position.x + 40, 10)]];
[enemy runAction:[CCMoveTo actionWithDuration:0.1 position:ccp(enemy.position.x - 10, 10)]];
}
I dont think, this code is bad, because if I dont have a background this code works but if i do this code stops all actions.

Cocos2d, Weird position offset when using CCParallaxNode

I'm using cocos2d for iOS. Not sure if I'm doing something wrong here or if CCParallaxNode does something strange that I just don't understand.
I'm trying to create a few layers of parallax scrolling in the background of my game, at the moment I just have one layer added to the parallax node till I can figure out what's going wrong. When the game loads the layer it's always offset down and left by about 30% of the image size. I've uploaded an image demonstrating the difference in position here http://oi42.tinypic.com/29dz1av.jpg.
Here is my code:
background = [CCParallaxNode node];
background.anchorPoint = ccp(0,0);
background.position = ccp(0,0);
[self addChild: background];
background_image = [CCSprite spriteWithFile: #"layer01.png"
rect: CGRectMake(0, 0, 100, 100)];
background_image.anchorPoint = ccp(0,0);
background_image.position = ccp(0,0);
[background addChild: background_image z:0 parallaxRatio: ccp(0,0) positionOffset:ccp(0,0)];
The cocos2d icon is attached to the same layer as the parallax node and it's position and anchor point are set to 0,0 so the bottom left of the icon should be in the same location as the bottom left of the blue background image.
I have tested this using a basic sprite in place of the parallax node and everything lines up as it should so it's not the image itself.
Any help with this would be appreciated.
First, I don't suggest you to set parallax node & its children's anchor point & position directly because it will cause some unexpected results. You should add the parallax node to a layer as its child, and set the layer's anchor point & position to place your parallax.
Second, CCParallaxNode also provides a positionOffset that you can place your picture in parallax at first. This can help if you want to align several layers of pictures' view center.
So I think you should do something like this(Since I'm using cocos2d-x, I'm not sure its right with obj-C):
layer = [[CCLayer alloc]init];
background = [CCParallaxNode node];
[layer addChild: background];
[self addChild: layer];
Then you just have to add the picture sprite in background, and set layer's position & anchor point.
Hope it can help.
Make sure the background image size is 480x320.
Why did you write CGRectMake(0, 0, 100, 100) ? Why 100 and 100 ? You're limiting your 'CGRect', that's probably wrong..

Cocos2D - filling a sprite

UIImageViews have a property called contentMode that you can use as
imageView.contentMode = UIViewContentModeScaleAspectFit;
and it will fill the entire view with your image without distorting, even if it has to bleed the image to do that.
Is there any similar stuff on Cocos2D? Sorry about the question, but I am new to Cocos2d.
I am creating the sprite like this:
CCTexture2D *textBack = [[CCTexture2D alloc] initWithImage:image];
CCSprite *sprite = [CCSprite spriteWithTexture:textBack];
thanks.
The equivalent method to performing a UIViewContentModeScaleAspectFit would be the .scale property. When a CCNode (or any of the sub nodes such as CCSprite etc.) is first created, the scale property is 1. Keep increasing it to scale the sprite up proportionally.
sprite.scale = 2.0f; // Scales the sprite proportionally at a factor of 2
As for it fitting to a specific size, you would have to write a routine:
Pass in desired rect and CCSprite bounding box rect.
Scale the box rect to aspect fit the desired rect.
Return the scaling factor
The result can then be applied to the CCSprite.scale property.
You can certainly scale the sprite to do that...
sprite.scale = ?
sprite.scaleX = ?
sprite.scaleY = ?
but I don't believe there is a function to automatically fill the entire screen. If you don't get a definitive reply here I would suggest posting on the Cocos2D forums (http://www.cocos2d-iphone.org/forum/).

Antialiasing edges of UIView after transformation using CALayer's transform

I have a UIView object that rotates using CALayer's transform:
// Create uiview object.
UIImageView *block = [[UIImageView alloc] initWithFrame....]
// Apply rotation.
CATransform3D basicTrans = CATransform3DIdentity;
basicTrans.m34 = 1.0/-distance;
blockImage.layer.transform = CATransform3DRotate(basicTrans, rangle, 1.0f, 0.0f, 0.0f);
After rotating the edges of the object are not antialiasing. I need to antialias them.
Help me, please. How can it be done?
One way to do this is by placing the image inside another view that's 5 pixels bigger. The bigger view should have a transparent rasterized border that will smooth the edges of the UIImageView:
view.layer.borderWidth = 3;
view.layer.borderColor = [UIColor clearColor].CGColor;
view.layer.shouldRasterize = YES;
view.layer.rasterizationScale = [[UIScreen mainScreen] scale];
Then, place your UIImageView inside this parent view and center it (With 2.5 pixels around each edge).
Finally, rotate the parent view instead of the image view.
It works very well - you can also encapsulate the whole thing in class that creates the hierarchy.
Simply add this key-value pair to your Info.plist: UIViewEdgeAntialiasing set to YES.
check allowsEdgeAntialiasing property of CALayer.
block.layer.allowsEdgeAntialiasing = YES; // iOS7 and above.
I had a similar issue when rotating around the z-axis. Setting shouldRasterize = YES prevented the jagged edges however it came at a performance cost. In my case I was re-using the views (and its layers) and keeping the shouldRasterize = YES was slowing things down.
The solution was, to turn off rasterization right after I didn't need it anymore. However since animation runs on another thread, there was no way of knowing when the animation was complete...until I found out about an extremely useful CATransaction method. This is an actual code that I used and it should illustrate its use:
// Create a key frame animation
CAKeyframeAnimation *wiggle = [CAKeyframeAnimation animationWithKeyPath:#"transform"];
NSInteger frequency = 5; // Higher value for faster vibration
NSInteger amplitude = 25; // Higher value for lower amplitude
// Create the values it will pass through
NSMutableArray *valuesArray = [[NSMutableArray alloc] init];
NSInteger direction = 1;
[valuesArray addObject:#0.0];
for (NSInteger i = frequency; i > 0; i--, direction *= -1) {
[valuesArray addObject:#((direction * M_PI_4 * (CGFloat)i / (CGFloat)amplitude))];
}
[valuesArray addObject:#0.0];
[wiggle setValues:valuesArray];
// Set the duration
[wiggle setAdditive:YES];
[wiggle setValueFunction:[CAValueFunction functionWithName:kCAValueFunctionRotateZ]];
[wiggle setDuration:0.6];
// Turn on rasterization to prevent jagged edges (anti-aliasing issues)
viewToRotate.layer.shouldRasterize = YES;
// ************ Important step **************
// Very usefull method. Block returns after ALL animations have completed.
[CATransaction setCompletionBlock:^{
viewToRotate.layer.shouldRasterize = NO;
}];
// Animate the layer
[viewToRotate.layer addAnimation:wiggle forKey:#"wiggleAnimation"];
worked like a charm for me.
I have not tried using this with implicit animations (i.e. animations that happen due to value change in animatable property for a non-view associated layer), however I would expect it to work as long as the CATransaction method is called before the property change, just as a guarantee the block is given to CATransaction before an animation starts.

Changing z-order of draw method in Cocos2d?

Right now I am trying to draw a polygon in Cocos2d, but I need it over a background, how do I change draw's z-index and make it top priority so that way I can see the line instead of it being covered by the background?
Here is the draw method:
I decided to just make it a line instead of polygon, and adjust the width of it but otherwise it is the same...
-(void) draw {
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(5.0f);
ccDrawLine(healthBar[0], healthBar[1]);
}
Use reorderChild function of CCNode. And put your rectangle over background
-(void) reorderChild:(CCNode *) child z:(int) zOrder
In your app delegate, you need to modify your GLView so that it has depth enabled. Then, you should be able to modify the depth of your draw call. In your app delegate, look for something like this:
EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
pixelFormat:kEAGLColorFormatRGBA8 // kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
Change the 0 to either GL_DEPTH_COMPONENT16_OES or GL_DEPTH_COMPONENT24_OES.
Edit:
I'm not familiar with OpenGL, but perhaps this page will help you.