Moving Sprits location with location issue - cocos2d-iphone

When i move my layer that's contain all sprits by scrolling, sprits location does't change.i want's to change my sprits location with scrolling. please give me some solution for this.
Thanks in Advance......

// simple position update
CGPoint a = [[CCDirector sharedDirector] convertToGL:[touch previousLocationInView:touch.view]];
CGPoint b = [[CCDirector sharedDirector] convertToGL:[touch locationInView:touch.view]];
CGPoint nowPosition = scrollLayer.position;
nowPosition.y += ( b.y - a.y );
nowPosition.y = MAX( 0, nowPosition.y );
nowPosition.y = MIN(20, nowPosition.y);
scrollLayer.position = nowPosition;
My scrollLayer contain all the sprits. This is the code by which my layer moves to a new location. All sprits also move with the layer but their position does not change with respect to the layer moving. When i touch on that possition the sprits move. But I want to touch on sprits for moving them.

if you move a layer without moving its child sprites, the sprite.position will return the same value even after moving the layer because its returning it relative to node space (layer). To get the position of the sprite according to the world or your scene you need to convert it to world space:
CGPoint worldPosition = [self convertToWorldSpace:sprite.position];
i hope this answers your question because it wasnt very clear.

Related

Fixed sprite on the tile map cocos2d?

I can't figure out how to handle with tile map layer and other node. I want to make another one layer(CCNode) for such things as menu button, score, joystick that must always stay fixed(not scrolled), when the whole map is scrolled.
self.theMap=[CCTiledMap tiledMapWithFile:#"map.tmx"];
self.bgLayer=[theMap layerNamed:#"bg"];
[self addChild:theMap z:-1];
CCNode *joystickNode;
joystickNode=[CCNode node];
[bgLayer.parent addChild:joystickNode z:2];
upArrowFrame=[CCSpriteFrame frameWithImageNamed:#"uparrow.png"];
upArrow=[CCButton buttonWithTitle:#"" spriteFrame:upArrowFrame];
[upArrow setTarget:self selector:#selector(upArrowPressed)];
upArrow.position= ccp(190,190);
[joystickNode addChild:upArrow z:2];
Now upArrow is not visible on the screen at all. If I add to self instead of joystickNode, it will appear.
I can't even understand, what parent should new CCNode have. Can anyone explain it to me? I also tried to add new CCNode as a child of self and theMap.
EDIT: Oops, it's actually moving the camera. How to implement it in this case?
-(void)setCenterOfScreen :(CGPoint) position {
CGSize screenSize=[[CCDirector sharedDirector]viewSize];
int x=MAX(position.x, screenSize.width/2);
int y=MAX(position.y, screenSize.height/2);
x= MIN(x, theMap.mapSize.width * theMap.tileSize.width - screenSize.width/2);
y= MIN(y, theMap.mapSize.height * theMap.tileSize.height - screenSize.height/2);
CGPoint goodPoint =ccp(x,y);
CGPoint centerOfScreen = ccp(screenSize.width/2, screenSize.height/2);
CGPoint difference = ccpSub(centerOfScreen, goodPoint);
self.position=difference;
}
- (void)update:(CCTime)dt{
[self setCenterOfScreen:hero.position];
}

Cocos2d 3.0 Chipmunk with gravity: sprite position doesn't change

Porting my game from Cocos2d v2 to v3 I don't know when the sprites go out of screen.
In v2 my solution was:
-(void) update:(ccTime) delta
{
// Should use a fixed size step based on the animation interval.
int steps = 2;
CGFloat dt = [[CCDirector sharedDirector] animationInterval]/(CGFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space_, dt);
}
if (mySprite.getPhysicsBody->p.y > 500)
[mySprite resetPosition];
}
now with Cocos2d v3 mySprite.physicsNode.position doesn't change through the time.
Any idea or link with some example?
Thanks.
physicsNode.position doesn't change with time because it uses its parent sprite coordinate space, not the global coordinate space.
You can get the global position of any node, considering the Anchor Point, using this:
CGPoint worldPos = [node convertToWorldSpaceAR:CGPointZero];
After that you can easily convert it to any other node space if necessary (like your level, maybe) using:
CGPoint position = [_levelNode convertToNodeSpaceAR:worldPos];
But beware that you shouldn't hardcode the screen size on your code, as it varies for each device. You can use instead:
CGSize viewSize = [[CCDirector sharedDirector] viewSize];

CGRectContainsPoints and bounding box check is off by several pixels

I've been studying this for hours (2 days, actually) and just cannot figure out what is wrong. The touches are accepted and processing, but the isTouchHandled test is triggering TRUE prematurely; as if a different bounding box was touched than the one that is touched. I have several non-overlapping CCSprite buttons, with each pointed to in the levelButtons array. Iterate through to see which one is touched; but it's always the wrong one.
Does the CGRectContainsPoints method get thrown off if these sprites are in their own layer, which is then in another layer? In other words, is CGRectContainsPoints using raw equality of pixel locations as reported by position? If so, a sprite's position relative to the entire screen is different than its reported position if it is a child, which is relative to the parent. Maybe this has something to do with it? My array and the tags of its contents are correctly lining up, I've logged and checked that many times; it appears to be the bounding box check.
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
CCLOG (#"levelButtons size:%i",[self.levelButtons count]);
BOOL isTouchHandled = NO;
for (int i=0;i<25;i++){
CCSprite*temp=(CCSprite*)[self.levelButtons objectAtIndex:i];
CCLOG(#"iteration temp.tag: %i for object: %i",temp.tag,i);
isTouchHandled= CGRectContainsPoint([temp boundingBox], [[CCDirector sharedDirector] convertToGL:[touch locationInView: [touch view]]]);
if (isTouchHandled) {
CCLOG(#"level touched: %i",temp.tag);
break;
}
}
return isTouchHandled;
}
UPDATE: Incidentally, I also just subclassed CCSprite and add the touche methods to the individual sprites in this fashion ,taking my array of sprites out of the picture. The results were the same, so I suspect the CGRectContainsPoints is not properly working when your rect is a child of other children, the coordinates are not being reported correctly, I suspect.
I think it may be problem with an array that you are getting sprites. Any way , this is how i am using the code for getting the sprite tag.
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
for(int i1=0;i1<=25;i1++)
{
CCSprite *sprite1 = (CCSprite *)[self getChildByTag:i1];
if(CGRectContainsPoint([sprite1 boundingBox], location))
{
//Your Code
break;
}
}
I solved this by creating a new CGRect for the CGRectContainsPoint test, and translating the bounding box into the actual onscreen rectangle; the bounding box test will not work on its own if it is located on a child sprite (or layer). It returns its local position only, relative to the parent.

a SPECIFIC sprite- touch detection

since i havnt got an answer in my previos post, and no one solve that problem , i am asking this again. there is no 1 explanation regarding this.
i need to detect a sprite touch, a SPECIFIC one. in cocos2d+box2d.
lets say i have sprite CCSprite *ran that has a body, BUT , i have many of it .
if i detect a touch with the ccTouchesBegan , and use the if(CGRectContainsPoint(particularSpriteRect, currentPosition))
i will detect the touch in ran but i dont know who ran is this from all, and i need to destroy than specific ran , which i cant know who it was .
i find the best way to do that, as i do with contact listener that gives me the specific sprite user data :
CCSprite *actora = (CCSprite*)bodyA->GetUserData();
CCSprite *actorb = (CCSprite*)bodyB->GetUserData();
and then i know that actora is what needs to be destroy cause i have his user data.
[self removeChild:actora cleanup:YES];
so , again , i need to detect a sprite touch and KNOW who it was,cause i have many ran's.
i guess its something needs to involve the userData .
any direction please ?
thanks alot.
ok, i have got it :
this is what i do, to destroy the specific body, different from what was said here :
put the next code in the touch method :
CGPoint currentPosition = [touch locationInView: [touch view]];
currentPosition = [[CCDirector sharedDirector] convertToGL: currentPosition];
b2Vec2 locationWorld = b2Vec2(currentPosition.x/PTM_RATIO, currentPosition.y/PTM_RATIO);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
b2Fixture *bf1 = b->GetFixtureList();
if (bf1->TestPoint(locationWorld))
{
CCSprite *tempSprite = (CCSprite *) b->GetUserData();
if (tempSprite .tag==2 || tempSprite .tag==3)
{
[self removeChild:tempSprite cleanup:YES];
world->DestroyBody(b);
}
}
}
here if you touch the right sprite(tagged) , it get destroyed .

dragging sprite

I have a problem dragging a sprite i've got the sprite moving left and right while keeping the y position the same, but i can't get the sprite to move up or down when the x position stays the same.
Also in the cctouchended the sprite moves so that it is in a fixed position, when all touches have ended
I am trying to make a game like slidieo/skozzle. Could do with some help
c1 is the column that is being moved, r1 is the row that is being moved,
[pos objectAtIndex:0] is the sprite's:red1 position and checks if the sprite is in c1 as every time you go into the game the sprite has a new random position and t1 is the cgrect of the sprite so that you must be clicking on the spirte because if you don't when you click above the sprite and try moving the sprite jumps to the touchlocation.
here is my code:
CGPoint touchLocation = [touch locationInView:[touch view]];
CGPoint prevLocation = [touch previousLocationInView:[touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL:prevLocation];
if (CGRectContainsPoint(c1,touchLocation)) {
if (CGRectContainsPoint(c1,[[pos objectAtIndex:0]CGPointValue])) {
if (CGRectContainsPoint(t1,touchLocation)) {
if (touchLocation.y>0||touchLocation.y<0) {
touchLocation.x = red1.position.x;
[red1 setPosition:ccp(touchLocation.x,touchLocation.y)];
}
}
}
}
if (touchLocation.x>0||touchLocation.x<0) {
touchLocation.y=red1.position.y;
[red1 setPosition:ccp(touchLocation.x,touchLocation.y)];
}
}
thanks
i've solved the problem :) just had to remove a few if statements and edit a few, now i've got it moving up and down and when the sprite stops it can move left and right