Search code examples
swiftsprite-kitswift-playgroundskphysicsbody

How to prevent Sprite Nodes from pushing each other?


3 Sprite Nodes are moving up at different speed levels. You see that the gorilla likes to rest, but the lobster is pushing it slowly upwards. Expected behaviour would be, that the lobster would rest also and continue going upwards when the gorilla starts moving again. Using .isDynamic = false did not work — the Sprite Nodes were overlaying and lobster ignored the physical body of the hedgehog and the gorilla totally.

Recording of my Playground Scene: https://youtu.be/l47kaJiJvkM

Screenshot of the video: screenshot

Code:

import SpriteKit

public class WalkingScene: SKScene {

public override func didMove(to view: SKView) {
    backgroundColor = .white

    view.showsPhysics = true

    let hedgehog = SKSpriteNode(imageNamed: "hedgehog")
    hedgehog.size = CGSize(width: 64, height: 64)
    hedgehog.position = CGPoint(x: size.width/2, y: 400)
    hedgehog.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 80, height: 80))
    hedgehog.physicsBody?.affectedByGravity = false
    hedgehog.physicsBody?.allowsRotation = false


    let gorilla = SKSpriteNode(imageNamed: "gorilla")
    gorilla.size = CGSize(width: 64, height: 64)
    gorilla.position = CGPoint(x: size.width/2, y: 140)
    gorilla.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 80, height: 80))
    gorilla.physicsBody?.affectedByGravity = false
    gorilla.physicsBody?.allowsRotation = false


    let lobster = SKSpriteNode(imageNamed: "lobster")
    lobster.size = CGSize(width: 64, height: 64)
    lobster.position = CGPoint(x: size.width/2, y: 20)
    lobster.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 80, height: 80))
    lobster.physicsBody?.affectedByGravity = false
    lobster.physicsBody?.allowsRotation = false


    //        hedgehog.physicsBody?.isDynamic = false
    //        gorilla.physicsBody?.isDynamic = false
    //                lobster.physicsBody?.isDynamic = false

    //        hedgehog.physicsBody?.usesPreciseCollisionDetection = true
    //                hedgehog.physicsBody?.collisionBitMask = 0
    //        gorilla.physicsBody?.usesPreciseCollisionDetection = true
    //                gorilla.physicsBody?.collisionBitMask = 0
    //        lobster.physicsBody?.usesPreciseCollisionDetection = true
    //                lobster.physicsBody?.collisionBitMask = 0

    self.addChild(lobster)
    self.addChild(hedgehog)
    self.addChild(gorilla)

    self.moveGorilla(gorilla)
    self.moveLobster(lobster)
    self.moveHedgeHog(hedgehog)
}

func moveGorilla(_ passenger: SKSpriteNode) {

    let moveLeft = CGVector(dx: 0, dy: 200)
    let aYYY = CGVector(dx: 200, dy: 0)
    let moving = SKAction.move(by: moveLeft, duration: 1)
    let turnAYY = SKAction.move(by: aYYY, duration: 1)
    let chill = SKAction.wait(forDuration: 3)

    passenger.run(SKAction.sequence([moving, chill, moving, chill, turnAYY])) {
        print("Gorilla arrived")
    }
}

func moveLobster(_ passenger: SKSpriteNode) {

    let moveLeft = CGVector(dx: 0, dy: 200)
    let moving = SKAction.move(by: moveLeft, duration: 1.2)

    passenger.run(SKAction.sequence([moving, moving, moving, moving, moving, moving, moving, moving, moving])) {
        print("Lobster arrived")
    }
}

func moveHedgeHog(_ passenger: SKSpriteNode) {
    let moveLeft = CGVector(dx: 0, dy: 200)
    let moving = SKAction.move(by: moveLeft, duration: 1)
    let chill = SKAction.wait(forDuration: 2)

    passenger.run(SKAction.sequence([chill, moving, moving, moving])) {
        print("Hedgehog arrived")
    }
}

}


Solution

  • You can set those dynamics this way:

         hedgehog.physicsBody?.isDynamic = true
         gorilla.physicsBody?.isDynamic = false
         lobster.physicsBody?.isDynamic = true
    

    By this strategy, you can extend this example to other situations.

    If isDynamic = true is treated as 0 , and the isDynamic = false, ie static, treated as infinity, there is something between which can be controlled by the mass of a physics body.

        hedgehog.physicsBody?.isDynamic = false. (mass = Infinity)
        gorilla.physicsBody?.isDynamic = true. (mass = big)
        lobster.physicsBody?.isDynamic = true  (mass = 0)
    
        gorilla.physicsBody?.mass = 1000