Hacking with Swift – Challenge 11

Time for another challenge! This is Day 51 for me and I will tackle Day 47 from Paul Hudson’s 100 Days of Swift initiative. I will keep trying to catch up as much as possibly but with every project becoming longer and each challenge getting…well, more challenging, it gets quite hard!

I will also try to be more concise in my article writing; I do not want to repeat what Paul said and will just focus on a step-by-step reminder of what was to be done and a deep dive in the Documentation when needed.

Review

Here is what we learned with this project (among other things):

  1. We can add physics to a node without letting it be moved, by changing its isDynamic property to false.
  2. A sprite node may or may not have a physics body attached.
    • The alternative answer was proposing that we can control the density of a sprite by setting its restitution property. This is false because restitution controls the “bounciness” of our sprite.
  3. collisionBitMask determines what objects a node bounces off, and contactTestBitMask determines which collisions are reported to us. This was the hard part to understand of the project.
  4. We can adjust whether a node is positioned in front of or behind other nodes by setting its zPosition property.
    • Here the alternative was hard as well: “the touchesBegan() method is called the first time any touch happens in our game, and never again”. We know this to be false but the reason may be found already in the method’s name: “touches”, plural! I guess there may be a time interval after which the method stops listening to touches.
  5. Xcode has a built-in graphical particle editor that lets us preview changes live.
  6. When collisions happen, we might get told that thing A hit thing B, thing B hit thing A, or potentially both.
  7. We can find the location of a touch in our game scene by using the location(in:) method.
  8. The toggle() method of Booleans flips its value from true to false or vice versa.
  9. Both SpriteKit and UIKit measure angles in radians.
    • I was a bit confused here because the alternative was “We can add text to our game scenes using SKLabel”, which is also true right? Well… it turns out it isn’t and that it would have been SKLabelNode!
  10. We can control the behaviour of nodes using SKAction.
  11. Blend modes affect how nodes are drawn.
  12. SKSpriteNode stores one sprite for our game scene.

Challenges

Challenge 1: the pictures we’re using in the app have other ball pictures rather than just “ballRed”. Try writing code to use a random ball color each time they tap the screen.

I created a global variable like this:

let availableBalls = ["ballBlue", "ballCyan", "ballGreen", "ballGrey", "ballPurple", "ballRed", "ballYellow"]

I initially created it inside the touchesBegan method but then I told myself: “Do we really need to create an destroy this property every time?” Sure, having it globally may require constant resources but, come on, this is a ball game so, shouldn’t I give importance to the balls?

Then in the part of code where a new ball is created I replaced the hardcoded “ballRed” with this:

let ball = SKSpriteNode(imageNamed: availableBalls.randomElement() ?? "ballRed")

I preferred to use nil-coalescing rather than force-unwrapping.

That’s it. On to the next one!

Challenge 2: right now, users can tap anywhere to have a ball created there, which makes the game too easy. Try to force the Y value of new balls so they are near the top of the screen.

I changed the location of the ball when it gets created to this:

ball.position = CGPoint(x: location.x, y: 768)

It just works! Great! On to the next one which seems the hard one!

Challenge 3: give players a limit of five balls, then remove obstacle boxes when they are hit. Can they clear all the pins with just five balls? You could make it so that landing on a green slot gets them an extra ball.

Mmm… I tried it and… I managed it?

It was strangely simple and therefore I am suspicious about it. I wonder if someone may look at my code and tell me if it is fine or not.

So: I created a numberOfBalls property and set it equal to 0. Then, in the ball’s creation code, after setting the ball’s name, I increased the numberOfBalls by 1 and set a condition as follows:

if numberOfBalls > 5 {
	if let fireParticles = SKEmitterNode(fileNamed: "FireParticles") {
		fireParticles.position = location
		addChild(fireParticles)
	}
	return
}

I tried to add an alert controller with a willSet property observer but then I could not call the present method on it… I have no idea why… Possibly because we are not using UIKit but, is it possible to have an alert controller in SpriteKit?

Anyway, this is a simple shortcut but it will just make the screen “explode” if one has created more than five balls (of course I could tweak the graphics but by now the matter is functionality).

In the collision method I added a numberOfBalls -= 1 in the “good” case and, after giving a “box” name to our created box node, I added another else if statement to remove the object instead of the ball…

I mean… that’s it, it just work but… I wonder if I have forgotten something…

Please give it a look here on GitHub if you have some spare time.

I would really appreciate your feedback.

Thank you!


If you like what I’m doing here please consider liking this article and sharing it with some of your peers. If you are feeling like being really awesome, please consider making a small donation to support my studies and my writing (please appreciate that I am not using advertisement on my articles).

If you are interested in my music engraving and my publications don’t forget visit my Facebook page and the pages where I publish my scores (Gumroad, SheetMusicPlus, ScoreExchange and on Apple Books).

You can also support me by buying Paul Hudson’s books from this Affiliate Link.

Anyways, thank you so much for reading!

Till the next one!

Published by Michele Galvagno

Professional Musical Scores Designer and Engraver Graduated Classical Musician (cello) and Teacher Tech Enthusiast and Apprentice iOS / macOS Developer Grafico di Partiture Musicali Professionista Musicista classico diplomato (violoncello) ed insegnante Appassionato di tecnologia ed apprendista Sviluppatore iOS / macOS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: