Most games worth playing include some type of goal or reward system—without it, players would quickly get bored playing your game and move on to something else.
In Gloop Drop, the player’s goal is to collect sticky globs of gloop (drops) as they fall from the sky without letting them hit the platform. Each time the player catches a drop, the player earns points.
Your first step to implementing Gloop Drop’s goal and reward system is to add the image resources for the sticky globs of gloop.
Similar to what you did in Add the Images Resources for the Player, you’ll add a new sprite atlas to hold the three gloop drop images—one for each resolution (@1x, @2x, and @3x):
To begin, open the gloopdrop project in Xcode.
From the Project Navigator, select the Assets.xcassets asset catalog. Click the + button at the bottom of the Outline View and select New Sprite Atlas. Rename the Sprites sprite atlas to collectibles, and delete the empty Sprite image set.
Open Finder and drag all of the images from the resources/collectibles folder into the newly created sprite atlas, like the first image.
When you’re done, your new sprite atlas will look like the second image.
With the image resources added, you’re ready to create the custom class for the collectible items.
Similar to what you did in Create the Player Class, you’ll create a custom class for the collectible items.
From Xcode’s App menu, select File ▶ New ▶ File... or press ⌘N on your keyboard to create a new file. Select the iOS Swift File template and name the file, Collectible.swift. When the new file opens in the Source Editor, replace its contents with the following code:
| import Foundation |
| import SpriteKit |
| |
| class Collectible: SKSpriteNode { |
| |
| } |
Like the Player class, this new class imports the Foundation and SpriteKit frameworks and provides the Collectible class definition.
Next, you’ll add a CollectibleType enum, making it easier to set up different types of collectible items as needed. Remember, with an enum, you can use memorable names, making it easier to refer to them in a type-safe way.
Above the Collectible class declaration, add the following code:
| // This enum lets you add different types of collectibles |
| enum CollectibleType: String { |
| case none |
| case gloop |
| } |
Because you’re using an enum, you can now extend the game later to include additional types of collectible items like power-ups, extra lives, and other goodies.
Adding More Collectible Types | |
---|---|
In this book, you’ll only be adding one type of collectible item—the sticky globs of gloop—however, it’s good practice to consider your future design when coding, so it doesn’t hurt to plan ahead and use an enum for future collectible items. The alternative is to hardcode your values, which is usually never a good idea. |
Your next step is to add a property for tracking and setting the collectible type, along with the initialization methods.
Inside and at the top of the Collectible class, add the following block of code:
| // MARK: - PROPERTIES |
| private var collectibleType: CollectibleType = .none |
| |
| // MARK: - INIT |
| init(collectibleType: CollectibleType) { |
| var texture: SKTexture! |
| self.collectibleType = collectibleType |
| |
| // Set the texture based on the type |
| switch self.collectibleType { |
| case .gloop: |
| texture = SKTexture(imageNamed: "gloop") |
| case .none: |
| break |
| } |
| |
| // Call to super.init |
| super.init(texture: texture, color: SKColor.clear, size: texture.size()) |
| // Set up collectible |
| self.name = "co_(collectibleType)" |
| self.anchorPoint = CGPoint(x: 0.5, y: 1.0) |
| self.zPosition = Layer.collectible.rawValue |
| } |
| |
| // Required init |
| required init?(coder aDecoder: NSCoder) { |
| fatalError("init(coder:) has not been implemented") |
| } |
This code initializes a Collectible object and sets its texture, name, anchorPoint, and zPosition properties.
Notice that you get the following error when setting the zPosition: Type Layer has no member collectible. To fix this error, open the SpriteKitHelper.swift file and modify the Layer enum so that it matches this:
| enum Layer: CGFloat { |
| case background |
| case foreground |
| case player |
| case collectible |
| } |
This updated code adds a new case for the z-position—essentially, another layer—above the player layer and clears the error.
Now that you have the groundwork laid for your collectible items, you’re ready to get the collectible drops added to the game scene using the process of iterative and incremental development.