Posted on by & filed under Content - Highlights and Reviews, Mobile Development.

In a previous post, iOS 5 Core Graphics: Creating Reusable Data Classes for Images, I looked at the task of drawing simple images to a graphical context using Core Graphics. Though it’s easy to do that sort of drawing directly in the drawRect: method of a UIView, doing so isn’t very repeatable.

To improve on this, I moved to an MVC (Model-View-Controller) architecture by creating a data model for images, and I then accessed that model with a controller. The result was more abstract and thus the sort of thing that I could use to create multiple games with my single graphics framework.

Here’s how my code was structured by the time I was done:

Abstracting data is just the first step; however, in creating data classes of this sort. You’ll also want to fill your controller with methods associated with the model. Some of them may simplify complex tasks while others may dynamically adjust the models themselves. I’ll be examining both sorts of methods in this article.

Encoding complex actions

To date, I’ve created one simple method for adding new images to my GameWindow — addImage:withFrame:, which places an image within a specific frame in the GameWindow. It’s theoretically sufficient, but it ignores the fact that I’ll often be placing images in the same places from game to game.

I’ve identified three sorts of image placements that are likely to repeat, and which require ugly calculations right now when I use addImage:withFrame:

  • Backgrounds. These are images that are resized to fill the entire background of a view.
  • Idents. These are images that are drawn at their full size, indented a specific amount from two of the edges of a view.
  • Logos. These are images that (in my games at least) are indented 5 pixels from the left and top edges.

In each of these cases, it’d be very easy to add a new method to the GraphicController that would standardize that type of placement. Then, when you’re programming future games, you can just call the more sophisticated method, making your programming easier (and keeping out simple mistakes). Overall, this sort of standardization is at least as important as the abstraction already completed when you’re creating good classes for reuse.
An addBackgroundImage: class just requires resizing the picture to the GameWindow’s frame:

The addImage:atIndent: code is the messiest, because I want to allow for positive indents (from the left and top edges) and negative indents (from the right and bottom edges). Of course, that messiness just makes me more grateful that I only have to write the code once:

With that in hand, a standardized addLogo: method becomes very simple:

Now I can return to the ViewController and write a much more intuitive viewDidLoad:. More importantly, I can also do so using different graphics for the next game and the next game.

That fulfills the goal of writing class methods to simplify image tasks — allowing me to move on to the question of making those images more dynamic.

Indexing the Graphics

The NSMutableArray that’s used to store the images is a good choice as it guarantees the order that the images are drawn in. That’s pretty important because I want the background to be drawn first and everything else to go on top of it.

Unfortunately, I can’t yet rearrange the image drawing order; instead images are drawn based on the sequence of the addImage: messages. Also, as you may have noted, I can’t delete images once I’ve added them.

Dynamically interacting with existing images in these ways requires a different sort of storage: an NSMutableDictionary that will allow for quick lookups. Fortunately, that’s an easy addition. After inserting a graphicsIndex NSMutableDictionary into the header file of GraphicController and initializing it in initInGameWindow: I just need to set it in addImage:withFrame:

Now I have a second way to access all of my images — one that will be very helpful when I’m looking for a specific image.

Moving and removing graphics

With that in hand, it should be pretty simple to code methods that can be used to rearrange and delete graphics, which together will complete the foundation of the Graphics classes that I’ve been designing in these two articles. removeImage: clears out the storage and then tells the GameWindow to redraw itself:

Moving an image below another image is very simple because I can use NSMutableArray’s insertObject:atIndex: method without modification.

Moving an image above another image takes more work because there’s not an insertObject:afterIndex: method. As a result, I needed to watch out for exceeding the bounds of the array:

Both of these methods (of course) also tell the GameWindow to redraw. They could be improved by some error checking, but I’ve left that out to show off the code in its barest form.

The next step

At this point, you should have a very functional set of classes for drawing images in Core Graphics. They abstract the idea of images, they simplify repetitive tasks, and they allow for dynamic modification.

There is; however, plenty of possibility for expansion:

  • The images model could be much more complex. For example, in the actual images model I use in my iOS games, I have an isShadowed Boolean that the view uses to paint an attractive backshadow behind images.
  • Buttons would be an obvious expansion to the framework. They could be very simple — just an isButton Boolean in the model that tells the GameWindow to watch for touches within the image’s bounds — or they could be a more complex additional class that does fancy things like toggling images and counting taps.
  • Similar models and controllers could be created for text, boxes, or other repeatable Core Graphics elements to be used in a GameView.

This article should provide the basic architectural ideas that you’ll need to pursue those possibilities.

Safari Books Online has the content you need

Check out these iOS books available from Safari Books Online:

iOS 5 Essentials will help you learn how to build simple, yet powerful iOS 5 applications incorporating iCloud Storage, Twitter, Core Image and Newsstand integration.
Building iOS 5 Games: Develop and Design offers real world iOS 5 examples and actual games the reader can code and play and is aimed at people who understand programming concepts but are new to iOS game development.
iOS 5 Programming Cookbook contains more than 100 new iOS 5 recipes covering iCloud, Automatic Reference Counting, storyboarding, graphics, animations, Grand Central Dispatch, threads, timers, audio and video and many other iOS 5 tools and techniques.
Assuming only a minimal working knowledge of Objective-C, and written in a friendly, easy-to-follow style, Beginning iOS 5 Development offers a complete soup-to-nuts course in iPhone, iPad, and iPod touch programming.

About the Author

  Shannon Appelcline is a versatile author and programmer. He currently works as the lead iOS developer for Skotos Tech, an online entertainment company. In the past two years, he’s written five iOS games for them, all based on tabletop releases by popular German designers. The first of these was Reiner Knizia’s Money (2010)—which has also been ported to MacOS—while the most recent was Reiner Knizia’s Modern Art: The Card Game (2011). Shannon’s two most recent books show the breadth of his interests. They are iOS4 in Action (2011), published by Manning Publications, and Designers & Dragons: A History of the Roleplaying Game Industry (2011), published by Mongoose Publishing.

Tags: Core Graphics, Data Classes, Drawing images, Images, iOS5,

Comments are closed.