Kio Coan
Kio Coan

Reputation: 581

NodesAtPoint does not find a node

I'm trying to create 10 balloons in my app. I create a random CGPoint to set my node's position and check, in case that already exist a node at this point I try again.

I don't know why, the balloons keep being placed over another balloon. Any ideia of what I am doing wrong?

Here is my code:

-(void)gerarBaloes:(int)quantidade
{
    balloons = [NSMutableArray new];
    u_int32_t maxHorizontal = 900;
    u_int32_t minHorizontal = 100;
    u_int32_t maxVertical = 650;
    u_int32_t minVertical = 100;
    for (int i=1; i<= quantidade; i++) {
        CGPoint posicao = CGPointMake(arc4random_uniform(maxHorizontal - minHorizontal + 1) + minHorizontal, arc4random_uniform(maxVertical - minVertical + 1) + minVertical);
        while (![self validPosition:posicao]) {
            posicao = CGPointMake(arc4random_uniform(maxHorizontal - minHorizontal + 1) + minHorizontal, arc4random_uniform(maxVertical - minVertical + 1) + minVertical);
        }
        balao* nBalao = [[balao alloc]initWithPosition:posicao];
        SKLabelNode* numero = [[SKLabelNode alloc]initWithFontNamed:@"Arial Rounded MT Bold"];
        numero.text = [NSString stringWithFormat:@"%d",i];
        numero.zPosition = 1;
        nBalao.body.zPosition = 0;
        [nBalao addChild:numero];
        nBalao.body.name = @"balloon";
        [balloons addObject:nBalao];
        [self addChild:nBalao];
    }
}

And this is my validation method:

-(BOOL)validPosition:(CGPoint)position
{
    NSArray* nodes = [self nodesAtPoint:position];
    NSLog(@"total de nodes %d",nodes.count);
    if (nodes.count > 0) {
        for (SKNode* n in nodes) {
            if ([n isKindOfClass:[balao class]]) {
                return NO;
            }
        }
        return YES;
    }else{
        return YES;
    }
}

Balao.m class:

@implementation balao

-(id)initWithPosition:(CGPoint)pos
{
    if (self = [super init]) {
        self.position = pos;
        int n = arc4random_uniform(4);
        _balloonAtlas = [SKTextureAtlas atlasNamed:[NSString stringWithFormat:@"balloon%d",n]];
        _explosionFrames = [NSMutableArray array];
        int numImages = _balloonAtlas.textureNames.count;
        for (int i=1; i<= numImages; i++){
            NSString *textureName = [NSString stringWithFormat:@"balloon_%d",i];
            SKTexture *temp = [_balloonAtlas textureNamed:textureName];
            [_explosionFrames addObject:temp];
        }
        SKTexture *textInicial = [_explosionFrames[0] copy];
        [_explosionFrames removeObjectAtIndex:0];
        self.body = [SKSpriteNode spriteNodeWithTexture:textInicial];
        [self addChild:_body];
    }
    return self;
}

- (void)explodeBalloon
{
    SKAction* explosao = [SKAction animateWithTextures:_explosionFrames timePerFrame:0.02f resize:NO restore:YES];
    [self.body runAction:explosao completion:^(void){
        [self removeFromParent];
    }];
    [self runAction:[SKAction playSoundFileNamed:@"popSound.mp3" waitForCompletion:NO]];
}

This is how the balloons appears:

Balloons

Edit: I tried the suggested method, with CGRectCointainsPoint, but it didn't work too. :/

enter image description here

Upvotes: 0

Views: 179

Answers (1)

rakeshbs
rakeshbs

Reputation: 24572

Checking for nodes at a given point is not enough to prevent overlap. You need to check whether the point falls inside the frame of another balloon. You can modify the function like this

-(BOOL)validPosition:(CGPoint)position
{
    NSArray* nodes = [self children];
    if (nodes.count > 0) {
        for (SKNode* n in nodes) {
            if ([n isKindOfClass:[balao class]]) {
                if (CGRectContainsPoint([n getBalloonFrame], position)) // Changed line
                {
                    return NO
                }
            }
        }
        return YES;
    }
    return YES;

}

CGRectContainsPoint checks whether a given rectangle contains a point.

Inside balao class define the following function. Also note the changed line in the above code.

-(void)getBalloonFrame
{
    return CGRectOffset(self.body.frame, self.frame.origin.x, self.frame.origin.y)
} 

Upvotes: 1

Related Questions