PascalCzasny
PascalCzasny

Reputation: 11

How to exclude positions in a field in SpriteKit?

I have a function that spawns little balls, randomly positioned, on the screen. The problem I face is that I want to distribute the balls randomly, but when I do so, some balls spawn on top of each other. I want to exclude all the positions that are already taken (and maybe a buffer of a few pixels around the balls), but I don't know how to do so. I worked around this by giving the balls a Physicsbody, so they move off from one another if they happen to spawn on top of each other. But I want them to not spawn on top of each other in the first place. My code for now is the following:

    spawnedBalls = [Ball]()
    level = Int()
    
    func setupLevel() {
            
        let numberOfBallsToGenerate = level * 2
        let boundary: CGFloat = 26
        let rightBoundary = scene!.size.width  - boundary
        let topBoundary   = scene!.size.height - boundary
        
        while spawnedBalls.count < numberOfBallsToGenerate {
            
            let randomPosition = CGPoint(x: CGFloat.random(in: boundary...rightBoundary), y: CGFloat.random(in: boundary...topBoundary))
            
            let ball = Ball()
            ball.position = randomPosition
            ball.size = CGSize(width: 32, height: 32)
            
            ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width)
            ball.physicsBody?.affectedByGravity = false
            ball.physicsBody?.allowsRotation = false
            ball.physicsBody?.categoryBitMask = 1
            ball.physicsBody?.collisionBitMask = 1
            
            spawnedBalls.append(ball)
            self.addChild(ball)
            
        }
        
    }

I don't know if this problem should be solved by having an array that stores all taken positions, or if I should use some kind of FiledNode, where occupied space can be sort of subtracted, but sadly I am unfamiliar with FieldNodes, so I don't know if that's the right way to face the problem.

Upvotes: 0

Views: 22

Answers (1)

Shadowrun
Shadowrun

Reputation: 3867

Step 1) Replace

let randomPosition = ....

with

let randomPosition = randomPositionInOpenSpace()

Step 2) Write the randomPositionInOpenSpace function:

Idea is: a) generate a random position b) is it in open space? if so return that c) repeat until OK

Then Step 3) write the 'is it in open space' function

For that you need to know if the proposed coordinate is near any of the other balls. For circles, you can test the distance between their centers is greater than (radiuses + margins). Distance between centers is pythagoras: sqrt of the x delta squared plus the y delta squared.

Upvotes: 0

Related Questions