Welcome to my 71st day of Learning how to code with Swift. This is being an amazing journey and, today, it’s again time to write a new app from scratch! Am I looking forward to it? Not so much…
I would really like to spend some relaxed time learning and absorbing notion while this productivity pushes make me suspect that working life as a coder is a continuous deadline stress, in which case I do not want to pursue that kind of career.
Coding is an amazing extra skill that enhances all your other skills at once but I want to keep a healthy lifestyle as the few coders I met in my brief learning path are ones who do not even want to hear about what coding is during the weekends or when they get out of work. That’s not how it should be.
I love my music notation job and I can speak freely of it even outside of the usual work times without feeling a stress surge. I would really like to add the coding skills to my roster without hindering that enjoyment part.
We learned a lot in these three projects (16-18) but I feel that the teaching was really like touching the surface and then letting go because it was too hot, as if when you accidentally touch a frying pan without the proper protection. I felt like information were deliberately kept from us because it is assumed we do not need them now. I would really like this decision to be ultimately on us.
We need to build a shooting game and, once more, I feel motivation go down under my feet. I’m quite fed up with this but again, yes, I will do my best. To be sincere, apart from the project cleaning, I have no idea where to start from.
I created a new Xcode project and it seems that I can create up to 10 App IDs every 7 days. If Apple things that I am going to pay the subscription right now they are very wrong. I hope I can build and run them on the Simulator even if the signing is not working.
In the project’s General panel I have set the Deployment Info to support only iPad and only in landscape orientation. I have also ticked the Requires full screen option as this was causing warnings in previous games.
I then proceeded to cleaning the project, by removing the Action.sks file then, in GameScene.sks, I removed the big “Hello, World” label, set the scene’s size to 1024 x 768 and the Anchor Point to 0, 0.
In GameScene.swift I then cleaned the file to have only the basic code we need.
In the first instructions we are told to go to a website and check some clip art to use for our project but, really, I already have so little time to study all this I cannot get lost like this.
The point is, in this precise moment, if I do not open past projects and look at how they worked my memory has nothing to say in this, I do not know how to do this.
So, as the point of this series seems to be to break your head with failure and hoping you are still alive when learning will hit, let’s go and see how we can make this by copying my own code from other places… but first, we need assets… I decided to import the assets from Hacking with macOS project 14 as I really have only one life to lose!
We need a plan
I tried for a good hour to do something, both making some kind of project on paper and trying to do something with code. Nothing …
Things either do not come out or they plainly do not work…
I hate this, I hate this feeling with a passion because, in the end, all what I can do now is to go out there and copy someone else’s code and that is not good!
I’m trying to think how to do things and nothing comes to mind. We just had one single lesson on all those subjects and we are now expected to remember everything like a snap. This is not fair…
I hate that the only chance now is to go copying someone else’s code, I hate this! This is not learning…
So I just opened a few projects from some different people, imagined what I wanted to do, looked for that in their code, copied it and adapted it to my scene. I mean, but really, what is the point? How can one grow like this?
At the end of this part of my frustration day 7 we have a working canvas thanks to the assets borrowed from a macOS project which needed all to be adapted, resized and repositioned (which of course will not happen in a regular project but we are here to get screwed, right?) and to some code plucked here and some code plucked there…
Moving on … piece by piece…
So, now we have the curtain contour, the moving water, the background… we need a score label and a bullet counter (graphical one) somewhere.
So, I created a
SKLabelNode and an accompanying
score variable with a
didSet property observer that will update the label’s text. Then I created an
SKSpriteNode with an accompanying
ammonitionsLeft variable set to
6 and with another
didSet property observer that will change the
texture of the sprite node with a different image according to the current state of the
I set the creation code inside the
createOverlay method, wrestling a good bit with the positioning values. I tried to use a font that I have on my Mac but Xcode could not find it. I reverted then to the old friend “Chalkduster”.
Now I need some targets moving around. We have three levels on which they have to run and I guess we need to create a custom type to avoid cluttering even more the view controller.
New tactic … analyse and self-teach!
As my head is not knowing by heart how to do things but kind of knows what it would like to see I made a plan about each step and then checked among my code if I had something that resembled what I needed. If I didn’t I checked other people’s code and wrote a self-tutorial while copying and adapting the code the my scene.
I created an optional
Timer variable for the game timer and another one for the target creation timer. I set the second to
0.8 seconds and let it alone by now. Next to the game timer I created an
SKLabelNode timer label with an integer variable for the remaining time (again with a property observer to update the label’s text). I also created a
targetSpeed variable and a
targetsCreated one as I felt I would need them pretty soon.
didMove(to:) I added a
startGame() method call as I know the game logic will go in there. I then started to write this new method under a mark called “Game Logic”.
Inside it I started by running an action which would play the sound file named “reload”. This would give a nice start. I then set the variables associated with labels to their original value to trigger the label’s text. I then invalidated the current timer (if available) and set a new one. Of course this needed me to write an
updateGameTimer method and to create an empty
createOverlay method I added the timer label.
This view controller is already 147 lines long so everything I can save will be absolutely great!
I created a new class based on
SKNode called “Target” and created two variables, one for the target and one for the wooden stick on which to make it stand.
createTarget method is needed now, with a randomisation of the stick and target type followed by the initialisation. The node’s name is then set to “target” so that when we will call the
gameOver method we will be able to destroy all of them together.
The target’s position is then increased by a fixed amount that we will need to fine-tune.
The next method is an
isHit method that will remove all the actions attached to the target, set its name to
nil and perform a change in color, a fade-out and a movement to make it disappear. In this process I learned of a new method (for me), the
Create enemies? Is that the time?
Before I forget I add a
isGameOver property set to
false so that we can use it later on.
startGame method I invalidate a possibly already existing
targetCreationTimer and then set it to a scheduled timer with the
targetCreationInterval and with the
createTarget method as its
It’s time now to write the
We create a
Target() and call its
create() method on itself, setting the a new
isMovingRight variable to true. I wonder if this could have been a property of the target data type.
We then decide on which vertical level to create our target (in front of the grass, in front of the water background or in front of the water foreground) using a
switch case over the
level property we create just before that (and set to a random integer between 0 and 2). For each of them we set a
position.y (that needs to be fine-tuned by trial and error) and, for the two higher levels (0 and 1) its
setScale method to give a sense of perspective.
Finally we configure the target’s movement by declaring an
SKAction and controlling whether the
isMovingRight property is true or false. In the first case we want to move it from just outside the screen on the left to just outside the screen on the right and in the second we want to do the opposite. After this movement has completed we want to remove the node from its parent. We therefore create and run a sequence composed of this move action and the
At the end we just add the child to the parent.
Create a pointer!
I wanted to create a pointer as for the macOS app we were given as model to follow but there seems not to be any point of doing so in iOS where you interact with every element simply with touch. I will possibly come back to this later if I find that this is possible.
In the end this seems unpractical so let’s move on to other things.
Once the first touch is found as well as its location and the nodes found in there, we reload our ammunitions if the nodes contain “ammunitions” in their name.
Then we proceed to manage the game’s logic: if the game is over we make a transition to show our GameScene file once more (even though I still have to figure out why the scene doesn’t launch at the same size). If the game is still running and we are not out of ammunitions, we shoot and remove 1 from the ammunitions left. So far, so good…
We then write a
reload method which will play the sound and reset the amount of ammunitions to 6.
Then the painful part which is driving me nuts once more … if I will ever program games I will never use SpriteKit. As powerful as it is, I do not like it, nor I like how it comes out …
I copied the method from Hacking with macOS project 14 and adapted it to my project and it works, nothing to say.
Now, I would like to be able to switch the names of each target so that I can get more or less points but I just cannot … I just get compile error after compile error …
How to switch over the different kinds of targets
Thanks to Rob Baldwin I have been able to find a solution to my suffering! The issue was that, copying from the macOS code, for some reason, I was accessing the parent node and not the child. I really do not know why this was not working and I have little to no means to understand it, unfortunately.
shot method needed to extrapolate the children nodes from the
hitNode parent node, optionally downcast them as an array of
SKSpriteNode and then to loop over them. Inside the loop we would have checked whether the child node would have had a name and then switched over it to determine which kind of score to assign to the player. I decided to to give points for the target and the shower duck and to remove points in case a “real duck” would be hit.
The only other thing to change was in the Target.swift file: I switched over the
targetType to assign a name to the child node and then, the important part, changed the
name property into
self.name = "target".
Here is the GitHub code. The “selectiveShooting” branch is the good one.
Again, I really think I would have never gotten there alone, and the amount of anger I had in the struggle period sincerely scares me.
I believe that this kind of learning is not a good one nor one that will bear any result in the long term but I also understand Paul and the other people proposing courses: they all say that no previous experience is needed, only one hour per day, no more, congratulations! You built your first iOS app!… If they would ever say how really hard it is no one would ever buy their books and services…
But behind this there is a much darker truth:
- Without a very good, and very solid, base in high school math it is not possible to develop apps with any good logic, and for high school math I mean a good base in integral calculus at least. Of course, an informatics engineering degree will greatly help, or why not, a computer science degree, would be even better but, yes, let’s be honest, a good, open brain and a good base in high school math will suffice.
- One hour per day is plain bullshit, I have never managed to finish any of these first 72 days in less than 90-120 mins. Fine, I am no English-native speaker so I take much more time to understand what is being taught but, really, the speed of teaching is unacceptable. From my side I have a full-time job (in a sector that is slowly dying to automation) but still I started this challenge because of the 1h/day promise. Well, I will go to the end, but I am very disappointed by this.
- All those encouraging phrases are very good marketing but sooner or later, you will be alone, against a blank screen, not knowing what to do or where to search… alone, because you trusted a teacher… again…
Learning is hard, coding is hard, but listen, everything is hard if you want to do it at a high level enough. You need to spit blood on your craft, I know it, because I practiced cello for 8hr/day for more than 10 years! But I had a clear path in front of me, I had a teacher who told me what to do and how! I discovered plenty of things on my own, but I never, never, felt alone in the dark!
Let me know what you think of all this.
Thank you for reading.
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!