hugo
hugo

Reputation: 13

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 :

https://i.sstatic.net/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...

Upvotes: 0

Views: 1529

Answers (2)

drewish
drewish

Reputation: 9380

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

Upvotes: 0

Felix
Felix

Reputation: 35394

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

Upvotes: 1

Related Questions