# Slot Collisions

1. Carrera D132 with anti-collision system installed. Surprising Dad for 99th birthday with '55 Ford he never thought would run again - Duration: 17:19. Jerry Heasley Recommended for you.
2. Should Station A and Station B attempt to retransmit in the same slot, they extend the number of slots. Each station then picks a new slot, thereby decreasing the probability of retransmitting in the same slot. Collisions are a way to distribute the traffic load over time by arbitrating access to the shared medium.

The mobile casino has taken the concept of personalized gaming Slot Collisions to a whole new level. Now you can play on the go 24×7 regardless of where you are. All you need is a smartphone that gives you Internet access via 3G, 4G, LTE, or Wi-Fi.

 < Previous: Spinning slots: SKAction Next: Scores on the board: SKLabelNode >

Just by adding a physics body to the balls and bouncers we already have some collision detection because the objects bounce off each other. But it's not being detected by us, which means we can't do anything about it.

In this game, we want the player to win or lose depending on how many green or red slots they hit, so we need to make a few changes:

1. Add rectangle physics to our slots.
2. Name the slots so we know which is which, then name the balls too.
3. Make our scene the contact delegate of the physics world – this means, 'tell us when contact occurs between two bodies.'
4. Create a method that handles contacts and does something appropriate.

The first step is easy enough: add these two lines just before you call `addChild()` for `slotBase`:

The slot base needs to be non-dynamic because we don't want it to move out of the way when a player ball hits.

The second step is also easy, but bears some explanation. As with UIKit, it's easy enough to store a variable pointing at specific nodes in your scene for when you want to make something happen, and there are lots of times when that's the right solution.

But for general use, Apple recommends assigning names to your nodes, then checking the name to see what node it is. We need to have three names in our code: good slots, bad slots and balls. This is really easy to do – just modify your `makeSlot(at:)` method so the `SKSpriteNode` creation looks like this:

Then add this to the code where you create the balls:

We don't need to name the bouncers, because we don't actually care when their collisions happen.

Now comes the tricky part, which is setting up our scene to be the contact delegate of the physics world. The initial change is easy: we just need to conform to the `SKPhysicsContactDelegate` protocol then assign the physics world's `contactDelegate` property to be our scene. But by default, you still won't get notified when things collide.

What we need to do is change the `contactTestBitMask` property of our physics objects, which sets the contact notifications we want to receive. This needs to introduce a whole new concept – bitmasks – and really it doesn't matter at this point, so we're going to take a shortcut for now, then return to it in a later project.

Let's set up all the contact delegates and bitmasks now. First, make your class conform to the `SKPhysicsContactDelegate` protocol by modifying its definition to this:

Then assign the current scene to be the physics world's contact delegate by putting this line of code in `didMove(to:)`, just below where we set the scene's physics body:

Now for our shortcut: we're going to tell all the ball nodes to set their `contactTestBitMask` property to be equal to their `collisionBitMask`. Two bitmasks, with confusingly similar names but quite different jobs.

The `collisionBitMask` bitmask means 'which nodes should I bump into?' By default, it's set to everything, which is why our ball are already hitting each other and the bouncers. The `contactTestBitMask` bitmask means 'which collisions do you want to know about?' and by default it's set to nothing. So by setting `contactTestBitMask` to the value of `collisionBitMask` we're saying, 'tell me about every collision.'

This isn't particularly efficient in complicated games, but it will make no difference at all in this current project. And, like I said, we'll return to this in a later project to explain more. Until then, add this line just before you set each ball's `restitution` property:

That’s the only change required for us to detect collisions, so now it's time to write the code that does the hard work.

But first, a little explanation: when contact between two physics bodies occurs, we don't know what order it will come in. That is, did the ball hit the slot, did the slot hit the ball, or did both happen? I know this sounds like pointless philosophy, but it's important because we need to know which one is the ball!

Before looking at the actual contact method, I want to look at two other methods first, because this is our ultimate goal. The first one, `collisionBetween()` will be called when a ball collides with something else. The second one, `destroy()` is going to be called when we're finished with the ball and want to get rid of it.

Put these new methods into to your code:

The `removeFromParent()` method removes a node from your node tree. Or, in plain English, it removes the node from your game.

You might look at that and think it's utterly redundant, because no matter what happens it's effectively the same as writing this:

But trust me on this: we're going to make these methods do more shortly, so get it right now and it will save refactoring later.

With those two in place, our contact checking method almost writes itself. We'll get told which two bodies collided, and the contact method needs to determine which one is the ball so that it can call `collisionBetween()` with the correct parameters. This is as simple as checking the names of both properties to see which is the ball, so here's the new method to do contact checking:

If you're particularly observant, you may have noticed that we don't have a special case in there for when both bodies are balls – i.e., if one ball collides with another. This is because our `collisionBetween()` method will ignore that particular case, because it triggers code only if the other node is named 'good' or 'bad'.

Run the game now and you'll start to see things coming together: you can drop balls on the bouncers and they will bounce, but if they touch one of the good or bad slots the balls will be destroyed. It works, but it's boring. Players want to score points so they feel like they achieved something, even if that 'something' is just nudging up a number on a CPU.

Before I move on, I want to return to my philosophical question from earlier: “did the ball hit the slot, did the slot hit the ball, or did both happen?” That last case won’t happen all the time, but it will happen sometimes, and it’s important to take it into account.

If SpriteKit reports a collision twice – i.e. “ball hit slot and slot hit ball” – then we have a problem. Look at this line of code:

And now this line of code:

The first time that code runs, we force unwrap both nodes and remove the ball – so far so good. The second time that code runs (for the other half of the same collision), our problem strikes: we try to force unwrap something we already removed, and our game will crash.

To solve this, we’re going to rewrite the `didBegin()` method to be clearer and safer: we’ll use `guard` to ensure both `bodyA` and `bodyB` have nodes attached. If either of them don’t then this is a ghost collision and we can bail out immediately.

It takes a little more explanation and a little more code, but the result is safer – and that’s always worth striving for!

SPONSOREDLearn SwiftUI to craft awesome iOS 14 apps! BLCKBIRDS has a new book called Interactive Mastering SwiftUI, designed to teach you all you need to know to build beautiful iOS 14 apps using SwiftUI. Step-by-step, they will build apps such as a chat messenger, a photo editor and a stocks app, and it's ideal for beginners and intermediate developers. Hacking with Swift readers get a 25% discount!

### Slot Commissions

 < Previous: Spinning slots: SKAction Next: Scores on the board: SKLabelNode >