Spritekit physics destroy objects animation

256 Views Asked by At

is it somehow possible to destroy an object on contact? Like not just delete it from the screen with body.removeFromParent(), I would like to have an animation.

I have a player and walls, and when the player has a special powerup, I want it to be able to destroy the walls on contact. I could imagine that I have like the wall split up as many little physics bodies and they hold together on like an anchor point and when my player hits it, they get an impulse from the player (just set isDynamic to true I guess) and losen the anchor point so all the sprite Nodes will fly their way and so the wall will be destroyed.

Can you give me some help / advise of a good way of doing that?

1

There are 1 best solutions below

11
On

You don't need to have the nodes making up the wall held together in any way - just place them on the screen. If the player doesn't have the power-up, turn off the bit for the player in the wall nodes' physicsBodies collisionBitMask so that the wall nodes do not collide with the player. Then when the player hits the wall, the player will be affected by the collision (and bounce off) but the wall nodes will be unaffected.

When the player has the power-up, make the wall nodes affected by the collision and also turn on contacts between the player and the wall (it's enough just to turn on the bit for the wall category in the player's contactTestBitMask). Then the wall nodes will be affected by the collision (and move or spin away) and your didBegin() will be called and you can run an action on each wall node comprising of the animation you want and ending with removeFromParent().

A guide to collision and contactTest bit masks: https://stackoverflow.com/a/40596890/1430420

Manipulating bit masks to turn collision & contacts off and on. https://stackoverflow.com/a/46495864/1430420

Edit: SK demo showing an object hitting a wall made up of blocks:

Create a new SK project and use this as the GameScene,swift:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

    override func didMove(to view: SKView) {

        physicsWorld.gravity = CGVector(dx:0, dy:0)

        let ball = SKSpriteNode.init(color: .red, size: CGSize(width: 50, height: 50))
        ball.physicsBody = SKPhysicsBody.init(circleOfRadius: ball.size.width/2)
        ball.position = CGPoint(x: 0, y: 0)

        buildWall()

        addChild(ball)

        ball.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
    }

    func buildWall() {
        let xStart : CGFloat = ((scene?.size.width)!/2) * -0.9
        var brickPosition = CGPoint(x: xStart, y: 500)
        let brickSize = CGSize(width: 20, height:20)

        for wallRow in 1...10 {
            for wallColumn in 1...30 {
                let brick = SKSpriteNode(color: .yellow, size: brickSize)
                brick.physicsBody = SKPhysicsBody.init(rectangleOf: brick.size)

                brick.position = brickPosition

                addChild(brick)
                brickPosition.x += brickSize.width + 1
            }
            brickPosition.x = xStart
            brickPosition.y -= 11
        }
    }
}