Tap Move ShakeTap, Move, Shake
A Hands-on Guide to Creating Multi-touch Games with iPad and iPhone

“This book is so great.” –Steve Wozniak, Apple Co-founder

Got a great game idea? This complete do-it-yourself guide shows you how to make your game idea a reality for the iPhone and iPad. By developing a real game hands-on through the course of this book, you’ll get a thorough introduction to Xcode and Objective-C, while learning how to implement game logic, sophisticated graphics, game physics, sounds, and computer AI.

Steve Wozniak and Todd Moore

Steve Wozniak and Todd Moore

Available at Amazon, iBookstore, Barnes & Noble, and O’Reilly Media.

App Store
– Download Paddles game which implements the classic game of pong in 20 lines of code.
– Download Air Hockey which demonstrates complex game logic, graphics, sounds, and computer AI.

Chapter 2 – Download the Paddles resources which includes the pong sound effects.
Chapter 3,5 – Download the Air Hockey resources which includes the graphics and sounds for Air Hockey.

Source Code
Chapter 1: Introduction to Xcode – Download the Game code which asks math questions.
Chapter 2: Hello Pong – Download the Paddles code which implements the classic game of pong.
Chapter 4: Physics – Download the Touches code which draws circles around multiple touches.
Chapter 3-5: Graphics, Physics, Sounds – Download the AirHockey code which implements two player air hockey.
Chapter 6: Computer AI – Download the AirHockey+AI code code which adds 3 levels of computer difficulty.


59 Responses to Book

  1. Michael Hemberger says:

    I just bought the ebook.
    Normally complete project code is made available with these books.
    Do you have any plans on releasing completed code with project?

  2. Agustin says:


    I love your book so far, I’m only in chapter 2, but I’m a bit stuck with the paddle game.
    I am having problems with the following method:


    the error is that both instances for Start and Reset seem to be missing, but I typed them there.

    this is my viewDidLoad code:

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self start];
    [self reset];

    Code for Start and Reset is here:

    - (void)reset
    // set direction of ball to either left or right direction
    if ((arc4random() % 2) == 0) dx = -1; else dx = 1;

    // reverse dy if not 0 as this will send the puck to the
    // player who just scored otherwise set in random direction
    if (dy != 0) dy = -dy;
    else if ((arc4random() %2) == 0) dy = -1; else dy = 1;

    // move point to random position in center = CGPointMake(15 + arc4random() % (320 - 30), 240);

    // reset speed
    speed = 2;
    - (void)start
    if (timer == nil)
    // create our animation timer
    timer = [[NSTimer scheduledTimerWithTimeInterval: 1.0/60.0 target:self selector: @selector(animate) userInfo: NULL repeats: YES] retain];
    // show the puck
    viewPuck.hidden = NO;

    I followed the instructions to the letter (or maybe not since I’m having problems)
    I’m also using the latest Xcode version (free license).

    I’d appreciate any and all help! thanks a lot!

  3. Hans Glitsch says:

    Hi Todd,

    I just finished reading your book “Tap, Move, Shake”. It was a really good, quick, and fun introduction to iphone programming and using xcode. I purchased the kindle version so I could have it on my screen next to xcode as I worked through the chapters. I really like the way you guided the projects in a kind of evolutionary way and built on what was done previously in the book. Your book was a really good way to get my feet wet and get a feel for how things are done. I only skimmed over the last two chapters, but it looks like there’s some really good advice in there — I intend to go back and reread them when I finish my first app.

    Now I need to read something that goes deeper and has more details about objective-c, the ios sdk, best practices, memory management, etc. Btw, I’ve been a c++ developer for over 20 years. Do you have any good book recommendations?


  4. Matas says:

    hi, please fix the 6th chapter source files, because when i click on the 6th chapter files i download files from 3-5chapter.
    Chapter 3-5: Graphics, Physics, Sounds – Download the AirHockey code which implements two player air hockey.
    Chapter 6: Computer AI – Download the AirHockey+AI code code which adds 3 levels of computer difficulty.

  5. Matt says:

    Hi Todd, i bought your book. ;) can you make tutorial without alerts ( tap the screen to play the game)? And game center wins count system?

    • todd says:

      Hi Matt, you could add a UILabel into the view that says “Tap To Start” and then track if the game is playing or not with a boolean. The touch handler could be used to start the game and hide the label. Apple sample code has a great class on managing Game Center interactions so I would start there. Cheers, Todd

  6. Stefan Fröhlich says:

    Hi Todd,

    I’ve downloaded all the sources for the book above.

    Unfortunately, none execept the “touches” example will compile using xCode 4.02/Snow Leopard.
    Here you can see the errors for the AirHockey project.

    Do your sample files require xCode 4.2? What can I do that I don’t get compiler errors on xCode 4.02?

    Thanks for your insights,

  7. MitchfromVA says:


    Tech 411 is the bomb! I’ve turned all my friend onto your podcast with out little buddy Oscar. (I’m a serious listener of TMOS and wish you guys the best). CAN I impose enough to ask a geeky question? If not just say the word and I will start researching the old fashion way…….just thought I would ask. THANKS!


    Question about high-speed internet, Cox Cable, and turning an old PC into a DVR

    What are you trying to do?? Capture Aussie Rules Football matches for later playback rather than wake up at 1:17 AM to watch a live event in Melbourne time.

    Incoming Sources: My high-speed internet bundle which gives me ESPN3 and Second is my Cox Cable TV subscription which gives me MhzNetworks which broadcast matches on their “world channel”.

    Question #1: Is there a difference between the signal coming in from high-speed internet and the signal coming in from a co-axial TV (HD Digital signal NOT analog signal) cable?

    Question #2: If so, is there a video card made that accepts two (2) inputs? Ethernet/wireless AND TV co-axial cable?

    Question #3: If so, is there a software program that tells the PC converted into a DVR, if you receive Ethernet/Wireless input record using this app. If you receive CATV input record using this app? Am I over thinking it??

    Question #4: Is it worthwhile to get a video card with an “HDMI out” to plug into the 42” TV that would be above this magical DVR/PC. Am I over engineering it?? This PC’s ONLY function would be as a DVR. No OS, no spreadsheets, no nothing. Storage of recorded programs only.

    Question #5: What is the best software/application/approach to turn an old PC into a functioning DVR?

    I’m good for a $50 Paypal to you or a gift certificate to the restaurant/bar of your choice….trust me I UNDERSTAND that time is money!!


  8. MitchfromVA says:


    Sorry I’m an idiot about DVR from old Dell PC question.

    Started reseaching and Monsoon Media’s Lava hold 6 to 8 hours and has MULTIPLE inputs / software based on your set up questions, cable provider, zip code, internet provider and gives you a custom “flicker-based menu” on you TV screen that you select just as with any DVR in the home. $199 direct from them (no shipping) or grab off the shelf at Best Buy, etc $199 off the shelf……………record and play back to you heart’s content.

    I apologize it you wasted the time reading BUT if you want to relate to 411 audience feel free !!!!! Best wishes again to you & Oscar!!


  9. Chris A. says:

    I chose to try and do the first Paddles exercise with Storyboards and ARC. No problems until I need to call the Pause and Stop methods from the PaddlesAppDelegate. I’m guessing since the PaddlesViewController is loaded by the Storyboard, it’s not the same as being loaded in didFinishLaunchingWithOptions? Any ideas how I would do that? Thanks!

  10. Fatso says:

    i downloaded the source for chapter 6, i cant find the AI class inside, did i download the wrong 1?

  11. Stefan Fröhlich says:

    Hi Todd,

    switching to Xcode 4.3.1 there is a problem with your 2 player sources of Air Hockey. It works well on iOS Simulator 5.1, but crashes on iOS Simulator 4.3:

    Here’s the stack trace:
    2012-03-22 18:47:11.580 AirHockey[5018:b903] *** Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key debug.’
    *** Call stack at first throw:
    0 CoreFoundation 0x00fcf5a9 __exceptionPreprocess + 185
    1 libobjc.A.dylib 0x014b8313 objc_exception_throw + 44
    2 CoreFoundation 0x00fcf4e1 -[NSException raise] + 17
    3 Foundation 0x009a1677 _NSSetUsingKeyValueSetter + 135
    4 Foundation 0x009a15e5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 285
    5 UIKit 0x0041d30c -[UIRuntimeOutletConnection connect] + 112
    6 CoreFoundation 0x00f458cf -[NSArray makeObjectsPerformSelector:] + 239
    7 UIKit 0x0041bd23 -[UINib instantiateWithOwner:options:] + 1041
    8 UIKit 0x0041dab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
    9 UIKit 0x002d3628 -[UIViewController _loadViewFromNibNamed:bundle:] + 70
    10 UIKit 0x002d1134 -[UIViewController loadView] + 120
    11 UIKit 0x002d100e -[UIViewController view] + 56
    12 UIKit 0x00244d42 -[UIWindow addRootViewControllerViewIfPossible] + 51
    13 UIKit 0x0024422d -[UIWindow _setHidden:forced:] + 303
    14 UIKit 0x0024401d -[UIWindow _orderFrontWithoutMakingKey] + 50
    15 UIKit 0x00242cd1 -[UIWindow makeKeyAndVisible] + 39
    16 AirHockey 0x000021ab -[PaddlesAppDelegate application:didFinishLaunchingWithOptions:] + 571
    17 UIKit 0x00221c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
    18 UIKit 0x00223d88 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
    19 UIKit 0x0022e617 -[UIApplication handleEvent:withNewEvent:] + 1533
    20 UIKit 0x00226abf -[UIApplication sendEvent:] + 71
    21 UIKit 0x0022bf2e _UIApplicationHandleEvent + 7576
    22 GraphicsServices 0x01f67992 PurpleEventCallback + 1550
    23 CoreFoundation 0x00fb0944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    24 CoreFoundation 0x00f10cf7 __CFRunLoopDoSource1 + 215
    25 CoreFoundation 0x00f0df83 __CFRunLoopRun + 979
    26 CoreFoundation 0x00f0d840 CFRunLoopRunSpecific + 208
    27 CoreFoundation 0x00f0d761 CFRunLoopRunInMode + 97
    28 UIKit 0x002237d2 -[UIApplication _run] + 623
    29 UIKit 0x0022fc93 UIApplicationMain + 1160
    30 AirHockey 0x00001eaa main + 170
    31 AirHockey 0x00001df5 start + 53
    32 ??? 0x00000001 0x0 + 1
    terminate called throwing an exception(lldb)

    There is a similar problem with the AI version.

    Strange thing is: my personal AI version works! Unfortunately, my 2 player version doesn’t. What’s the problem?

    Thanx for your help,

  12. David Blair says:


    When is the book going to be available on the UK iTunes?

    • todd says:

      I’m surprised it isn’t. I’ll check on it.

      • David Blair says:

        I have an app under development which is a folio of design and photography. I have wallpapers, twitter and flickr integration. To help get the app through the review process I want to put in a simple game (such as the air hockey one).

        You have some code in the implentation file. As the game I want to do would be a screen off of the home screen, would I still put the code into the implenation file?

        Sorry if this question makes no sense.

  13. Martin says:

    When the paddles game is running I see the following in the debug area:

    Applications are expected to have a root view controller at the end of application launch

    This only started appearing after the alert message was put into the code to ask the user if they are ready to play.

    How do you get rid of the message?

  14. Martin says:

    I did some searching on the web and found this answer and it worked for me.


    Try replacing [alert show] with:
    [alert performSelector:@selector(show) withObject:nil afterDelay:0.0];

    This delays the alert for a single pass through the runloop, presumably allowing your app’s controllers and storyboards to complete their setup before the alert is presented.

    • todd says:

      Thanks for the info. Did you create your project with storyboards?

      • Martin says:

        No I didn’t Todd. I followed the directions that you had for creating the Paddles project without storyboards. I don’t know how to use storyboards yet. :)

        I forgot to initially mention that I was using the iOS 5 simulator.

        Everything worked great! On to Graphics now!

  15. Martin says:

    Hi Todd,

    I finally made it to Chapter 3 Graphics. I was having trouble connecting the puck and the paddles to their respective property definitions. The scores were already connected from before. I am running XCode 4.2. But when I unconnected the first score and then tried to reconnect it, I couldn’t do it. So nothing happens when the game starts.

    I am able to ctrl-click and drag a line from the puck and paddles, to the property definition.

    Oh, I needed to manually bring up the ViewController.h file. It was not there automatically.

    What am I doing wrong?

    • todd says:

      Sometimes the assistant doesn’t automatically pull up the correct header but it’s easy enough to manually do it as you found out. If you command-click or right click on the game object (puck/paddles) you will be able to see what the object is connected to if anything. You can then make sure it is connected to the correct object in the header file. Just make sure the correct header file and XIB file are opened up and on screen at the same time.

      • Martin says:

        Yeah, I had to manually bring up the correct header. Some of my problem may have been due to the fact that I renamed the PaddlesViewController to AirHockeyViewController.

        I was able to see if the game object was connected to anything, but couldn’t make a connection.

        I did find a link that helped out.

        But it wasn’t a success right away. It still had issues. But I got it to work out. But first I had the paddles assigned to the wrong property and that was interesting. But I fixed that and all was fine.

        It was a good chapter. I had downloaded a trial version of Adobe Fireworks and was trying to go along with the chapter, but it was a little different for some reason. Oh well, I understood what needed to be done and it was helpful.

  16. Martin says:

    Hi Todd,

    I just finished Chapter 6. There were a few things that tripped me up.

    I had trouble on page 178. The new screen would not come up. I got a sigabrt in thread 1. While attaching the buttons, I had one of them assigned to a referencing outlet which wasn’t correct. Had to detach that. Not sure how that happened.

    I also had trouble on page 183. Got a sigabrt there too. The cause came from the page that had us add gameController to the AirHockeyAppDelegate.h file, we weren’t told to add a synthesize for the gameController in the AirHockeyAppDelegate.m file. Note that I use the name AirHockeyAppDelegate instead of PaddlesAppDelegate.

    Later on when we add debug, we need to add a synthesize for debug. Plus make sure we connect the debug label to the property definition for debug.

    Heading on to Chapter 7 now. :)

  17. Peter says:


    I’ve bought the book a few days ago for Kindle and am struck in chapter one. I’m using Xcode 4.5 (4G182).

    1) In GameViewController.m I’ve got vievDidLoad and didReceiveMemoryWarning, but no viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear and viewDidUnload. Is this because of newer Xcode version?
    I’ve added NSLog to the two I do have and just went on.

    2) Making the connections for interface, I can’t select Action instead of Outlet in the popup for the submit button, the selection area is grey like in figure 1-19.
    The two other items worked, but in GameViewController.m there’s again no viedDidUnload, so I see no [self setLabel/Answer:nil].

    • todd says:

      1. Just paste in the methods if they aren’t already included and everything should work fine. 2. Make sure you have a button selected and not a label. Check the Type on the popup. 3. Also make sure when you generate the project you did not select ARC (automatic reference count). All the book code was generated not using ARC.

  18. nico koller says:

    Hey Todd
    i have a problem with my app
    can you just look about it and tell me what i did false ?

  19. Brett says:

    Hi Todd,

    I’m in chapter 4 and looking back at the screen shot from ch3 fig 3-16 the “score” labels are in vertical orientation with relation to the top of the screen.
    After making changes to the app as described in ch4, building and running app the labels are still in the same orientation but in screen shot fig 4-2 the “score” labels are rotated 90 deg.

    How was that accomplished?


    • todd says:

      Good catch! Add the following to the viewDidLoad method:

      // rotate score text
      viewScore1.transform = CGAffineTransformMakeRotation( M_PI / 2.0 );
      viewScore2.transform = CGAffineTransformMakeRotation( M_PI / 2.0 );

  20. Mike says:

    Hi Todd,

    I just got your book a week ago and am loving it so far! However, I’ve run into a problem I can’t seem to solve myself. In chapter 6 (computer AI) I had implemented the title screen and most of the AI states, but when I added the last state (AI_START) and put in the debug label at the top of my screen, it broke the game.

    Now when I select 1 player vs comp, it constantly resets the game, anywhere from every 2 seconds to multiple times per second. I added NSLogs to all the methods like reset and newGame etc, and none of them were being called except when they should be. I also wasn’t (intentionally) altering anything except what the book told me to, which was basically just the computerAI method in PaddlesViewController.m.

    I’m wondering if somehow I could have pressed a wrong button or clicked the wrong place while trying to drag in and position the new label in the nib file. I have tried deleting it and remaking it, and I’ve tried adding a breakpoint to the computerAI method so I can see exactly when the game is resetting itself (both paddles and the puck all get re-centered). It seemed that everything was running normally and then suddenly it got reset for no apparent reason.

    Hopefully you can give me some insight! Thanks in advance, and thanks for the great book!


  21. KevinH says:

    Hiya Todd,

    Great book but having one issue so far. I’m at the Increasing Difficulty part of the paddles app and I’ve still to get the puck to move. I’ve rechecked the code, referenced with yours that I’ve downloaded from the site and even started from scratch once. ARC is disabled… uuurrrrgggg…

  22. Antoine says:

    Hi Todd,

    For random number generation, you should not use: arc4random() % upperBound, unless upperBound is a divisor of 2**31

    This causes a bias; this is certainly not perceptible for small numbers, but you don’t how your readers will use what they have learned. Maybe somebody will use arc4random() % ((2**32)-1 ) /3 . As you don’t mention that there is a bias, I suspect that may not be aware of it.

    From the arc4random man page:

    arc4random_uniform() will return a uniformly distributed random number less than upper_bound.
    arc4random_uniform() is recommended over constructions like “arc4random() % upper_bound” as it avoids “modulo bias” when the upper bound is not a power of two.

    Great book by the way, and have a nice day.

  23. Pingback: Air Hockey: Tap, Move, Shake iOS Mobile Game App ID 463154960

  24. Sam says:

    Hi Todd, thanks a lot for making this book,really useful for a newbie like me
    I do have some problems with the coding for the Math game.

    – (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);

    – (void)dealloc
    [label release];
    [answer release];
    [super dealloc];
    – (IBAction)submit:(id)sender
    // convert our answer text value into an integer
    int num = [answer.text intValue];
    // check if it is correct by comparing to the label tag
    UIAlertView *alert;
    if (num == label.tag)
    // answer was correct

    alert = [[UIAlertView alloc]
    message:@”Let’s try another one!”
    otherButtonTitles: nil];
    // use the alert tag to mark that answer was correct
    alert.tag = 1;
    } else
    // answer is incorrect
    alert = [[UIAlertView alloc]
    message:@”That answer is incorrect.”
    cancelButtonTitle:@”Try Again”
    otherButtonTitles: nil];
    // show and release the alert
    [alert show];
    [alert release];

    The errors I get are :
    Semantic Issue – ‘release’ is unavailable: not available in automatic reference counting mode

    ARC Restrictions – ARC forbids explicit message send of ‘release’
    ARC Restriction – ARC forbids explicit message send of ‘dealloc’

    Hope to hear from you soon. Thanks.

    • todd says:

      The book example does not use ARC. So you can either recreate the project without ARC -or- just remove the lines where you call [alert release];


  25. Vito says:

    Hi Todd,
    Truly sorry to bother you, I bought your book last week.
    I’m now sticking on p.121 :
    – (IBAction) onPlay: (id) sender
    ” [app Playgame: button.tag] ”
    it can’t build successfully and pop out warning message:
    ” implicit conversion loses integer precision : ‘NSInteger’ (aka ‘long’) to ‘int’ ”
    I’m a beginner of learning Obj-c, using Xcode version 5.1.1.
    Hope you can help me, much obliged.

  26. Tom says:

    Dear Todd,
    I recently got your book Tap, Move, Shake and have been working through it on Xcode version 5.1.1. I just had a question as I am having some trouble. Firstly, on pages 22 to 24 I need to type in the various NSLog statements. The only problem is, I can’t see some of the code that appears to already be there. After the first NSLog (didFinishLaunchingWithOptions), I am unable to see the code below that begins with self.viewController = [[GameViewController … . Another problem that I am having is that I cannot see the file named GameViewController.xib, I thought that the one called Main.Storyboard was similar and was the correct one instead. Lastly, another example of the problem I have is that on page 43-45 I cannot see some of the boxes such as the simulated metrics boxes. (pg. 44). I thought that maybe it was because of my version of Xcode but I was still unsure. Overall though, I really like the book and I am looking forward to continuing to work my way through it. Thanks, Tom

  27. Joan says:

    Hello Todd,I brought your book,i am really happy that now i can program in Obj-C.
    But i have a question.
    [self viewController (anOther method)] is not working on xCode 5.1.
    Can you help me with that case?
    Thank You!

  28. Alex says:

    Hello, Mr. Todd!
    Many thanks for your book! I bought it in Russia. This book has helped me to begin the exciting journey into the world of programming!
    I tried to add in the “Paddle” hilarious storyline – this is what happened:
    On my site there Promotional codes.
    Thank you again!

  29. Maciej says:

    Hi Todd,

    Your book is really great! I’m currently at chapter 2, trying to write Paddles for iOS 7 on Xcode 5.

    Most works fine, but I encountered an issue related to restarting after game is over and message box is shown: the puck position is restarted to random position on central line, but not moving.

    Second problem is when trying to call “pause” and “resume” methods from PaddlesAppDelegate. How can I reference ViewController methods in latest SDK?

    Can you help, please?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>