How to set physics body for a sprite with rounded

2019-08-11 17:30发布

I have created a SKShapeNode in the following way,

let sprite = SKShapeNode(rect: CGRect(x: -20, y: -10, width: 40, height: 20), cornerRadius: 10)

I also set a physics body like so,

sprite.physicsBody = SKPhysicsBody(rectangleOf: sprite.frame.size)

but I realized that the collisions and contacts weren't precise, so I changed showsPhysics to true and got the following. How can I make the physics body precise, even for the rounded corners?

enter image description here

3条回答
霸刀☆藐视天下
2楼-- · 2019-08-11 17:49

Remember that too much precision is very bad for performance. Read this: https://developer.apple.com/reference/spritekit/skphysicsbody

For general cases, it would be better to ignore the corners and stick with the normal rectangle physics, unless you REALLY need that precision. If you do, you could use a SKTexture on a SKSpriteNode instead of a ShapeNode. That would be much easier, because you could simply do this:

let size = CGSize(width: 100, height: 50)
let roundedRectangleTexture = SKTexture(image: UIImage(named: "textureImage")!)
let mySpriteNode = SKSpriteNode(texture: roundedRectangleTexture, size: size)
mySpriteNode.physicsBody = SKPhysicsBody(texture: roundedRectangleTexture, size: size)

With a texture, you can easily make a more detailed and precise physicsBody by simply using the SKPhysicsBody(texture: size:) constructor.

查看更多
forever°为你锁心
3楼-- · 2019-08-11 17:51

I would follow the documentation of SKPhysicsBody, and create a polygonal shape that approximates the rounded corners of your sprite.

An example on the documentation shows that you can define a polygonal physics body like so:

// Spaceship 3: polygonal physics body
let polygonalSpaceShip = SKSpriteNode(texture: spaceShipTexture)
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: -5, y: 37), CGPoint(x: 5, y: 37), CGPoint(x: 10, y: 20),
                        CGPoint(x: 56, y: -5), CGPoint(x: 37, y: -35), CGPoint(x: 15, y: -30),
                        CGPoint(x: 12, y: -37), CGPoint(x: -12, y: -37), CGPoint(x: -15, y: -30),
                        CGPoint(x: -37, y: -35), CGPoint(x: -56, y: -5), CGPoint(x: -10, y: 20),
                        CGPoint(x: -5, y: 37)])
path.closeSubpath()
polygonalSpaceShip.physicsBody = SKPhysicsBody(polygonFrom: path)
查看更多
Ridiculous、
4楼-- · 2019-08-11 18:02

From the documentation:

Maybe the #4 is your case

enter image description here

let spaceShipTexture = SKTexture(imageNamed: "spaceShip.png")

Spaceship 1: circular physics body

let circularSpaceShip = SKSpriteNode(texture: spaceShipTexture)
circularSpaceShip.physicsBody = SKPhysicsBody(circleOfRadius: max(circularSpaceShip.size.width / 2,
                                                                  circularSpaceShip.size.height / 2))  

Spaceship 2: rectangular physics body

let rectangularSpaceShip = SKSpriteNode(texture: spaceShipTexture)
rectangularSpaceShip.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: circularSpaceShip.size.width,
                                                                     height: circularSpaceShip.size.height))

Spaceship 3: polygonal physics body

let polygonalSpaceShip = SKSpriteNode(texture: spaceShipTexture)
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: -5, y: 37), CGPoint(x: 5, y: 37), CGPoint(x: 10, y: 20),
                        CGPoint(x: 56, y: -5), CGPoint(x: 37, y: -35), CGPoint(x: 15, y: -30),
                        CGPoint(x: 12, y: -37), CGPoint(x: -12, y: -37), CGPoint(x: -15, y: -30),
                        CGPoint(x: -37, y: -35), CGPoint(x: -56, y: -5), CGPoint(x: -10, y: 20),
                        CGPoint(x: -5, y: 37)])
path.closeSubpath()
polygonalSpaceShip.physicsBody = SKPhysicsBody(polygonFrom: path)

Spaceship 4: physics body using texture’s alpha channel

let texturedSpaceShip = SKSpriteNode(texture: spaceShipTexture)
texturedSpaceShip.physicsBody = SKPhysicsBody(texture: spaceShipTexture,
                                              size: CGSize(width: circularSpaceShip.size.width,
                                                           height: circularSpaceShip.size.height))
查看更多
登录 后发表回答