How To Make a Letter / Word Game with UIKit and Swift: Part 2/3

In this second part of the tutorial series, you’ll aim for developing a fully playable version of the game. When you’re finished, the user will be able to drag the tiles and drop them on the correct targets, where they will “stick” to the spot. By Caroline Begbie.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 6 of this article. Click here to view the first page.

Creating a HUD

HUD’s up!

Your game could use some controls and readouts. You might ask, “Should I add these elements to the gameView?”

No. The gameView is for all gameplay elements. You generally want to put elements like the score, time readouts and player controls onto their own view layer. This allows you to do many types of things more easily, like hide them when the game is paused, or maintain fixed sizes and locations for these controls while simultaneously zooming in on some area of the game board.

This separate layer is often called a heads-up-display, or HUD. It will be easier to test your HUD layer if you have something to display in it, so first you will make a label to display the game timer.

Create a new Swift file in Anagrams/Classes/Views named StopwatchView. This will be a subclass of UILabel that displays the remaining time in the format “[minutes]:[seconds]”.

Open up StopwatchView.swift and replace its contents with the following:

import UIKit

class StopwatchView: UILabel {
  
  //this should never be called
  required init(coder aDecoder:NSCoder) {
    fatalError("use init(frame:")
  }

  override init(frame: CGRect) {
    super.init(frame: frame)
    self.backgroundColor = UIColor.clearColor()
  }
  
  //helper method that implements time formatting
  //to an int parameter (eg the seconds left)
  func setSeconds(seconds:Int) {
    self.text = String(format: " %02i : %02i", seconds/60, seconds % 60)
  }
}

The above code isn’t fancy. It just sets the label’s background to be transparent (the “clear” color), and creates a method to set the label’s text property to the mm:ss format.

Now that you have a label to display, you need a HUD layer to hold it. Create a new Swift file in Anagrams/Classes/Views named HUDView and replace its contents with the following:

import UIKit

class HUDView: UIView {
  
  var stopwatch: StopwatchView
  
  //this should never be called
  required init(coder aDecoder:NSCoder) {
    fatalError("use init(frame:")
  }

  override init(frame:CGRect) {
    self.stopwatch = StopwatchView(frame:CGRectMake(ScreenWidth/2-150, 0, 300, 100))
    self.stopwatch.setSeconds(0)
    
    super.init(frame:frame)
    self.addSubview(self.stopwatch)
  }
}

For now, you’ll have a single stopwatch property that holds a timer initialized to 0 seconds remaining.

Now to get that timer on the screen! You haven’t checked your progress in a while.

First add a HUDView property to the game controller. Inside GameController.swift at the top of the class, add:

var hud: HUDView!

Next you’ll create the HUD view in your ViewController – the same spot where you create the game view. Switch to ViewController.swift and inside viewDidLoad(), find the line controller.gameView = gameView and just below it, add the HUD to the window’s view and the game controller:

//add one view for all hud and controls
let hudView = HUDView(frame: CGRect(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight))
self.view.addSubview(hudView)
controller.hud = hudView

You create a new HUD view as big as the screen and you add it to the view controller’s view. Then you also assign it to the game controller’s hud property.

OK, build and run again and have a look at your new HUD layer!

Ugly Label!

Well, that’s some progress. Before you move on with the functionality, now is probably a good time to talk about….

The Art of Gamification

The fact you are using UIKit to create a game does not mean that you also have to use vanilla UIKit components. To make a game more “game-like”, you will want to use fonts, buttons and other controls that look like they belong in a game and not in a spreadsheet program.

For example, compare the two fonts below:

Compare fonts

If you think the first font rendered above is more exciting, in a game context at least, perhaps you should hire a graphic designer :]. Long story short, choose an appropriate font for your game. You’re not likely to excite players with a game menu rendered in Arial or Verdana.

Note: Then why did you go for good old Verdana when you created the tile view? On tiles, it makes sense to have maximum readability. Players shouldn’t get confused about which letters they’re seeing.

I’ve included a fun font for you in the project. To use it, first open up Config.swift and add these font constants:

let FontHUD = UIFont(name:"comic andy", size: 62.0)!
let FontHUDBig = UIFont(name:"comic andy", size:120.0)!

Some of you probably will ask, “Isn’t it faster to put the font definition in the code? Why should it be in a separate file?”

The answer is convenience. Imagine your graphic designer finds a much cooler font for your game. If you already have font assignments sprinkled all over the game code, replacing them will be a pain.

What’s more, abstracting the font size is a very good idea. That’s why you have two definitions – one for a big font and one for normal-sized font. This makes it a lot easier to change the font size in all HUDs throughout your game with a single line change.

Open StopwatchView.swift and add the following line to the end of init(frame:):

self.font = FontHUDBig

This sets the label’s font to FontHUDBig, which you just defined in Config.swift.

Build and run again to behold your new, game-ready label!

Note: If you want to include your own font, as well as importing it into the project, you need to add the font to the project’s Info.plist using the key Fonts provided by application.

Beautiful timer!

Nice! However… if you try to drag the tiles around you will notice they don’t drag anymore…

Well… actually, that’s fine. It’s all because of how you normally have views ordered in a game setup.

As illustrated in the schema below, you will always have the game controls, score, time, etc. on top, so that they are always visible. Under the controls you will have all the objects that move – heroes, word tiles, and so on. And usually at the very back you will have the background – whether static or parallax, it does not matter.

You have exactly the same setup so far, but since the HUD view is on top of everything it swallows all touches. Fear not! You can easily turn off the user’s interaction with the HUD view, thus allowing the user to touch the tiles in the underlying game objects view.

Switch to HUDView.swift and at the end of the init(frame:), add the code to disable touches:

self.userInteractionEnabled = false

Now it’s fixed forever!

Build and run the game again, and you’ll see that you can have your timer and drag tiles, too! Sweet victory!

HUD works

Contributors

Over 300 content creators. Join our team.