CCMenuItemImages positioning? - iphone

I am new to cocos2d and I'm trying to build a simple word game. I am stuck with some doubts.
I have arranged the letter's images at bottom of the screen. I've used CCMenuItemImage as buttons and arranged them. No way when I click the images individually, the letters should move to first position and second, and so on. For example:
if there is some letters like b, u, t, x, y, z and if I click on any letters then it should move to some location like (200, 300) (first position) and then second position. Then third... so on.
How should I do it?? I'm a noob so explain properly. Please help!!
Thanks in advance!!

You would want to make your CCMenuItemImage have a selector to target a helper function to help move your CCMenuItemImage. Within the helper function you'd have your CCMenuItemImage moving code.
To move your CCMenuItemImage you can study/copy the cocos2d-iphone project example's ActionsTest.
You can use CCMoveTo or CCMoveBy to move your CCMenuItemImage.
The actions are defined with a duration and a target position. There are some differences between CCMoveTo and CCMoveBy. The significant one is CCMoveBy can be 'reversed' to get a reversed action for your action. Example below moves grossini to ccp(80,80) and the reverse actionByBack moves it back to it's original position. The following code can be found in the ActionsTest.m file of your cocos2d-iphone project. It defines the movement of 3 sprites, tamara, grossini and kathia.
CGSize s = [[CCDirector sharedDirector] winSize];
id actionTo = [CCMoveTo actionWithDuration: 2 position:ccp(s.width-40, s.height-40)];
id actionBy = [CCMoveBy actionWithDuration:2 position: ccp(80,80)];
id actionByBack = [actionBy reverse];
[tamara runAction: actionTo];
[grossini runAction: [CCSequence actions:actionBy, actionByBack, nil]];
[kathia runAction:[ CCMoveTo actionWithDuration:1 position:ccp(40,40)]];
So in your case, if your CCMenuItem is called _alphabet1 you can use the actionBy action definition example to do the following
[_alphabet1 runAction: [CCSequence actions:actionBy, actionByBack, nil]];
That will send your _alphabet1 CCMenuItemImage to ccp(80,80) within 2 seconds and reverse back to the origin in 2 seconds.
If you just want to move your CCMenuItem to a position and not reverse, just use CCMoveTo.

Related

cocos-2d: Randomly Falling Blocks

so I want to randomly create falling blocks. The blocks can be GRects or Sprites, I just have no clue how to go about it.
I need to both randomly choose a time to call the createBlock function. Then I need it to create a block at the top of the screen that falls to the bottom off the screen. The end result should be an endless flow of blocks falling off the screen. I'm less concerned with the random interval part and more concerned with getting as many blocks as I need to fall.
Thanks in advance!
Well, assuming you have a basic understanding of how cocos2d operates (layers, scenes, children, etc), this is how you might go about it.
CGSize winSize = [[CCDirector shareDirector] winSize];
CCSprite *block = [CCSprite spriteWithFile:#"block.png"];
// Generate a random x position
CGFloat x = arc4random() % winSize.width;
// Position the block at a random x, just above the top of the screen
block.position = ccp(x, winSize.height + block.contentSize.height/2);
// Tell the block to fall down to the bottom of the screen over 2 seconds
CCMoveTo *fall = [CCMoveTo actionWithDuration:2 position:ccp(block.position.x, 0 - block.contentSize.height/2)];
[block runAction:fall];
If you wanted this to occur in a constant stream of blocks, you can setup a callback function to call your "createBlock" function every so often. It's not very efficient to constantly recreate blocks, but it's more simple than maintaining a list of off-screen blocks and moving them up to the top to fall again when necessary.
CCSequence *rainBlocks = [CCSequence actions: [CCCallBlock actionWithBlock:^{
[self createBlock];
}],
[CCDelayTime actionWithDuration:3],
nil]];
[self runAction:[CCRepeatForever actionWithAction:rainBlocks]];
I'm not 100% on the syntax there, but that's the general idea.

How to implement camera flyby in Cocos2d

Let's say the width of a level in my game is three times the screen width, and my player starts at the left most edge. How should I go about implementing a camera flyby starting from the right edge at the beginning of this level to scroll through the entire world so the player knows what to expect ahead?
I came across this post here http://www.cocos2d-iphone.org/forum/topic/9568 that seems to be useful, borrowed the block of code in it and put it in my GameWorldLayer, but it didn't work. I'm essentially only seeing a black screen. What's wrong? And what would be a better way of implementing this?
-(void)visit {
CGSize screenDims = [[CCDirector sharedDirector] winSizeInPixels];
CGPoint camPos = gameCamera.position;
float camZoom = gameCamera.zoom;
[[CCDirector sharedDirector] setProjection:kCCDirectorProjectionCustom];
//now set your projection
kmGLMatrixMode(KM_GL_PROJECTION);
//save current projection state
kmGLPushMatrix();
kmGLLoadIdentity();
kmMat4 orthoMat;
kmMat4OrthographicProjection(&orthoMat,
camPos.x -screenDims.width/(2*camZoom),
camPos.x +screenDims.width/(2*camZoom),
camPos.y +screenDims.height/(2*camZoom),
camPos.y -screenDims.height/(2*camZoom),
-1000,
1000);
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLLoadIdentity();
[super visit];
//put it back
kmGLMatrixMode(KM_GL_PROJECTION);
kmGLPopMatrix();
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLLoadIdentity();
}
All that is way to complicated for what you want. Position the layer at the end of the level at the beginning and then simply move it to the beginning i.e.
[layer runAction:[CCMoveTo actionWithDuration:10 position:ccp(starty, startx)]];
Where 20 is the time you want it to take for the "flyby" and the position is the start position

How to move the PhysicsSprite in box2d

I am having a physicsSprite of kinematics body type and I want to move the body and sprite bit down and back to its position. I tried it like this Inside update method:
for (NSValue *bodyValue in [self getGoalPostBodiesList])
{
b2Body *gPBody = (b2Body *)[bodyValue pointerValue];
PhysicsSprite *pSprite =(PhysicsSprite *) gPBody->GetUserData();
NSLog(#"\n tag value of Sprite = %d",pSprite.tag);
if(pSprite == goal1)
{
pSprite.position = CGPointMake((gPBody->GetPosition().x)*32.0,(gPBody->GetPosition().y)*32.0);
float angle = gPBody->GetAngle();
pSprite.rotation = -(CC_RADIANS_TO_DEGREES(angle));
id moveDownAction = [CCMoveTo actionWithDuration:0.5 position:CGPointMake(pSprite.position.x,(pSprite.position.y )- 40)];
id moveUpAction = [CCMoveTo actionWithDuration:0.5 position:CGPointMake(pSprite.position.x,(pSprite.position.y )+ 40)];
CCSequence *seqAction = [CCSequence actions:moveDownAction,moveUpAction, nil];
[pSprite runAction:seqAction];
b2Vec2 pos = b2Vec2(pSprite.position.x/32.0, pSprite.position.y/32.0);
gPBody->SetTransform(pos, CC_DEGREES_TO_RADIANS(pSprite.rotation));
gPBody->SetLinearVelocity(b2Vec2(0.0f, 0.0f));
gPBody->SetAngularVelocity(0.0f);
}
}
Still the sprite is not changing its position.
Anyone's help will be deeply appreciated.
Thanks all,
MONISH
To summarize your code, you update the position of your sprite to reflect that of the body, start an animation, and then update the position of the body to correspond to the position of the sprite. So naturally, nothing should move here, since your CCMoveTo actions have not exerted any effect on your sprite yet.
Second, your update method may be called very often, like dozens of times per second, so the animation gets reset continously and will not make any visible progress.
To follow a consistent pattern, how about you set the velocity of your kinematic bodies. Also, update the position of your sprites to correspond to these bodies as you would do for dynamic bodies, but don't set the transformation of your bodies to correspond to their sprites.

Cocos2D CCNode position in absolute screen coordinates

I've been looking around for a while, and I have not been able to find an answer to this for some reason. It seems simple enough, but maybe I just can't find the right function in the library.
I have a scene with a layer that contains a bunch of CCNodes with each one CCSprite in them.
During the application, I move around the position of the main layer, so that I "pan" around a camera in a way. (i.e. I translate the entire layer so that the viewport changes).
Now I want to determine the absolute position of a CCNode in screen coordinates. The position property return the position relative to the parent node, but I really would like this transformed to its actual position on screen.
Also, as an added bonus, it would be awesome if I could express this position as coordinate system where 0,0 maps to the upper left of the screen, and 1,1 maps to the lower right of the screen. (So I stay compatible with all devices)
Edit: Note that the solution should work for any hierarchy of CCNodes preferably.
Every CCNode, and descendants thereof, has a method named convertToWorldSpace:(CGPoint)p
This returns the coordinates relative to your scene.
When you have this coordinate, flip your Y-axis, as you want 0,0 to be in the top left.
CCNode * myNode = [[CCNode alloc] init];
myNode.position = CGPointMake(150.0f, 100.0f);
CCSprite * mySprite = [[CCSprite alloc] init]; // CCSprite is a descendant of CCNode
[myNode addChild: mySprite];
mySprite.position = CGPointMake(-50.0f, 50.0f);
// we now have a node with a sprite in in. On this sprite (well, maybe
// it you should attack the node to a scene) you can call convertToWorldSpace:
CGPoint worldCoord = [mySprite convertToWorldSpace: mySprite.position];
// to convert it to Y0 = top we should take the Y of the screen, and subtract the worldCoord Y
worldCoord = CGPointMake(worldCoord.x, ((CGSize)[[CCDirector sharedDirector] displaySizeInPixels]).height - worldCoord.y);
// This is dry coded so may contain an error here or there.
// Let me know if this doesn't work.
[mySprite release];
[myNode release];

How do I animate a sprite using cocos2d?

I have a sprite which will move right,left and jump.
I need to add the action to a animated sprite ie an animated sprite should jump, turn right and left.
Can anyone please tell me how to do it with sample code.
This is quite simple with cocos2d code here:
Sprite *mySprite = [Sprite spriteWithFile#"mySprite.png"];
[mySprite setPosition:ccp(x,y)];
[self addChild:mySprite]; //This displays the Sprite in your layer
Now for the sequence you intend to do...
id moveRight = [MoveBy actionWithDuration:2 position ccp(x+k,y) //Where k is how much to the right you want it to go.
id moveLeft = [MoveBy actionWithDuration:2 position ccp(x-k,y)];
id jump = [JumpBy actionWithDuration:1 position:ccp (x,y) height:1 jumps:1];
id sequence = [Sequence actions:moveRight,moveLeft,jump,nil];
[mySprite runAction:sequence];
Hope that's clear.
-Oscar