Move the Player with Actions

Currently, the player object is defined in the scene using a local variable within a single method. This approach won’t work because you need access to the player object from outside of that single method. To fix this problem, you’ll add a new player property to the GameScene and remove the local player variable from the didMove(to:) method.

Still inside the GameScene.swift file, add the following property to the GameScene class, just above the didMove(to:) method:

 let​ player = ​Player​()

Then, change the player set-up code in the didMove(to:) method to match this:

 // Set up player
 player.position = ​CGPoint​(x: size.width/2, y: foreground.frame.maxY)
 addChild​(player)
 player.​walk​()

This code gives you access to the player object from other methods within the game scene. The next step is to move the player node left and right when the user, your human player, touches the screen.

Add the Move Action

First, you need a new method that moves the player node. For this new method, you’ll use another action.

Open the Player.swift file and add your new method below the walk() method:

 func​ ​moveToPosition​(pos: ​CGPoint​, speed: ​TimeInterval​) {
 let​ moveAction = ​SKAction​.​move​(to: pos, duration: speed)
 run​(moveAction)
 }

With this action, you’re moving the player node from its current position to the position indicated in the pos input parameter. You’re also setting the duration, which specifies how long it should take to move the node from point A to point B.

Speed versus Duration

images/aside-icons/info.png

When you’re working with actions, a handful of properties control the timing. Two of those properties are speed and duration. The speed property is a CGFloat that controls how fast an action runs, whereas the ‘duration property is a TimeInterval that determines how long it takes an action to run. So, why did I use moveToPosition(pos:speed:) instead of moveToPosition(pos:duration:), which is closer to the SKAction.move(to:duration:) method?

When I name custom methods, I tend to think in terms of gameplay rather than what the method is technically doing. You could argue that I’m using the Swift API guideline that states you should “name variables, parameters, and associated types according to their roles, rather than their type constraints,” but in this case, it’s a fine line. The length it takes Blob to move across the scene, in my mind, is his speed—how fast he’s moving.

Respond to Touch

When you create a new project, the iOS Game template creates some useful methods, including its touch handlers. In Clean Up the Default Template, you removed those handlers for clarity—it’s time to add them back into the code.

In the GameScene.swift file, add the following code below the didMove(to:) method:

 // MARK: - TOUCH HANDLING
 
 /* ####################################################################### */
 /* TOUCH HANDLERS STARTS HERE */
 /* ####################################################################### */
 
 func​ ​touchDown​(atPoint pos : ​CGPoint​) {
 
 }
 
 override​ ​func​ ​touchesBegan​(_ touches: ​Set​<​UITouch​>, with event: ​UIEvent​?) {
 for​ t ​in​ touches { ​self​.​touchDown​(atPoint: t.​location​(in: ​self​)) }
 }

This boilerplate code handles one of the standard touch events.

A Word about Comment Blocks

images/aside-icons/info.png

You might be wondering why so many comments are included with the code examples you’re adding. For example, the large comment block, TOUCH HANDLERS STARTS HERE, that immediately proceeds the // MARK: - TOUCH HANDLING comment.

While it’s generally a good idea to include some comments with your code, adding larger blocks helps to visually break up your code without having to rely on the jump bar or separator lines.

If you’re typing this code into your editor, and you’d rather skip the comments, that’s fine.

For the code you just added, your focus is on the touchDown(atPoint:) method. This method is indirectly called whenever the user touches the screen. It works that way because the touchesBegan(_:with:) method is automatically called by the system when the user touches the screen, and this method now passes the touch location to your custom method.

In the touchDown(atPoint:) method, add the following line:

 player.​moveToPosition​(pos: pos, speed: 1.0)

This line of code passes the desired position and speed to the moveToPosition(pos:speed:) method you created earlier.

Build and run the project, and then start tapping anywhere on the screen.

images/AddingAnimationAndMovementWithActions/spritekit-build-03.png

You likely already noticed a problem. Well, actually, three problems:

  • Blob moves anywhere you tap, including off the platform.
  • The direction Blob is facing doesn’t always match the direction he’s going.
  • Blob’s speed is inconsistent.

The good news is that all of Blob’s movement issues are fixable, which you’ll do next.

Testing with the Simulator

images/aside-icons/important.png

As you start to add more features to your SpriteKit games, such as animation and movement, you’ll notice that running things on the simulator is very slow. To get around this problem, you can test on a physical device rather than using the simulator. As a matter of fact, you should never ship your games or apps without proper testing on a physical device first.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset