How To Make a Letter / Word Game with UIKit: Part 1/3

This 3-part tutorial series will guide you through the process of building a board game for the iPad, where you create words with letters. You’ll also learn about best practices for creating solid, modular iOS apps. And as a bonus, you’ll get a crash course in audio-visual effects with UIKit! By Marin Todorov.

Leave a rating/review
Save for later
Share

Update 11/5: We have updated this post for iOS 8 and Swift – check out the updated version!

Are you a seasoned iOS developer who is thinking of creating an iOS game, but have no experience programming games? Maybe learning OpenGL ES makes you uncomfortable, or maybe you’ve just never crossed paths with Cocos2d for iPhone?

Well, good news! UIKit is a power tool for game developers. Its high-end frameworks provide you with the means to create all of your game logic, from creating animations (including frame-animation) to playing audio and video.

This 3-part tutorial series will guide you through the process of building a board game for the iPad, where you create words with letters. You’ll also learn about best practices for creating solid, modular iOS apps. And as a bonus, you’ll get a crash course in audio-visual effects with UIKit!

This tutorial series is designed for readers who are already somewhat familiar with Objective-C, and thus won’t go over details like primitive types or syntax. If your Obj-C knowledge is rusty, I recommend checking out our Objective-C Crash Course.

Click through to get your game on!

Getting Started: Introducing Anagrams

The letter / word game with UIKit you will be making in this tutorial is about anagrams.

An anagram is a word or phrase formed by rearranging the letters of another word or phrase. For example, the word cinema can be rearranged into the word iceman. Your game will challenge the player to create anagrams from words and phrases you provide.

The finished game will look something like this:

As you can see, there is a row of letter tiles on the lower end of the screen that makes up the initial phrase. In the screenshot above it is the word admirer, minus the M tile, which the player has dragged to the upper row.

The player’s job is to drag the letters from admirer to form a different word, using the same letters.

Can you guess what it is? I’ve already given you a hint… it starts with an M!

[spoiler title=”Answer”]

The correct answer is married. Did you figure it out? If so, give yourself a high-five!

[/spoiler]

So anyway, this is the game you will be making. As you build this game, you will learn about the following foundational topics:

  • Proper model-view-controller (MVC) game structure.
  • Loading level configuration from config files.
  • Organizing your game controller logic.
  • Writing a simple audio controller for UIKit with AV Foundation.
  • Using QuartzCore for static visual effects.
  • Using UIAnimation to smooth in-game movements.
  • Using UIKit particles to add visual effects.
  • Building separate HUD and game layers.
  • Using game fonts to improve the look and polish.
  • Upgrading default UIKit components to game-like components.
  • Also included: discussion of the software tools I use along the way when I’m creating a game. :]

Oh, and there will be explosions. :] Let’s dig in!

The Starter Project

To get you straight to the good stuff – using UIKit to build an iOS game – this tutorial provides a ZIP file that includes a starter XCode project and all game assets (images, fonts, audio and config files).

Download the Anagrams Part 1 starter file, unzip it and open it up in Xcode.

Have a look at what’s bundled in the starter project. The project file browser on the left should look something like this:

Here’s a quick summary of what you see:

  • config.h: Your code configs in one place.
  • Levels: A folder with three .plist files to define the game’s three difficulty levels.
  • Classes/models: This is where you’ll add your data models.
  • Classes/views: This is where you’ll create your custom view classes.
  • Classes/controllers: This is where you’ll create your controllers.
  • Assets/Fonts: A custom TTF font for the game HUD.
  • Assets/Particles: There is a single PNG file to use for particle effects.
  • Assets/Audio: Creative Commons-licensed audio files.
  • Assets/Images: These are all the images you’ll use to create the game.
  • MainStoryboard.storyboard: Open up the storyboard and you’ll see there’s only one screen with the background set to a faint woodgrain image, which is included in the project assets.
  • credits.txt: Includes links to the sources of all the assets used in the project.

Poke around, play the sounds and browse the images. Then run the project.

It’s much better than an empty app window, isn’t it?

In this first part of the series, your goal is to display the initial anagram and target boxes on the screen. In future tutorials, you’ll add the ability to drag the tiles, and the gameplay logic.

There’s a lot involved to get this first part working. But don’t worry, you’ll break down this epic task into 8 small steps:

  1. Load the level config file.
  2. Create a game controller class.
  3. Create an onscreen view.
  4. Create a tile view.
  5. Deal the tiles on the screen.
  6. Add the letters.
  7. Slightly rotate the letters randomly.
  8. Add the targets.

Let’s go over these one step at a time.

1) Load the Level Config File

Select the level1.plist file in the project file browser. Have a look what’s inside:

There are three top-level keys:

  • pointsPerTile: the points awarded for each correctly-placed tile.
  • timeToSolve: The number of seconds the player will have to solve the puzzle.
  • anagrams: A list of anagrams, each anagram containing two items, an initial and a final phrase.

Don’t bother for the moment with the first two and focus on anagrams. It’s an array of array-elements and each element has two string elements. You’re now going to build a data model to load this configuration in Objective-C.

Create a new Objective-C class file in the Anagrams/Classes/models folder. Call the new class Level and make it a subclass of NSObject.

Open up Level.h and in between the @interface and @end lines, add the following properties and method for your Level class:

//properties stored in a .plist file
@property (assign, nonatomic) int pointsPerTile;
@property (assign, nonatomic) int timeToSolve;
@property (strong, nonatomic) NSArray* anagrams;

//factory method to load a .plist file and initialize the model
+(instancetype)levelWithNum:(int)levelNum;

The properties match the structure of the .plist file, so you are simply going to load the data and populate the properties. You also declare a factory method to produce Level class instances for a given difficulty level. These will range from 1 to 3, going from easiest to most difficult.

Now add the code to power-up the Level data model class. Inside the class implementation in Level.m, add the method body of the factory method to create Level instances:

+(instancetype)levelWithNum:(int)levelNum;
{
    //1 find .plist file for this level
    NSString* fileName = [NSString stringWithFormat:@"level%i.plist", levelNum];
    NSString* levelPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];

    //2 load .plist file
    NSDictionary* levelDict = [NSDictionary dictionaryWithContentsOfFile:levelPath];

    //3 validation
    NSAssert(levelDict, @"level config file not found");
    
    //4 create Level instance
    Level* l = [[Level alloc] init];

    //5 initialize the object from the dictionary
    l.pointsPerTile = [levelDict[@"pointsPerTile"] intValue];
    l.anagrams = levelDict[@"anagrams"];
    l.timeToSolve = [levelDict[@"timeToSolve"] intValue];

    return l;
}

There are four small sections in the method body – four small steps towards the goal of the method, if you will:

  1. Determine the path to the appropriate level config file (level1.plist, level2.plist, etc), based on the levelNum value passed into the method.
  2. Load the file’s contents into an NSDictionary. Fortunately, the NSDictionary class knows how to parse .plist files!
  3. Validate that there’s something loaded in levelDict. I use NSAssert often for errors that should never happen in a shipped app. (I.e., if they EVER happen during development I want the app to stop and crash, so I can fix it before doing anything else.)
  4. Create a new instance of Level.
  5. Copy the values from the NSDictionary to the Level object’s properties.

Now let’s give the class a try and validate your achievement of the first step towards the goal!

Open up ViewController.m and add at the top:

#import "Level.h"

And at the end of viewDidLoad:, add:

Level* level1 = [Level levelWithNum:1];
NSLog(@"anagrams: %@", level1.anagrams);

In the Xcode console you will see the list of anagrams for Level 1. Nice!

Now you can remove the NSLog line from viewDidLoad to keep the console tidy.

That’s one task knocked down. Ready to move ahead to the next one?

Contributors

Over 300 content creators. Join our team.