efe_ertugrul

apple developer

home tech-notes github twitter stackoverflow dev.to

Getting Started with Physics Bodies


Create and assign a physics body to enable physics.

Overview

An SKPhysicsBody object defines the shape and simulation parameters for a physics body in the system. When the scene simulates physics, it performs the calculations for all physics bodies connected to the scene tree. So, you create an SKPhysicsBody object, configure its properties, and then assign it to a node’s physicsBody property.

There are three kinds of physics bodies:

SpriteKit provides a few standard shapes—those based on arbitrary paths and those generated from the alpha channel of a texture. The following figure shows the shapes available:

getting-started-with-physics-bodies-001

The following code shows how to generate the four physics bodies called out above:

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))

The shape of a physics body affects performance. A circular physics body offers the best performance and can be significantly faster than other physics bodies. If your simulation contains many physics bodies, circular bodies are the best solution. Rectangular and polygonal shapes improve collision accuracy with reduced speed. Physics bodies created from the alpha channel of a texture offer the best fidelity at the highest performance cost.

Create and Assign Physics Bodies

A physics body is created by calling one of the SKPhysicsBody class methods. Each class method defines whether a volume-based or edge-based body is being created and what shape it has. As soon as a node has its physics body set and is added to a scene, it begins to participate in the physics simulation. The following code shows how to create a simple scene containing a shape node that is the curvy ground and a sprite node—the rocket ship. The shape node’s physics body is created from its path and the sprite node’s physics body is created from the texture automatically generated by SpriteKit when the node was initialized. Because the ground node has its isDynamic set to false, it is not affected by gravity and remains stationary.

// Create the rocket ship node and physics body
let spriteNode = SKSpriteNode(imageNamed: "rocketShip")
spriteNode.position = CGPoint(x: 320, y: 320)
spriteNode.physicsBody = SKPhysicsBody(texture: spriteNode.texture!,
                                       size: spriteNode.texture!.size())
spriteNode.physicsBody?.usesPreciseCollisionDetection = true
     
// Create the ground node and physics body
var splinePoints = [CGPoint(x: 0, y: 500),
                    CGPoint(x: 100, y: 50),
                    CGPoint(x: 400, y: 110),
                    CGPoint(x: 640, y: 20)]
let ground = SKShapeNode(splinePoints: &splinePoints,
                         count: splinePoints.count)
ground.lineWidth = 5
ground.physicsBody = SKPhysicsBody(edgeChainFrom: ground.path!)
ground.physicsBody?.restitution = 0.75
ground.physicsBody?.isDynamic = false
     
// Add the two nodes to the scene
scene.addChild(spriteNode)
scene.addChild(ground)

After running for a few moments, the above code creates a scene that looks like the following illustration—the sprite node has come to rest in one of the valleys of the curvy ground line.

getting-started-with-physics-bodies-002


download this page as .md

download this page as .pdf

back to SpriteKit documentation