Book Image

iOS 9 Game Development Essentials

By : Chuck Gaffney
Book Image

iOS 9 Game Development Essentials

By: Chuck Gaffney

Overview of this book

Table of Contents (15 chapters)
iOS 9 Game Development Essentials
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Mutable/immutable collections


One rather important discussion that we've left out is how to subtract, edit, or add to arrays, sets, and dictionaries. However, before we do this, you should understand the concept of mutable and immutable data/collections.

A mutable collection is simple data that can be changed, added to, or subtracted from, whereas an immutable collection cannot be changed, added to, or subtracted from.

To work with mutable and immutable collections efficiently in Objective-C, we had to explicitly state the mutability of the collection beforehand. For example, an array of the type NSArray in Objective-C is always immutable. There are methods we can call on NSArray that would edit the collection, but behind the scenes, this would be creating brand new NSArray objects, thus would be rather inefficient to do this often in the life of our game. Objective-C has solved this issue with the class type, NSMutableArray.

Thanks to the flexibility of Swift's type inference, we already know how to make a collection mutable or immutable! The concept of constants and variables has us covered when it comes to data mutability in Swift. Using the keyword let when creating a collection will make that collection immutable, while using var will initialize it as a mutable collection.

//mutable Array
var unlockedLevels : [Int] =  [1, 2, 5, 8]

//immutable Dictionary
let playersForThisRound : [PlayerNumber:PlayerUserName] = [453:"userName3344xx5", 233:"princeTrunks", 6567: "noScopeMan98", 211: "egoDino"]

The array of integers, unlockedLevels, can be edited simply because it's a variable. The immutable dictionary playersForThisRound can't be changed since it's already been declared as a constant. There is no additional layer of ambiguity concerning additional class types.

Editing/accessing collection data

As long as a collection type is a variable, using the var keyword, we can do various edits to the data. Let's go back to our unlockedLevels array. Many games have the functionality of unlocking levels as the player progresses. Let's say that the player has reached the high score needed to unlock the previously locked level 3 (as 3 isn't a member of the array). We can add 3 to the array using the append function:

unlockedLevels.append(3)

Another neat attribute of Swift is that we can add data to an array using the += assignment operator:

unlockedLevels += [3]

Doing it this way however will simply add 3 to the end of the array. So, our previous array [1, 2, 5, 8] is now [1, 2, 5, 8, 3]. This probably isn't a desirable order, so to insert the number 3 in the third spot, unlockedLevels[2], we can use the following method:

unlockedLevels.insert(3, atIndex: 2)

Now, our array of unlocked levels is ordered to [1, 2, 3, 5, 8].

This is assuming though that we know a member of the array prior to 3 is sorted already. There are various sorting functionalities provided by Swift that could help keeping an array sorted. We will leave the details of sorting to our discussions of loops and control flow later in this chapter.

Removing items from an array is just simple. Let's again use our unlockedLevels array. Imagine that our game has an overworld for the player to travel to and from and the player has just unlocked a secret that triggered an event that blocked off access to level 1. Level 1 would now have to be removed from the unlocked levels. We can do it like this:

unlockedLevels.removeAtIndex(0) // array is now  [2, 3, 5, 8]

Alternately, imagine that the player has lost all of their lives and got a Game Over message. A penalty for this could be to lock the furthest level. Though probably a rather infuriating method and us knowing that level 8 is the furthest level in our array, we can remove it using the .removeLast() function of array types.

unlockedLevels.removeLast() // array is now [2,3,5]

Note

This is assuming that we know the exact order of the collection. Sets or dictionaries might be better at controlling certain aspects of your game.

Here are some ways to edit a set or a dictionary as a quick guide.

Set

inventory.insert("Power Ring")    //.insert() adds items to a set
inventory.remove("Magic Potion")  //.remove() removes a specific item
inventory.count                   //counts # of items in the Set
inventory.union(EnemyLoot)        //combines two Sets
inventory.removeAll()             //removes everything from the Set
inventory.isEmpty                 //returns true

Dictionary

var inventory = [Float : String]() //creates a mutable dictionary

/*
one way to set an equipped weapon in a game; where 1.0 could represent the first "item slot" that would be placeholder for the player's "current weapon"  
*/
inventory.updateValue("Broadsword", forKey: 1.0)


//removes an item from a Dictionary based on the key value
inventory.removeValueForKey("StatusBooster")

inventory.count                   //counts items in the Dictionary
inventory.removeAll(keepCapacity: false) //deletes the Dictionary
inventory.isEmpty                 //returns false

//creates an array of the Dictionary's values
let inventoryNames = [String](inventory.values)

//creates an array of the Dictionary's keys
let inventoryKeys = [String](inventory.keys)

Iterating through collection types

We can't discuss collection types without mentioning how to iterate through them en masse.

Here's some way we'd iterate though an array, a set, or a dictionary in Swift:

//(a) outputs every item through the entire collection
  //works for Arrays, Sets and Dictionaries but output will vary
for item in inventory {
    print(item)
}

//(b) outputs sorted item list using Swift's sorted() function
  //works for Sets
for item in sorted(inventory) {
    print("\(item)")
}

//(c) outputs every item as well as its current index
  //works for Arrays, Sets and Dictionaries
for (index, value) in enumerate(inventory) {
    print("Item \(index + 1): \(value)")
}

//(d)
//Iterate through and through the keys of a Dictionary
for itemCode in inventory.keys {
    print("Item code: \(itemCode)")
}

//(e)
//Iterate through and through the values of a Dictionary
for itemName in inventory.values {
    print("Item name: \(itemName)")
}

As stated previously, this is done with what's known as a for-loop; with these examples, we show how Swift utilizes the for-in variation using the in keyword. The code will repeat until it reaches the end of the collection in all of these examples. In example (c), we also see the use of the Swift function, enumerate(). This function returns a compound value, (index,value), for each item. This compound value is known as a tuple, and Swift's use of tuples makes for a wide variety of functionalities for functions, loops, as well as code blocks.

We will delve more into tuples, loops, and blocks later on.