TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

100 days of Swift - Day 63 - Project 17 - Space Race - Challenge 1

Forums > 100 Days of Swift


Sorry to say I'm befuddled by the first challenge, did the other 2 no problem, but I'm really not sure what your asking for.

  1. Stop the player from cheating by lifting their finger and tapping elsewhere – try implementing touchesEnded() to make it work.

TouchesEnded - happens when the user picks up their finger...

Is this about event bubbling? Is the idea to cancel/handle the event so it doesn't run touches moved? ok hint plz.

Or just explode the spaceship if they lift their finger? That seems rather punishing and unintuitive.

The cheat to me, it seems to happen on touchesBegan/Moving, where it doesn't check that the user actually tapped the spaceship.. (a check nicely shown in Proj 14)

I'm really at a loss at what I should be understanding in touchesEnded. At touchEnded, it's already moved the space ship... I could move the update to position code to Ended, but then it would only update on finger lifted

i must be going down a blind alley, please help me back on track, thanks.


Not sure how many hints do you want :-) But the key is to implement both touchesBegan and touchesEnded when checking if the player is indeed touching the spaceship and not trying to cheat.



huh, thanks will do that :D

So there's no special "one-liner hack" for touchesEnded, i was missing?



I ended up sticking with touchesMoved, using excepts from Paul's code for node in nodes(at:touch.location(in self)) { if node == player { //update player.position

Is that bad from from a performance angle? The above code seemed clear & consise to me...

Using touchesBegan/Ended seemed cluttered, and possibly bad for multitouch?

if it had a bool touchedShip set on tBegan, update ship's position if touchedShip is true in tMoved, the set it to false in tEnded...

but... how well would that handle leaving a finger on the screen, then add a new touch, or multi touch? I may be over thinking things... it just seemed to complicate things in this case.


I think your approach is perfectly viable, what I did was a very similar thing:

  1. I created var isPlayerTouched: Bool
  2. in touchesBegan - if the touched node is the ship: isPlayerTouched = true.
  3. in touchesEnded - if the touched node is the ship: isPlayerTouched = false.

That way, I can control when the ship can be moved and when not. So in my case, touchesMoved works with the ship node only when isPlayerTouched = true.

EDIT: Ah, now I remember. My first approach was identical to yours. However, I noticed that my finger was 'losing' the ship when I was moving it very fast. The above method got rid of all the problems.


Hello everyone!

I kept what Paul wrote on touchesMoved() and I implemented touchesEnded() like so:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if !touches.isEmpty {
            for touch in touches {
                let location = touch.location(in: self)
                for node in nodes(at: location) {
                    if == "player" {
                        debugPrint("Player node found")
                        player.position.y = node.position.y
                        player.position.x = node.position.x
        } else { return }

I'm not really sure why but it works sometimes. I've done several tests and the times it doesn't work is because:

  1. I touch/tap several times on the same spot.
  2. I tap and hold.

I also feel like all the player.positions are being stored/remembered because the method fails more as time goes on.

Any insights?


I use this formula to calculate distance between 2 CGPoint in touchMoved"var location = touch.position(in: self)" and "player.position": func CGPointDistanceSquared(from: CGPoint, to: CGPoint) -> CGFloat { return (from.x - to.x) (from.x - to.x) + (from.y - to.y) (from.y - to.y) }

if it is > 5000 or some thing, you can modify it. it will return from touchMoved function. So that player can not cheat to lift finger then moved finger in a distance that too far the original one.


i decided to use the logic if the touchesBegan location of the touch contains the rocket than move the rocket else don't move the rocket.. So keeping with paul's original code for touchesMoved(), i added touchesBegan that returns a boolean to detect if touchesBegan contains the rocket frame if player.frame.contains(location) is true, then allow for touchesMove else don't move the rocket.


I think the problem for me was "what is the cheat". It wasn't really explained in the challenge and it took me quite a while to actually cause the cheat. I tapping all over the screen and nothing was happening. Once I tapped and held then I finally saw the issue.


Hacking with Swift is sponsored by Superwall.

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.