Cocos2d: Move a Sprite along a path/bezier? - cocos2d-iphone

I need to move a sprite from one CGPoint to another using Cocos2d for the Iphone. The problem is that the animation should be along a bezier.
Basically I would use this :
id move = [CCMoveTo actionWithDuration:.5f position:ccp(100,200)];
[sprite runAction:move];
Now how can I do this in a non linear path ?

Try this
ccBezierConfig bezier;
bezier.controlPoint_1 = ccp(0, s.height/2);
bezier.controlPoint_2 = ccp(300, -s.height/2);
bezier.endPosition = ccp(300,100);
id bezierForward = [CCBezierBy actionWithDuration:3 bezier:bezier];

Well, actually I was once again too fast seeking for help.
Found the solution, there is a method : CCBezierTo

Related

Cocos2d - retina images not displaying

Simply trying to test retina display. I setup the director like this:
CCDirectorIOS* director = (CCDirectorIOS*)[CCDirector sharedDirector];
director.wantsFullScreenLayout = NO;
director.projection = kCCDirectorProjection2D;
director.animationInterval = 1.0 / 60.0;
director.displayStats = YES;
[director enableRetinaDisplay:YES];
I create two versions of the file in Photoshop - outline-hd.png and outline.png. I color the HD version red so I can tell if it's being displayed.
Display code:
CCSprite *border = [CCSprite spriteWithFile:#"outline.png"];
[self addChild:border];
Yet it is the non-hd image that gets displayed on my iPhone5. Why?
I came across this question while trying to solve the exact same problem in my own project. Had to dig around in the cocos2d source to figure it out. The problem is that the director's enableRetinaDisplay:YES method doesn't work unless the director's view is set. So, it needs to be called after the glView is set up, and you've called setView on the director:
CCGLView *glView = [CCGLView viewWithFrame:aFrame
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
[[CCDirector sharedDirector] setView:glView];
NSLog(#"glView is set, enable retina...");
[[CCDirector sharedDirector] enableRetinaDisplay:YES];
This should fix the problem for you!
May be you forgot:
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO];
[sharedFileUtils setiPhoneRetinaDisplaySuffix:#"-hd"];

CCAction in box2d world

i'm newbie to both cocos2d and box2d and i've been struggling for two days with this problem : i have a scene with many sprites dropping down (with bodies attached to them). and i have a BackgroundLayer from which i add my background image into the scene (which is not involded into the physics simulation). In my backgroundLayer i'm trying to perform an action on a sprite :
(it blink in the first position and jump directly to the end position )
id flyBubble = [CCEaseInOut actionWithAction:[CCMoveTo actionWithDuration:0.7 position:randomEndPosition]];
but my sprite doesn't respond at all to this action!! my sprite doesn't have any b2body attached and seems like it respond to the tick: method of the physics world (which is in my Main Scene). How can i perform an action to a sprite that doesn't have a b2body attached.
any help would be appreciated!!! thanks
here is the entire code :
CCSprite *bubble = [CCSprite spriteWithFile:#"bubble.png"];
[self addChild:bubble];
CGPoint startPosition = ccp(100, 100);
bubble.position = startPosition;
CGPoint endPosition = ccp(400, 400);
id flyBubble = [CCEaseInOut actionWithAction:[CCMoveTo actionWithDuration:0.7 position:randomEndPosition]];
id remove = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[self removeFruit:(CCSprite *)node];
}];
[bubble runAction:[CCSequence actions:flyBubble, remove, nil]];
I guess source and destination position of sprite is same. So no difference in action.
try like this..
sprite.position = ccp(0,0);
id flyBubble = [CCMoveTo actionWithDuration:0.7 position:randomEndPosition];
[sprite runAction:flyBubble];
i did a little mistake that costs me lot of times. it was in this line of code
id flyBubble = [CCEaseInOut actionWithAction:[CCMoveTo actionWithDuration:0.7 position:randomEndPosition]];
CCEaseInOut doesn't work i don't know why!! when i used CCEaseExponentialInOut it worked perfectly.
Thanks anyway!

CCRepeatForever Error

I've got a problem in my current game.
I'm trying to move a sprite based on the movement of a other physic body, for a map. This is my code:
...
NSMutableArray *mapObjetcs = [[[NSMutableArray alloc]init]autorelease];
[mapObjetcs addObject:swordman];
[mapObjetcs addObject:icon];
CCCallFuncND* iconMap = [CCCallFuncND actionWithTarget:self selector:#selector(mapLoc:mapObj:) data:mapObjetcs];
CCSequence* iconMapSequence = [CCSequence actions:[CCDelayTime actionWithDuration:1.0f/60.0f], iconMap, nil];;
CCRepeatForever* iconRef = [CCRepeatForever actionWithAction:iconMapSequence];
[self runAction:iconRef];
}
-(void) mapLoc:(ccTime)delta mapObj:(NSMutableArray*)mapObj
{
GB2Sprite *swordmanTemp = (GB2Sprite*)[mapObj objectAtIndex:0];
CCSprite *iconTemp = (CCSprite*)[mapObj objectAtIndex:1];
CGPoint swordmanPos = [swordmanTemp ccPosition];
float pos = (swordmanPos.x/convFactor)+65;
iconTemp.position = ccp(pos, 290);
}
Every time i run the code with the CCRepeatForever the games freezes, if i run the code without the CCRepeatForever the game run grat but dont refresh the icon in map.
Can anybody help me??? Thanks
Its a problem with running CCRepeatForever on layer itself.. Ofcourse it will freeze the game.. You can try for alternate solution I guess.. Instead of using a separate CCRepeatForever loop, use the update method of your layer.. As its already doing same thing that you want to do with your own action..
Another solution is make a same CCRepeatForever for your icon sprite.. and in its CCCallFuncND take the position of other object....
Hope this helps.. Try yourself.. If it doesn't work.. I'll try 2 give you code... Don't run CCRepeatForever Loop on your layer itself.. :)
To avoud such actions you can simply schedule some method with needed interval. smth like
[self schedule: #selector(methodToBeCalled) interval: intervalInSeconds];
just don't forget to unschedule it later

Best way for z-ordering sprites on isometric map with cocos2d

after few headaches i figured out that using CCSpriteBatchNode with cocos2d olny allows to z-order sprites added to it as child (which is obvious, now i see..)
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"token_default.plist"];
CCSpriteBatchNode *tokenSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"token_default.png"];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"objects_default.plist"];
CCSpriteBatchNode *objectsSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"objects_default.png"];
CCSprite *token = [[[CCSprite alloc] initWithSpriteFrameName:#"token_SE.png"] autorelease];
[token setPosition:tokenSpawnPoint];
CCSprite *enemy = [[[CCSprite alloc] initWithSpriteFrameName:#"token_blak_SE.png"] autorelease];
[enemy setPosition:enemySpawnPoint];
CCSprite *houseA = [[[CCSprite alloc] initWithSpriteFrameName:#"house_small.png"] autorelease];
[houseA setPosition:[self randomHousePosition]];
CCSprite *houseB = [[[CCSprite alloc] initWithSpriteFrameName:#"house_big.png"] autorelease];
[houseB setPosition:[self randomHousePosition]];
[tokenSpriteSheet addChild:token];
[tokenSpriteSheet addChild:enemy];
[objectsSpriteSheet addChild:houseA];
[objectsSpriteSheet addChild:houseB];
and since i have to add them to the display list as follows..
[_isoMap addChild:objectsSpriteSheet];
[_isoMap addChild:tokenSpriteSheet];
there is no way i can change the z-order of single tokens between other houses...
they will be always rendered over the house until i change the order of these batch nodes
btw, i can "merge" all sprites' arts in one big single batch node... doing so it became possible to order sprites using sprite's coordinates
[fullSpriteSheet reorderChild:token z:token.position.y];
i'm a little stuck with it...... is there a way to achieve that, having different sprite bacth nodes? or is possible to programmatically merge two batchnodes? (or something like that)
i found KnightFight, a really interesting open project on github by LozArcher.. he used CCSpriteFrame and CCSprite's setDisplayFrame method, instead of batch nodes... but i can't run it since it seems to be an older version of cocos2d (apparently not working with xcode 4)
i found out that changing the vertexZ property of a CCNode (like a CCSprite) it actually changes its Z position (so it will be slightly bigger/smaller, and also translated)
so, in order to arrange on z-index CCSprites with different spriteSheet i had to use reorderChild method (to just change the rendering order) and mostly i need NOT TO USE CCSpriteBatchNode..
after a little refactoring of the above example, i should have:
CCSprite *token = [CCSprite spriteWithSpriteFrameName:#"token_SE.png"];
[token setPosition:tokenSpawnPoint];
CCSprite *enemy = [CCSprite spriteWithSpriteFrameName:#"token_blak_SE.png"];
[enemy setPosition:enemySpawnPoint];
CCSprite *houseA = [CCSprite spriteWithSpriteFrameName:#"house_small.png"];
[houseA setPosition:[self randomHousePosition]];
CCSprite *houseB = [CCSprite spriteWithSpriteFrameName:#"house_big.png"];
[houseB setPosition:[self randomHousePosition]];
[_isoMap addChild:token];
[_isoMap addChild:enemy];
[_isoMap addChild:houseA];
[_isoMap addChild:houseB];
i also added each sprite to a NSMutableArray
and then in a for loop (inside the update scheduled method):
CCSprite *sprite = [mySpritesArray objectAtIndex:i];
[_isoMap reorderChild:sprite z:(_isoMap.mapSize.height - sprite.y)];
hope this could help someone :)
I still think that is not better solution,
if your objects on map are moving dynamically, you can still stuck in z order issues.
I know its very old post, and people keep coming here by google search,
so I am posting solution here.
float lowestZ = tilemap.map.width +tilemap.map.height ;
float currentZ = self.gridLocation.x + self.gridLocation.y ;
int zOrderDecided = lowestZ + currentZ - 1 ;
[self.parent reorderChild:self z:zOrderDecided];
Set the Sprites Z order to it's Y position on the map. Reorder your dynamic sprites in an update loop. Calculate the Z order using the Sprites current Y position and the visible height of the map.
void LocalGameController::SetZOrderForObject(cocos2d::Sprite *object){
int objectZOrder = visibleSize.height - object->getPositionY();
context->reorderChild(object, objectZOrder);
}

cocos2d hide/show sprites with animation

i am spending a lot for my time for a simple things i think.I want to hide and show a sprite
in scene.
myS = [CCSprite spriteWithFile:#"Background_Pause_pad.png"];
[myS setPosition:ccp(384,470)];
myS.opacity = 0;
[self addChild:myS z:1];
and when i need to appear it..
[myS runAction:[CCFadeIn actionWithDuration:1]];
and hide it
[myS runAction:[CCFadeOut actionWithDuration:1]];
but it does not work.....can anyone plz help??
Why do you use a Sequence for one action ?
You have to choose the animation you want !
E.g : if you choose CCFadeIn
[mySprite runAction:[CCFadeIn actionWithDuration:0.5f]];
I think you can try the below stuff of the code. It would work for you
id action1 = [CCFadeIn actionWithDuration:1];
id action2 = [CCDelayTime actionWithDuration:1];
id action3 = [CCFadeOut actionWithDuration:1];
[myS runAction:[CCSequence actions:action1,action2,action3,nil]];
As you need the fadein fadeout action it would generate it and display the Same.