a SPECIFIC sprite- touch detection - cocos2d-iphone

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 .

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];
}

How to Detect the CCSprite Touchevent getBoundingbox equals of CCTouches

I am new to COCOS2d. I am using ccsprite with animation as a button. Now i am struggle to detect the CCTouches and CCsprite getbounding box are equals for click event.
From this way you can achieve what you need and write this code in CCtouches___() :
ArrayList<CCSprite> animation= new ArrayList<CCSprite>();
CGPoint location = CCDirector.sharedDirector().convertToGL(CGPoint.ccp(event.getX(), event.getY()));
for (CCSprite target : animation){
if(CGRect.containsPoint((target.getBoundingBox()), location)){
//here what you want
}

Repeatedly move a box2d body in a similar way to moving CCSprites with CCRepeatForever

I've got a problem with my current project.
What I'd like to do is make a b2Body move up and down repeatedly. I already know how to do this with a CCSprite:
[paddle runAction:[CCRepeatForever actionWithAction:
[CCSequence actions:
[CCMoveTo actionWithDuration:1.0 position:ccp([paddle position].x,[paddle position].y+40)],
[CCMoveTo actionWithDuration:1.0 position:ccp([paddle position].x,[paddle position].y)],
nil
]]];
Can anybody help me do the same thing with a b2Body?
Thanks in advance!
You will have to implement the sequence yourself, which involves:
keeping track of the current target position
from the current position of the body, detect whether it has reached the target
if it has, change the target position
apply force, impulse or set velocity as necessary to move the body
You might be able to extend CCMoveTo to make your own class to do this... I would look into that first.
i've got it dude,
in almost explanation, every CCsprite move depend on b2body movement -that movement is placed at 'tick' method-.
in my case, i reverse that way, i move b2body according to CCsprite movement on tick method, so i give these code on tick method:
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
if (sprite.tag == 4 || sprite.tag == 5) {
b2Vec2 b2Position = b2Vec2(sprite.position.x/PTM_RATIO,
sprite.position.y/PTM_RATIO);
float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(sprite.rotation);
b->SetTransform(b2Position, b2Angle);
}
}
}

Moving Sprits location with location issue

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.

Is it possible to to re-initialize an object in cocos2d

I have a class named insect child of sprite.I have created a
instance of that class in GameLayer and then initialize with
it using,
insect *bgg = [insect spriteWithFile:#"bird2a.gif"];
then i set a timer(10 second) to change the image using
*bgg = [insect spriteWithFile:#"2.gif"];
but my program crashes.Now my question is it possible to
re-initialize an object or it is immutable??
I have another question, when i used
- (BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *) event
{
UITouch *touch = [touches anyObject];
CGPoint point2 = [touch locationInView:[touch view]];
CGPoint cpoint=[[Director sharedDirector] convertCoordinate:point2];
NSLog(#"In touch began");
}
in my insect class it cannot detect touch on 'bgg' object declared
in GameLayer.But when I used this function in GameLayer it can
detect touch.
whats wrong with my approach??Plz someone explain.
Advanced thanx for your reply.
Your program crashes because you have a typo. Remove the '*' from '*bgg'. That means you are dereferencing the pointer, then trying to apply the creation of a new object to the dereferenced pointer. You just want
bgg = [insect spriteWithFile:#"2.gif"];
However, it's overkill to create an entirely new sprite just to change the image. A Sprite is a subclass of TextureNode, so just use TextureNode's texture property to give a Sprite a different image.
Texture2D *newImage = [[TextureMgr sharedTextureMgr] addImage:#"2.gif"];
bgg.texture = newImage;