ByCyril / Physics-Board

Simplified version of Fidge It

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Physics-Board

Developed and Designed by Cyril

Tutorial

Setup

Create a GameScene Xcode Project and download the emoji files I have or you can use your own image for your nodes.

Step 1

Import CoreMotion and create a CMMotionManager property. This will allow us to use the accelerometer to create the physics effect. Also create an array of [SKSpriteNote] which will allow us to hold current nodes in our screen for later use.

Step 2

Setup your physics world in your SKScene.

physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
physicsWorld.gravity = CGVector(dx: 0, dy: -9.8)

Then after that, start the accelerometer updates

motionManager.startAccelerometerUpdates()

Step 3

Create a function that will be used within the touchesMoved(:_) method

    func createNode(at position: CGPoint) {
//        This is for the emoji names.
//        You may not need it if you are using
//        a single image
        let i = Int.random(in: 1...85)

//        create the node
        let node = SKSpriteNode(imageNamed: "emoji\(i)")
        node.size = CGSize(width: 50, height: 50)
        node.position = position
        
//        add the physics body
        node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2)
        node.physicsBody?.restitution = 0.5
        node.physicsBody?.friction = 0.2
        node.physicsBody?.allowsRotation = true
        node.physicsBody?.isDynamic = true
        scene?.addChild(node)
        
//        add the newly created node to our nodes array.
        nodes.append(node)
    }

Then call this method in your touches moved by passing in the location of the touch.

Step 4

We can create our clearScene() method because, why not :)

func clearScene() {
       for node in nodes {
//            create the scaling affect
           let scale = SKAction.scale(by: 0, duration: 1.25)
           
//            remove the node from the parent
           let remove = SKAction.run {
               node.removeFromParent()
           }
           
//            create the rotation affect
           let rotationAngle: CGFloat = 2 * CGFloat.pi
           let rotate = SKAction.repeatForever(SKAction.rotate(byAngle: rotationAngle, duration: 0.35))
           
//            create a sequence where we run the scaling and removing affect
           let sequence = SKAction.sequence([scale, SKAction.wait(forDuration: 0.25), remove])
           
//            rotate the nodes and run it with the scaling and removing affect/
           node.run(rotate)
           node.run(sequence)
       }
       
//        then remove all references of the nodes
       nodes.removeAll()
   }

Step 5 - Where the magic happens

To create the physics affect, we want to use our motionManager to access the accelerometer data and use that to change the physics world gravity.

We do this inside our update(_:) method

guard let acc = motionManager.accelerometerData?.acceleration else { return }
       
let harshness: Double = 75
physicsWorld.gravity = CGVector(dx: acc.x * harshness, dy: acc.y * harshness)

Step 6

To call the clearScene() method, I did this inside the GameViewController class since the motion method for some reason does not trigger inside the scene

  override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {

       guard motion == .motionShake else { return }
       guard let skView = view as? SKView else { return }
       guard let scene = skView.scene as? GameScene else { return }
       scene.clearScene()
       
   }

That's it, enjoy!

About

Simplified version of Fidge It

License:MIT License


Languages

Language:Swift 100.0%