Anilkumar iOS Developer
Anilkumar iOS Developer

Reputation: 3755

How to get Hexagon shape from SKPhysicsBody from SpriteKit framework

I am doing iOS app in swift. I want to show layout like Apple Music bubbles. And the below code is working fine to show that layout, but, I want to show Hexagon layout instead of circle bubble.

Can anyone suggest/guide me, how to show that Hexagonal layout instead of circle layout.

In Magnetic Class :

 func configure() {

         physicsWorld.gravity = CGVector(dx: 0, dy: 0)
         physicsBody = SKPhysicsBody(edgeLoopFrom: { () -> CGRect in
             var frame = self.frame
             frame.size.width = CGFloat(magneticField.minimumRadius)
             frame.origin.x -= frame.size.width / 2
             return frame
         }())
         let strength = Float(max(size.width, size.height))
         let radius = strength.squareRoot() * 100
         magneticField.region = SKRegion(radius: radius)
         magneticField.minimumRadius = radius
         magneticField.strength = strength
         magneticField.position = CGPoint(x: size.width / 2, y: size.height / 2)
     }

In Node Class :

public init(text: String?, image: UIImage?, color: UIColor, radius: CGFloat) {
    super.init(circleOfRadius: radius)

    self.physicsBody = {
        let body = SKPhysicsBody(circleOfRadius: radius + 2)
        body.allowsRotation = false
        body.friction = 0
        body.linearDamping = 3
        return body
    }()
    self.fillColor = .white
    self.strokeColor = .white
    _ = self.sprite
    _ = self.text
    configure(text: text, image: image, color: color)
}

Upvotes: 1

Views: 522

Answers (2)

AmandaR
AmandaR

Reputation: 81

expanding on KnightofDragon's answer, you can calculate the 6 points of a hexagon with the following psuedocode/math:

PI =  3.14159
for i in 0..<6 {
    theta = i*2.0*PI / n; // angle to the ith vertex, in radians (not degrees)
    x = radius * cos(theta)
    y = radius * sin(theta)
    vertex = centerPosition.x + x, centerPosition.y + y 
}

Upvotes: 2

Knight0fDragon
Knight0fDragon

Reputation: 16827

All you need to do is use a different initializer. You are using super.init(circleOfRadius: radius) To make a hexagon, just use super.init(path path:CGPath) Where path is a CGPath in the shape of a hexagon. (CGPath is simple to understand, just create it with 6 points in the shape of a hexagon, however large you need it) You can then take this path and give it to the physics body by doing let body = SKPhysicsBody(polygonFrom:path)

On a personal note, you may want to cut back on using closures the way you are doing it. (let physicsBody = {...}()) They are not guaranteed to fire immediately and could cause a concurrency problem. A better way to right it would be to do it in an if let statement:

if let body = SKPhysicsBody(circleOfRadius: radius + 2)
{        
    body.allowsRotation = false
    body.friction = 0
    body.linearDamping = 3
    self.physicsBody = body
}

Upvotes: 1

Related Questions