José María
José María

Reputation: 3063

Avoid Sprite Kit nodes stacking each other

I'm a beginner developer and I'm making a game where two colored balls fall. You have to get the blue ones and avoid the red ones. Right now, the balls appear in a random point at the top of the screen, but sometimes some of the balls appear in top of other, and I would like to know if there's a way to detect that and avoid it on the code, because I have no idea on how I could achieve it. Thanks! If you need more info on something, feel free to ask it to me.

Upvotes: 0

Views: 213

Answers (2)

BSevo
BSevo

Reputation: 793

It might be better to have one SKNode just for balls and when adding new ball just go thru that node and check where are the balls.

//balls node variable in scene, SKNode *ballsNode,
//add this to init or other method:
//self.ballsNode = [SKNode node];
//[self addChild:self.ballsNode];
//
-(void)addRock
{
  SKSpriteNode *rock = [[SKSpriteNode alloc] initWithColor:[SKColor brownColor] size:CGSizeMake(8, 8)];
  CGFloat newRandomX;
  CGPoint ballPosition;
  BOOL positionIsOk = NO;
  while(!positionIsOk)
  {
    newRandomX = getRandomX();
    ballPosition = CGPointMake(newRandomX, yourYPos);
    for(SKSpriteNode *node in self.ballsNode.children)
    {
      if(!CGRectContainsPoint ( node.frame, ballPosition ))
      {
        positionIsOk = YES;
        break;
      }
      else
      {
        newRandomX = getRandomX();
        ballPosition = CGPointMake(newRandomX, yourYPos);
      }
    }
  }
  rock.position = ballPosition;
  [self.ballsNode addChild:rock];
}

This way you will go thru all balls and get the position so it does not collide with all of that balls.

Upvotes: 1

Basheer_CAD
Basheer_CAD

Reputation: 4919

You can make a static global variable that holds the previous x position of the last added ball, and check if the new created ball has the same value as the last one, then you can rerandom the position for the ball and check again. Example:

// here is the global variable declaration 
static float _lastRandomX = 0;

//this method creates a rock (you can call it addBall)
- (void)addRock
{
    SKSpriteNode *rock = [[SKSpriteNode alloc] initWithColor:[SKColor brownColor] size:CGSizeMake(8, 8)];
    rock.name = @"rock";

     // the work goes here
    CGFloat newRandomX = 0;
    while(_lastRandomBall == newRandomX) {
        newRandomX = getRandomX();
    }
    rock.position = CGPointMake(newRandomX, yourYPos);
    _lastRandomX = newRandomX
    [self addChild:rock];
}

// now here is the action calling this method
- (void)runAction {
SKAction *makeRocks = [SKAction sequence:@[
                                               [SKAction performSelector:@selector(addRock) onTarget:self],
                                               [SKAction waitForDuration:0.10 withRange:0.15]]];
    [self runAction:[SKAction repeatActionForever:makeRocks]];

.....
}

Upvotes: 0

Related Questions