I want to move sprite body when i touch screen but it cant happen...
-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
for(b2Body *b=world->GetBodyList();b;b=b->GetNext())
{
CGPoint location=[touch locationInView:[touch view]];
location=[[CCDirector sharedDirector]convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
if(b->GetUserData()!=NULL)
{
CCSprite *sprite =(CCSprite *)b->GetUserData();
b->SetTransform(b2Vec2(location.x, location.y), 0);
id action = [CCMoveTo actionWithDuration:0.4 position:CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO)];
[sprite runAction:action];
}
}
}
please help me...
thanks
Please try the below code it would work for you.
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
for(b2Body *b=world->GetBodyList();b;b=b->GetNext())
{
if(b->GetUserData()!=NULL)
{
CCSprite *sprite =(CCSprite *)b->GetUserData();
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
b->SetTransform(b2Vec2(locationWorld.x, locationWorld.y), 0);
id action = [CCMoveTo actionWithDuration:0.4 position:CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO)];
[sprite runAction:action];
}
}
}
}
The sprite with the body moves to a location where the touch is Ended.
add self.isTouchEnabled = YES; in your init method
Related
I have 20 sprites in my scene which I've added to a NSMutableArray. My problem is that when I drag one sprite over another, the other also moves. How do I restrict the movement of untouched sprites?
Please help me with code (I am new to Cocos2d).
if( (self=[super init])) {
collection=[[NSMutableArray alloc]init];
CCLayer *base=[CCSprite spriteWithFile:#"Base.png"];
base.position=ccp(512,384);
[self addChild:base];
x=0;
for(int i=1;i<=7;i++)
{
CCSprite *hole=[CCSprite spriteWithFile:#"ball.png"];
hole.position=ccp(140+x,318);
hole.tag=i;
[self addChild:hole];
hole.visible=YES;
[collection addObject:hole];
x=x+75;
}
self.isTouchEnabled=YES;
}
return self;
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"count:%i",[collection count]);
UITouch *touch=[touches anyObject];
CGPoint location=[touch locationInView:[touch view]];
location=[[CCDirector sharedDirector]convertToGL:location];
location=[self convertToNodeSpace:location];
for(CCSprite *s in collection)
{
if(CGRectContainsPoint([s boundingBox], location))
s.position=ccp(location.x,location.y);
return;
}
}
You can do that:
Declare this in interface .h file
CCSprite *mSpriteOnHand;
CGPoint mLastPos;
Inside init assign it to nil.
mSpriteOnHand = nil;
In touchesBegan method check like this
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
for(CCSprite *s in collection)
{
if(CGRectContainsPoint([s boundingBox], location))
{
mLastPos = s.position;
s.position=ccp(location.x,location.y);
mSpriteOnHand = s;
break;
}
}
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint location=[touch locationInView:[touch view]];
location=[[CCDirector sharedDirector]convertToGL:location];
location=[self convertToNodeSpace:location];
if(mSpriteOnHand)
{
mSpriteOnHand.position = location;
}
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if(mSpriteOnHand)
{
mSpriteOnHand.position = mLastPos;
mSpriteOnHand = nil;
}
}
Im trying to get my sprite to move on touch but seems to disappear on touch then reappear on second touch . I do not know how to fix this to get my sprite to move at the direction I tap. I have been trying to figure this out for a while but seems I am out of luck. I am hoping someone can point me at the right direction.
CGSize winSize = [[CCDirector sharedDirector] winSize];
player = [CCSprite spriteWithFile:#"Player.png"
rect:CGRectMake(0, 0, 27, 40)];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player z:1];
(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
-(void)setPlayerPosition:(CGPoint)position {
player.position = position;
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];
CGPoint playerPos = player.position;
CGPoint diff = ccpSub(touchLocation, playerPos);
if (abs(diff.x) > abs(diff.y)) {
if (diff.x > 0) {
playerPos.x += contentSize_.width;
} else {
playerPos.x -= contentSize_.width;
}
} else {
if (diff.y > 0) {
playerPos.y += contentSize_.height;
} else {
playerPos.y -= contentSize_.height;
}
}
The syntax of your touch function seems to be different.
try this code instead
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
CGPoint playerPos = player.position;
}
I have made a code for scrolling a background in Cocos2d to create an effect of a camera, but I cant prevent the camera going beyond the edges of my background. My background is an image that is 1440*1080. My code is:
+(id) scene
{
CCScene* scene = [CCScene node];
TileDemo* layer = [TileDemo node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if ((self = [super init]))
{
self.isTouchEnabled = YES;
CCSprite *Nivel1 = [CCSprite spriteWithFile:#"Nivel1.png"];
Nivel1.position = ccp(0.5f, 0.5f);
[self addChild:Nivel1 z:0 tag:1];
}
return self;
}
-(void) dealloc
{
[super dealloc];
}
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event
{
return YES;
}
-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent*)event
{
}
-(void) ccTouchCancelled:(UITouch*)touch withEvent:(UIEvent*)event
{
}
-(void) ccTouchMoved:(UITouch*)touch withEvent:(UIEvent*)event
{
CGPoint touchLocation = [touch locationInView: [touch view]];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
CGPoint diff = ccpSub(touchLocation,prevLocation);
CCNode* node = [self getChildByTag:1];
CGPoint currentPos = [node position];
[node setPosition: ccpAdd(currentPos, diff)];
}
#end
you have to calculate maximum and minimum posiible position of your sprite and check it in your touchMoved:withEvent: method. On my mind, it is easier to calculate these values, when anchorPoint of your sprite is in (0.f, 0.f), instead of standard (0.5f, 0.5f). then your positions will be
CGPoint maxPos = ccp(0.f, 0.f);
CGPoint minPos = ccp((spriteWidth - screenWidth) * (-1), (spriteHeight - screnHeight) * (-1));
then just check if your sprite's new position is in valid range before set it.
I have two hands on either side of the screen that do not move at all and two thumbs that rotate 360 degrees. I want to limit the thumbs rotation, meaning I only need them to be able to rotate like normal thumbs. I am new to cocos2d so any help will be greatly appreciated. Here is what I have so far
#import "cocos2d.h"
#interface GameScene : CCLayer {
CGFloat lthumbRotation, rthumbRotation;
CCSprite *lthumb, *rthumb;
}
+(CCScene *) scene;
#end
------------------------------------
#import "GameScene.h"
#implementation GameScene
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
GameScene *layer = [GameScene node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if ((self = [super init]))
{
lthumb = [CCSprite spriteWithFile:#"lthumb.png" rect:CGRectMake(0,0, 145, 59)];
lthumb.position = ccp(100, 140);
lthumb.anchorPoint = ccp(0.3, 0.8);
[self addChild:lthumb z:0];
rthumb = [CCSprite spriteWithFile:#"rthumb.png" rect:CGRectMake(0,0, 145, 59)];
rthumb.position = ccp(380, 140);
rthumb.anchorPoint = ccp(0.7, 0.8);
[self addChild:rthumb z:0];
[self scheduleUpdate];
}
return self;
}
-(void)update:(ccTime)delta
{
lthumb.rotation = lthumbRotation;
rthumb.rotation = rthumbRotation;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//acquire the previous touch location
CGPoint firstLocation = [touch previousLocationInView:[touch view]];
CGPoint location = [touch locationInView:[touch view]];
//preform all the same basic rig on both the current touch and previous touch
CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];
CGPoint firstVector = ccpSub(firstTouchingPoint, rthumb.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, rthumb.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
//keep adding the difference of the two angles to the dial rotation
lthumbRotation += currentTouch - previousTouch;
rthumbRotation -= currentTouch - previousTouch;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void) dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[super dealloc];
}
#end
This lets both of the thumbs move at the same time in upward/downward angles with the anchor point at the bottom of the thumbs(acting like a joint).
I also need the thumbs rotation to reset back to 0 once the touches have ended.
Thanks in advance
In your ccTouchesMoved:withEvent: method, simply check to see if the new rotation is within a given threshold before applying it to your sprites.
Finally, in ccTouchesEnded:withEvent:, you can simply set the rotation values back to 0:
lthumbRotation = 0;
rthumbRotation = 0;
I was following Ray`s tutorial for making a simple iPhone game (here: http://goo.gl/fwPi) , and decided that i wanted the enemies to be eliminated when they get touched.
My initial approach was to spawn a small CCSprite sprite on the touch location, then use CGRectMake to create a bounding box of said sprite to detect if the enemy sprite was touched. Much like Ray does with the projectile/enemy. But of course, my way of doing it isnt working and i cant dig myself out of this hole.
Here is the relevant code snippet. Any help is appreciated:
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace: touch];
location = [[CCDirector sharedDirector] convertToGL:location];
CCSprite *touchedarea = [CCSprite spriteWithFile:#"Icon-72.png" rect:CGRectMake(location.x, location.y, 2, 2)];
touchedarea.tag = 2;
[self addChild:touchedarea];
[_touchedareas addObject:touchedarea];
}
- (void)update:(ccTime)dt {
NSMutableArray *touchedareasToDelete = [[NSMutableArray alloc] init];
for (CCSprite *touchedarea in _touchedareas) {
CGRect touchedareaRect = CGRectMake(
touchedarea.position.x,
touchedarea.position.y,
touchedarea.contentSize.width,
touchedarea.contentSize.height);
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target in _targets) {
CGRect targetRect = CGRectMake(
target.position.x - (target.contentSize.width/2),
target.position.y - (target.contentSize.height/2),
target.contentSize.width,
target.contentSize.height);
if (CGRectIntersectsRect(touchedareaRect, targetRect)) {
[targetsToDelete addObject:target];
}
}
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
}
if (targetsToDelete.count > 0) {
[touchedareasToDelete addObject:touchedarea];
}
[targetsToDelete release];
}
for (CCSprite *touchedarea in touchedareasToDelete) {
[_touchedareas removeObject:touchedarea];
[self removeChild:touchedarea cleanup:YES];
}
[touchedareasToDelete release];
}
That looks like a very difficult way to go about doing it. I havent been coding long myself but maybe the following might help you.
lets say u have a nsmutablearray called enemies and you add the new enemy object to this array when ever you create one. enemy object would be a ccnode and have a ccsprite within it called _enemySprite
then do the touch
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
//UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
int arraysize = [enemies count];
for (int i = 0; i < arraysize; i++) {
if (CGRectContainsPoint( [[[enemies objectAtIndex:i] _enemySprite] boundingBox], location)) {
//some code to destroy ur enemy here
}
}
// NSLog(#"TOUCH DOWN");
}
hope this helps
Another way of doing it is that calculating distance between touch position and your sprites.. If touch is close enough to one of your sprites, you can kill it.. Something like this..
for (CCSprite *sprite in anArrayThatCOntainsAllYourSprites) {
float distance = pow(sprite.position.x - location.x, 2) + pow(sprite.position.y - location.y, 2);
distance = sqrt(distance);
if (distance <= 10) {
sprite.dead = YES;
}
}