SpriteKit: The Runner Chronicles

Part 3: if statements

Awesome! Made it to the end. I finally remembered how this blog post was going to flow. Let’s get back into it!

So we’ve solved the block instance access problem. This was the part that I thought was going to be smooth sailing.

Actually checking the block’s position with the player. Sounds easy enough.

But I was faced with another problem.

When the block has passed, it was supposed to increment the counter. It incremented. Sure. But it incremented non stop. Here was my mistake.

This has already been addressed in the second blog post but I’m going to point it out anyways. Spoiler alert, this was the time when removing the block from the array was not on my mind. Remember this code snippet?

if block.position.x < (self.player.position.x + (self.player.size.width / 2)) {
// block passed through half of the player
self.score += 1
self.scoreLabel?.text = "Score: \(score)"

When the block has passed the player, that if statement still returns true. So now you know where the problem lies. On top of that, it was still in the array. That made it worse.

I changed the code to this.

if firstShape.position.x == (self.player.position.x + (self.player.size.width / 2)) {
self.score += 1
self.scoreLabel?.text = "Score: \(score)"

All good? Nope. It still continued incrementing.

So as any developer would do, I debugged by printing out the values. Let’s just say I was naive to think that the CGFloat values would be equal. The decimals were all over the place.

It was literally like

// 99.88876679023
print("First block x position: \(block.position.x)")
// 99.87667494012
print("Player: \(self.player.position.x + (self.player.size.width / 2))")

As you can see. So much for being equal..

An idea struck me

No idea why I thought it was silly at the time. But, I converted the CGFloat to an Int . Easier to check against as they say.

Here’s the updated code.

if Int(block.position.x) == Int((self.player.position.x + (self.player.size.width / 2))) {
self.score += 1
self.scoreLabel?.text = "Score: \(score)"

This worked! 👍🏼

I tried something silly, for experimentation

I really wanted to use the < operator. Let’s go back to Maths class. Since the detection works on an equal sign, as it should, you can still do this with the < and the > operator.

Much like this right?

// block: 49 < x < 51
// player: 50

So I tried this with code.

if block.position.x > ((self.player.position.x + (self.player.size.width / 2)) - 1) && block.position.x < (self.player.position.x + (self.player.size.width / 2) + 1) {
self.score += 1
self.scoreLabel?.text = "Score: \(score)"

For some reason, it worked on and off. I have no idea why. This is where my curiosity just goes to die.

And there you have it. Wow, I remembered all three issues. Hope you enjoyed this series.

The project is not complete yet but I wanted to put my thoughts on the blog because I was scared it’d disappear. I don’t have a good memory. But it will be open sourced on my Github for those of you who want to learn!

Happy coding!