How To select all the targets with touches rect in cocos2d - iphone

i want to select my targets using touches rect
am creating my unselected dots by coding like these:-
targets1 = [[NSMutableArray alloc] init];
for(int i=0;i<3;i++)
{
for (int y=0; y<3; y++) {
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:#"UnselectedDot.png"];
block = [CCSprite spriteWithTexture:texture rect:CGRectMake(0,0,82,82)];
CGFloat xoffset = ((block.contentSize.width)*10) + (((block.contentSize.height)-175)*y);
block.position = ccp( (i*82)+80,xoffset);
[bg1 addChild:block];
[targets1 addObject:block];
}
}
below is my sample output .
now i need to select all the dots by touches method. i written coding like these:-
- (void)update:(ccTime)dt {
// NSLog(#"%#",targets1);
for (CCSprite *sprite in targets1) {
CGRect dotrect = CGRectMake(sprite.position.x,
sprite.position.y-95,
sprite.contentSize.width,
sprite.contentSize.height);
CGFloat x = location.x;
CGFloat y = location.y;
CGFloat width = (location1.x - location.x);
CGFloat height = -(location1.y - location.y);
CGRect touchrect = CGRectMake (x, y, width,height);
NSLog(#"dotrect = %f,%f,%f,%f",dotrect.origin.x,dotrect.origin.y,dotrect.size.width,dotrect.size.height );
NSLog(#"touch rect = %f,%f,%f,%f,%f,%f",touchrect.origin.x,touchrect.origin.y,touchrect.size.width,touchrect.size.height,location1.x,location1.y);
if( CGRectContainsRect(dotrect, touchrect))
{ //collision detection
NSLog(#"am touched dot ");
}
}
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
NSLog(#"am touched began");
return YES;
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
location1 = [touch locationInView:[touch view]];
location1 = [[CCDirector sharedDirector] convertToGL:location1];
location1 = [self convertToNodeSpace:location1];
}
as per above coding my concept is :- using touches began and touches ended am making rectangle here.. inside these touchrect my unselected dot rect came means collsison detected.. then i can do my stuffs there. but its not colliding all.
am not getting were am making mistake.
Edit :1
now i got why coillision not working... actually insidemy touches rect having multiple rect.. so only ... here, am using rectcontainsrect.. tahts the problem.. any other method to rect having several rect for colllsion detection..

Try using:
CGPoint location=[touch locationInView:[touch view]];
location = [self convertTouchToNodeSpace:touch];
CGRectContainsPoint([dot boundingBox], location);
inside the CCTouch.. methods (as you wish depending on what you want to do).

Related

curved line in cocos2d

I have to develop curved line in cocos2d.Curved is similler to finger rotaion that is some of top spirits curved as per touch location.
i have an array of 50 spirit point array.if we move first spirit (in code BG_Sprite3) , want to set 1st,2nd,3rd,....50th spirit position (in code BG_Sprite2)and rotation as per touchlocation .if we move more deep(IF Y IS LESS )then rotation and position of BG_Sprite2 is also change.just like a Finger bend and Finger rotation.
This is my code ..haft of code working.but not getting curved rotation of BG_Sprite2.
-(id) init
{
if( (self=[super init]))
{
aPoints = [[NSMutableArray alloc]init];
[self removeChild:BG_Sprite2 cleanup:YES];
int m=100,n=80;
for(int i=0;i<25;i++)
{
BG_Sprite2 = [CCSprite spriteWithFile:#"nodeConnectorWhite.png"];
BG_Sprite2.position = ccp(m,n);
m=m+5;
n=n+5;
BG_Sprite2.rotation=135;
[self addChild:BG_Sprite2];
[aPoints addObject:[NSValue valueWithCGPoint:ccp(m,n)]];
}
[self removeChild:BG_Sprite3 cleanup:YES];
BG_Sprite3 = [CCSprite spriteWithFile: #"connection_green.png"];//This is first spirit
BG_Sprite3.position=ccp(235, 215);
[BG_Sprite3 setRotation:135];
[self addChild:BG_Sprite3];
}
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = [touches anyObject];
NSMutableArray *apointsarray = [[NSMutableArray alloc]init];
CGPoint movedtouchLocation = [touch locationInView: [touch view]];
movedtouchLocation = [[CCDirector sharedDirector] convertToGL: movedtouchLocation];
int xDiff= movedtouchLocation.x-225;//angle between first spirit and touch location
int yDiff= movedtouchLocation.y-205;
for(int i=0;i<[aPoints count];i++)
{
float angle2 = atan2f(xDiff, yDiff);
angle2 = CC_RADIANS_TO_DEGREES(angle2); // convert to degrees
angle2 -= 90; // rotate
angle2 *= -1; // clockwise
BG_Sprite2 = [CCSprite spriteWithFile:#"nodeConnectorWhite.png"];
BG_Sprite2.position =movedtouchLocation;
[BG_Sprite2 setRotation:angle2];
[self addChild:BG_Sprite2];
}
}

objective-c iPhone game programming : detect touch on tile map object layer

hi made an object layer on my tile map with tile map editor like this :
http://i.stack.imgur.com/f5fZK.png
The big square represent my object layer named : ObjectIt.
My problem is when i touch the square in the simulator it doesn't correspond to the right place. Some people told me problem with float value or open gl but I'm noob i need clear answers .
This is my code :
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touch detect");
CCNode* node = [self getChildByTag:TileMapNode];
NSAssert([node isKindOfClass:[CCTMXTiledMap class]], #"not a CCTMXTiledMap");
CCTMXTiledMap* tileMap = (CCTMXTiledMap*)node;
// Get the position in tile coordinates from the touch location
CGPoint touchLocation = [self locationFromTouches:touches];
CGPoint tilePos = [self tilePosFromLocation:touchLocation tileMap:self.tileMap];
// Check if the touch was on water (e.g., tiles with isWater property)
bool isTouchOnWater = NO;
CCTMXObjectGroup* objectLayer = [tileMap objectGroupNamed:#"ObjectIt"];
bool isTouchInRectangle = NO;
int numObjects = [objectLayer.objects count];
for (int i = 0; i < numObjects; i++)
{
NSDictionary* properties = [objectLayer.objects objectAtIndex:i];
CGRect rect = [self getRectFromObjectProperties:properties tileMap:tileMap];
if (CGRectContainsPoint(rect, touchLocation))
{
isTouchInRectangle = YES;
break; }
}
if (isTouchInRectangle)
{
NSLog(#"TOUCH IN RECTANGLE");
// get the ALGORITH FOR TOWERS
}
}
-
(CGPoint) locationFromTouch:(UITouch*)touch
{
CGPoint touchLocation = [touch locationInView: [touch view]];
return [[CCDirector sharedDirector] convertToGL:touchLocation];
}
-(CGPoint) locationFromTouches:(NSSet*)touches
{
return [self locationFromTouch:[touches anyObject]];
}
-(CGRect) getRectFromObjectProperties:(NSDictionary*)dict
tileMap:(CCTMXTiledMap*)tileMap
{
float x, y, width, height;
x = [[dict valueForKey:#"x"] floatValue] + tileMap.position.x;
y = [[dict valueForKey:#"y"] floatValue] + tileMap.position.y;
width = [[dict valueForKey:#"width"] floatValue];
height = [[dict valueForKey:#"height"] floatValue];
return CGRectMake(x, y, width, height);
}
Thats the code , ill give you more if you need.
Also : when i run on the iPhone i got vertical black lines...
In order to get the correct touch location in Cocos2D points use this CCNode convenience method:
- (CGPoint)convertTouchToNodeSpace:(UITouch *)touch
{
CGPoint point = [touch locationInView: [touch view]];
point = [[CCDirector sharedDirector] convertToGL: point];
return [self convertToNodeSpace:point];
}
I'm not sure if it's been added to the API since phix23 posted their answer but the convertTouchToNodeSpace: method basically does the same thing:
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CCTMXTiledMap* tileMap = (CCTMXTiledMap*)[self getChildByTag:TileMapNode];
CGPoint p = [tileMap convertTouchToNodeSpace:touch];
// If you wanted to figure out which tile in a layer they touched (assuming
// it's Ortho) you could do something like this:
CCTMXLayer *layer = [tileMap layerNamed:#"Tile Layer 1"];
CGPoint q = {
(int) (p.x / tileMap.tileSize.width),
// World origin is bottom left but map coordinates are top left so flip
// the y.
layer.layerSize.height - (int) (p.y / tileMap.tileSize.height) - 1
};
CCSprite *s = [layer tileAt:q];
NSLog(#"Touched %#", s);
return YES;
}

Rotate image on center using one finger touch

I want to rotate the below image on a center point using one finger touch...
And i want to display the value of the image with the label when I rotate the image using touch.
I have done the image rotation but the problem is that how to set the value of the image according to rotation.
The angle of the rotation is increase so i can not set the value.
Can any one help me?
The code is below
float fromAngle = atan2(firstLoc.y-imageView.center.y,
firstLoc.x-imageView.center.x);
NSLog(#"From angle:%f",fromAngle);
float toAngle = atan2( currentLoc.y-imageView.center.y,
currentLoc.x-imageView.center.x);
NSLog(#"to Angle:%f",toAngle);
// So the angle to rotate to is relative to our current angle and the
// angle through which our finger moved (to-from)
float newAngle =angle+(toAngle-fromAngle);
NSLog(#"new angle:%.2f",newAngle);
CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle);
imageView.transform=cgaRotate;
angle = newAngle;
Can any one help me ?
Wasn't totally sure what you were after; but try out this code.
If you create a new View-based Application project called 'Rotation' and replace the code in RotationViewController.h and .m for the following you'll get a green block that you can rotate using your calculations. You can replace the green block UIView with your UIImageView, or anything else you want to spin.
RotationViewController.h
#import <UIKit/UIKit.h>
#interface RotationViewController : UIViewController
{
UIView* m_block;
UILabel* m_label;
CGPoint m_locationBegan;
float m_currentAngle;
}
- (float) updateRotation:(CGPoint)_location;
#end
RotationViewController.m
#import "RotationViewController.h"
double wrapd(double _val, double _min, double _max)
{
if(_val < _min) return _max - (_min - _val);
if(_val > _max) return _min - (_max - _val);
return _val;
}
#implementation RotationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect blockFrame = CGRectMake(0, 0, 200, 200);
m_block = [[UIView alloc] initWithFrame:blockFrame];
m_block.backgroundColor = [UIColor greenColor];
m_block.center = self.view.center;
[self.view addSubview:m_block];
[m_block release];
CGRect labelFrame = CGRectMake(0, 0, 320, 30);
m_label = [[UILabel alloc] initWithFrame:labelFrame];
m_label.text = #"Loaded";
[self.view addSubview:m_label];
}
- (void) touchesBegan:(NSSet *)_touches withEvent:(UIEvent *)_event
{
UITouch* touch = [_touches anyObject];
CGPoint location = [touch locationInView:self.view];
m_locationBegan = location;
}
- (void) touchesMoved:(NSSet *)_touches withEvent:(UIEvent *)_event
{
UITouch* touch = [_touches anyObject];
CGPoint location = [touch locationInView:self.view];
[self updateRotation:location];
}
- (void) touchesEnded:(NSSet *)_touches withEvent:(UIEvent *)_event
{
UITouch* touch = [_touches anyObject];
CGPoint location = [touch locationInView:self.view];
m_currentAngle = [self updateRotation:location];
}
- (float) updateRotation:(CGPoint)_location
{
float fromAngle = atan2(m_locationBegan.y-m_block.center.y, m_locationBegan.x-m_block.center.x);
float toAngle = atan2(_location.y-m_block.center.y, _location.x-m_block.center.x);
float newAngle = wrapd(m_currentAngle + (toAngle - fromAngle), 0, 2*3.14);
CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle);
m_block.transform = cgaRotate;
int oneInFifty = (newAngle*50)/(2*3.14);
m_label.text = [NSString stringWithFormat:#"Angle: %f 1in50: %i", newAngle, oneInFifty];
return newAngle;
}
#end

Multitouch don't work in cocos2d

This is my ccTouchesMoved method.
Whats wrong? I use cocos2d framework.
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CCNode *sprite = [self getChildByTag:kTagPlayer];
CCNode *sprite2 = [self getChildByTag:kTagEnemy];
CGPoint point;
//Собрать все касания.
NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches)
{
point = [touch locationInView:[touch view]];
point = [[CCDirector sharedDirector] convertToGL:point];
if (point.y > 384)
{
if (point.x > 992)
sprite2.position = ccp(992, size.height - 100);
else if (point.x < 32)
sprite2.position = ccp(32, size.height - 100);
else
sprite2.position = ccp(point.x, size.height - 100);
}
else
{
if (point.x > 992)
sprite.position = ccp(992, 100);
else if (point.x < 32)
sprite.position = ccp(32, 100);
else
sprite.position = ccp(point.x, 100);
}
}
}
Have you enabled multiple touches in your glView? By default the glView is instantiated in the app delegate. The code is below.
[glView setMultipleTouchEnabled:YES];
In case you're developing a Retina display App, be aware that all coordinates are in points, not pixels. So even on a Retina display with 960x640 pixels the coordinates in points (your touch location) will be in the range 480x320.
If you want to use pixels, use the "InPixels" version of all coordinates, in this case:
sprite.positionInPixels = ccp(992, 100);
If that's not the problem you should add to your post what the expected outcome is and what happens instead. A little context goes a long way.
What does the debugger say is in allTouches? You could try getting all the touches for the view like this instead:
UITouch* touch = [touches anyObject];
NSSet* allTouches = [touches setByAddingObjectsFromSet:[event touchesForView:[touch view]]];

Detecting if a specific sprite was touched on Cocos2d-iphone

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