This is part of an ELC Tech Network

iPhone Programming Tutorial: Animating A Game Sprite

One thing I have noticed about many of the games in the app store is they lack animation. Of course, the huge companies like Sega and PopCap have some pretty amazing animation, but what about us indie iPhone game developers?

Well, Apple has made it quite simple to do animations. I really feel this method is often overlooked. I will show you in just a few lines of code, how to completely animate your game images. I will walk you through creating a simple application that uses animation. If you don’t care about creating the app and just want the animation code, you can skip to this step.  We will be making an animation of Ryu throwing some punches.

1. Create A View Based Application

I’m not going to explain this one…

2. Add These Images To Your Resources Folder

Downloadryu.zip and unzip it. Then drag the unzipped files into your Resources folder. Note: Sprite sheet downloaded from http://panelmonkey.org/. This file contains 12 images of Ryu from Street Fighter punching. It also has the background to Blanca’s stage just for fun.

3. Create The Background

You don’t have to do this step, it’s just to make it pretty.

Double click on whateveryoucalledyourapplicationViewController.xib to open it in Interface Builder. Click the arrow button on the view to rotate it. If you don’t what I am talking about, check out this post.

Drag a UIImageView on to the screen and stretch it to fill the entire iPhone screen. In the Attributes inspector select sfst-blanka.jpg. Make sure mode is set to center as this image has very low resolution. It should look something like this (I have added a black background color).

screenshot_01

4. Creating The Animation

Open up yourApplicationViewController.m and add the following code to the viewDidLoad method.

Advertisement

- (void)viewDidLoad {
    [super viewDidLoad];
	NSArray * imageArray  = [[NSArray alloc] initWithObjects:
							[UIImage imageNamed:@"1.png"],
							[UIImage imageNamed:@"2.png"],
							[UIImage imageNamed:@"3.png"],
							[UIImage imageNamed:@"4.png"],
							[UIImage imageNamed:@"5.png"],
							[UIImage imageNamed:@"6.png"],
							[UIImage imageNamed:@"7.png"],
							[UIImage imageNamed:@"8.png"],
							[UIImage imageNamed:@"9.png"],
							[UIImage imageNamed:@"10.png"],
							[UIImage imageNamed:@"11.png"],
							[UIImage imageNamed:@"12.png"],
							nil];
	UIImageView * ryuJump = [[UIImageView alloc] initWithFrame:
		CGRectMake(100, 125, 150, 130)];
	ryuJump.animationImages = imageArray;
	ryuJump.animationDuration = 1.1;
	ryuJump.contentMode = UIViewContentModeBottomLeft;
	[self.view addSubview:ryuJump];
	[ryuJump startAnimating];
}

For all of you “1337″ coders that are going to post in the comments telling me “Why don’t you use a for loop to load the images” (very nerdy voice): I am doing it like this, so it is obvious what is going on.  I want to show that you must populate the array with images.

So here is what is going on in this code:

We first create an array of UIImages.  Next, we allocate our UIImageView. The next part is where the magic happens… Apple has given you a property of UIImageView that is an array of images.  The UIImageView class has a built in functionality to cycle through images at a given interval (hence animating them).

The next variable we see is the animation duration.  This is the number of seconds it takes to cycle through all of the images.  The default value for this is the number of images multiplied by 1/30.  This will give you a 30 fps frame rate.  Since we have 12 images and not 30, this duration would make our Ryu look like he was on crack.

In our case, the default would be 12 * (1/30) or .4 . We are going to slow this down significantly to 1.1.  Go ahead and play with this number when creating your animation.

The next variable is the contentMode.  The content mode determines how the image will fit inside the UIImageView frame.  Since our animation images vary in size, we just make the frame as large as the largest image and set the contentMode to UIViewContentModeBottomLeft.  What this means is, draw the image withough scaling and place it in the bottom left of the UIImageView.  Read up on contentMode to figure out what will be right for your applicaiton.

Finally, we just add the UIImageView to our main view and call the startAnimating method on it.  This will start the animation of these images.  There are also some other helpful methods you might use when doing animation.  They include stopAnimating and isAnimating.

5. Make Sure The Device Starts In Landscape Mode

In this example, we assumed that the device was in landscape mode.  Again, read this post to see how to do this.  It involves adding Initial interface orientation to the info.plist file and adding this code to your viewController.m file.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

That concludes our simple animation tutorial. Post a question or ask me on Twitter if you need help.  You can download the source for this tutorial here. Happy iCoding!

This entry was posted in iPhone Game Programming, iPhone Programming Tutorials, iphone and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

42 Comments

  1. Angel
    Posted July 24, 2009 at 12:34 pm | Permalink

    Clear and useful explanation! Thanks for sharing.

    Several questions after it if you do not mind:

    [1] Can yo limit the number of animation loops?

    [2] If the sprite has several animations in the game, would you [a] redefine it each time it changes, [b] use several sprites, other?

    Angel

  2. Posted July 24, 2009 at 12:40 pm | Permalink

    @Angel

    Great questions!

    1. Yes – just set ryuJump.animationRepeatCount = loopLimit

    2. I would use the same UIImageView but change the images array. So I’d have an array for jump, attack, move, etc…

    That way, you ensure the animation always happens at the correct location.

  3. Posted July 24, 2009 at 1:17 pm | Permalink

    Thanks for this tutorial! it will be very useful

  4. Modo
    Posted July 24, 2009 at 1:54 pm | Permalink

    Is there a callback implementation to notify UIImageView when animation has stopped?

  5. Posted July 24, 2009 at 1:56 pm | Permalink

    @Modo

    I doubt it. Check out the docs for UIImageView. It will show you all of the methods and properties you can use. You shouldn’t need to do this, a callback for when animation stops sounds like a bad design to begin with.

  6. Modo
    Posted July 24, 2009 at 4:30 pm | Permalink

    Fair enough. But my experience w. fighter games like in your example is you want to have a neutral animation loop while waiting for the next move. So you’d only want to execute a move or sequence of moves after the previous move had completed to produce a seamless animation.

    The only way I could come up with is possibly using NSTimers to trigger the next animation in a sequence. A callback, would be preferable than that though.

  7. Posted July 25, 2009 at 1:35 am | Permalink

    Great tutorial.

    I know you are not trying to focus on memory management in this tutorial, but you may want to release the imageArray and ryuJump vars at the end of your function… (both addSubview and setting animationImages should do a retain if I am not mistaken…)

  8. Mark
    Posted July 25, 2009 at 6:17 am | Permalink

    How did you go about cutting up the sprite sheet into separate images? Anyway to keep them in a single sheet and change the viewable area of the sheet with bounds maybe?

  9. Posted July 25, 2009 at 4:27 pm | Permalink

    Nice tutorial. Very straight forward and to the point.

  10. Andy
    Posted July 26, 2009 at 7:31 am | Permalink

    Yes i would really like to know how you cut the sheets up. Probably used photoshop but any info would be appreciated:)

    - Andy

  11. Posted July 26, 2009 at 9:52 am | Permalink

    @Mark @Andy – I just used photoshop. The great thing is, since we are using UIViewContentModeBottomLeft, the sprites don’t have to be the same size.

    So I just cut out each pose, and created a new file from it. Very simple actually. Too bad UIImageView doesn’t have a nice way to animate a sprite sheet.

  12. grinder
    Posted July 26, 2009 at 11:43 am | Permalink

    The only problem is, you are limited in number of animatable Sprite. If you use animation in 10 sprite, then you will see that iPhone is crying. Yet I didn’t get why only 10-11 sprite animation take huge overhead on this system.

  13. Posted July 26, 2009 at 11:48 pm | Permalink

    I am completely new to this. How do I go about the first step….I am eager to learn this..

  14. Andy
    Posted July 27, 2009 at 7:09 am | Permalink

    Thanks Brandon, luckily My brother is an Artist and I got an older version of PhotoShop to suit my needs :) Thanks again for all the great examples!

  15. Posted July 27, 2009 at 10:02 am | Permalink

    UIImage imageNamed is a really bad resource hog. It’s far better to use UIImage imageWithContentsOfFile. Take a look at this link for more information on the issue: http://www.alexcurylo.com/blog/2009/01/13/imagenamed-is-evil/

  16. Posted July 27, 2009 at 3:52 pm | Permalink

    @Sachin – Read some of my earlier tutorials. They are in the sidebar of this blog.

  17. Vamsi
    Posted July 28, 2009 at 2:15 am | Permalink

    Great tutorial. I got stuck at the connection inspector.

    When I try to connect the view2, I drag the referencing outlet on to File owner object, it does not give me drop down of view.

    Can you help me on what might be wrong?

  18. Posted July 28, 2009 at 2:26 am | Permalink

    Simply great.
    Is there a way to use a single file with tiled images ?

  19. Posted July 29, 2009 at 12:20 pm | Permalink

    Every programmer I’ve worked with on an iPhone game has used sprite sheets instead of arrays of images. Like another commenter said, once you get into 11-12 images in array using the multiple file method, the iPhone drags like hell.

    There’s a reason they used sprite sheets in the NES days, and still continue to do so. Slice up the single-file sprite sheet using code. It’s much less of a hog.

    What I’ve been doing is exporting Flash animation as PNG sequences from Flash, making sure that the images’ dimensions are a power of two (16×16, 32×32). I do a bit of math to figure out how many can fit on the smallest sprite sheet possible and how many columns to put together. Then I use GlueIt to put the sprite sheet together. Easy.

    Check out “Wedgie Toss” in the App Store for an example of how efficient the sprite sheet is. The background is a 2056×2056 PNG that we still managed to cram into the 24 mb texture memory limit.

  20. Posted July 29, 2009 at 12:50 pm | Permalink

    @Jim

    I understand the performance issues around doing it this way. I just wanted to show a simple way of doing animation without having to mess with OpenGL or Quartz.

    I have yet to find a way of doing simple animation without OpenGL or Quartz using a sprite sheet. Can you suggest one? I would love to post about it (crediting you of course) if you can.

  21. Posted July 31, 2009 at 12:31 pm | Permalink

    Perhaps a stupid way, but just reading and thinking aloud. You could have your own “image” class that’s essentially a UIScrollView with a UIImageView and just manually scroll the UIScrollView in increments the size of the image. I don’t know the exact performance effects of scrolling with a scroll view though

  22. Posted August 20, 2009 at 6:00 am | Permalink

    Great tutorial Man, i got to learn alot and got my issues cleared with the help of this tutorial. Guys i know one more iphone courses which i hv joined recently, its awesome, just wanted to share this online course with you.

    Please google Edumobile and you will find the site straightway ……

  23. MikeN
    Posted August 25, 2009 at 3:04 pm | Permalink

    Great tutorial on game sprites.
    I have some newbie questions.
    How do I draw only on sprite from the imageArray?

    great tutorial…

  24. Posted August 31, 2009 at 7:11 am | Permalink

    Great tutorial, one question.

    I would like to know how to get the little Ryu to follow touch events. Ive been stuck on this for a while.

    Ideally i want to touch the screen and have him animate once per touch.

    I have the code for moving one .png to touch events but i cant get any animations to move to touch events.

    Thank You!

    Alex

  25. Posted September 9, 2009 at 7:36 pm | Permalink

    Just a heads up that the link to your other tutorial (“Integrating twitter into your applications) is incorrect.

  26. Posted September 16, 2009 at 2:16 am | Permalink

    Very nice and well-explained tutorial..good work.

    After going through all comments, I wanted to share one thing……
    Cocos2D library for iPhone provides a mechanism for Sprite animations, you can also call any specific function at the end of animation. So I think, if you are really into game development, I would prefer go with Cocos2D, which is easy to understand and use. It will save a lot of development time.

    Thanks……Happy iPhone Coding ;)

  27. Billy
    Posted September 17, 2009 at 4:31 pm | Permalink

    Great Tutorial.

    One question, How do u determine exactly where on the screen the image “ryu” starts. Can you put him anywhere>? If so how?

    Thanks

  28. Kyle Tomson
    Posted September 22, 2009 at 11:40 pm | Permalink

    Very nice tutorial. I have one question. You say in your tutorial “For all of you “1337″ coders that are going to post in the comments telling me “Why don’t you use a for loop to load the images” (very nerdy voice):”. Well, I’m fairly new to Objective C and I can’t figure out HOW to use a for loop to load the images and have it work properly. Any hints?

    Thanks.

  29. Posted September 24, 2009 at 4:00 pm | Permalink

    I hope this new version solves the xml-rpc error. Some of us still can’t setup our blog or post with this app.

  30. JK
    Posted September 28, 2009 at 2:33 pm | Permalink

    nice tutorial. But how would you get the animating subview to move around the screen?

  31. vijay
    Posted September 29, 2009 at 12:48 am | Permalink

    Instead of animating…..how can we controll the character?

  32. vijay
    Posted October 1, 2009 at 3:29 am | Permalink

    Instead of animating…..how can we controll the character? brandon waiting for ur reply……plz reply soon…..

  33. Steve
    Posted November 6, 2009 at 8:20 pm | Permalink

    Hi,

    There doesn’t seem to be any .plist in my project. How would I go about creating it?

    Thanks!

  34. Joe
    Posted May 11, 2010 at 10:34 am | Permalink

    I notice how you added those UIImage objects to the array one by one…

    Can you please show how to add a large number of them through a loop? I’m dying to add about 100 images into an NSArray as UIImages and to animate through them (simulating a 3d model), but I can’t, for the life of me, figure out how to do that.

    I can get the list of files into an array using some filemanager methods, however these are just pointers to files (I assume), not the UIImage objects that is needed.

    • N8nnc
      Posted July 24, 2010 at 7:40 pm | Permalink

      I make no claim that this is a goo way to do this, but this works to load images into the array in a loop:

      NSMutableArray *imageArray = [[NSMutableArray alloc] init];
      for (int i=1; i<=12; i++) {
      [imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png", i]]];
      }

      Comments:
      1. This works for images named 1- (or any sequence that can be easily indexed via the loop control values. There are many ways to support more flexible indexing.
      2. The array must be mutable to allow the addition of items.
      3. Deciphering:
      [NSString stringWithFormat:@"%d.png", i] // Set string to ” .png”, for =1 to 12
      [UIImage imageNamed:[… // Init image with file named by string
      [imageArray addObject:[… // Add image to array

      • N8nnc
        Posted July 24, 2010 at 7:45 pm | Permalink

        Sorry about the (lack of) formatting – it got lost in the cut-n-paste.
        Sorry also about the “goo”!-) (should be “good”)

        Hmm – I now see other missing stuff. I had used greater-than/less-than brackets, but they got stripped (to filter HTML, I suppose). So the range of names should be 1-[N].

  35. Keyur Patel
    Posted May 22, 2010 at 9:34 pm | Permalink

    I got the animation to work, no problems. I was just curious what kind of method I could use to detect when the animation stopped. Maybe like an “if” statement. I’ve tried using a BOOL, but it’s getting called while the animation is still happening. Any help is much appreciated. Thanks

  36. Dennis
    Posted July 21, 2010 at 4:27 pm | Permalink

    Great stuff..

    Im trying to use the “isAnimating” boolean in IF statement to start a second animation one the first one has completed, but so far i cant seem to get it to work..

    Any suggestions on how to use this in a IF statement?

    thx for the replies before hand..

  37. Dennis
    Posted July 21, 2010 at 4:44 pm | Permalink

    right now i have tried mucking around with this

    if ([launchPrep isAnimating]== YES)
    {
    }
    else{
    do something
    }

    However isAnimating never seems to return the NO statement

  38. POLYGAMe
    Posted August 4, 2010 at 9:54 am | Permalink

    Wow! Thanks for these, I’m only just starting out with Objective C but this looks a whole heap of fun!

  39. Bluebaroo
    Posted August 30, 2010 at 8:33 pm | Permalink

    This is my first time animating something on the iPhone. But I cant seem to get ryu to render. I even tried copy and pasting the code into my project, but I he still doesnt appear. Does anyone have any idea what may be causing this problem?

  40. Bluebaroo
    Posted August 30, 2010 at 9:16 pm | Permalink

    After playing around with breakpoints (I have no experience with XCode), it looks like it is never getting to the ryu code. Is there something I am missing?

5 Trackbacks

  1. [...] Im icodeblog gibt es einen frischen Hilfe-Artikel für iPhone-Entwickler. Der Eintrag “Animating A Game Sprite” gibt Programmiert-Tipps bei der Erstellung animierte Spiel-Sequenzen, zeigt Code-Beispiele [...]

  2. [...] Brandon has posted a nice project here at: Animating A Game Sprite [...]

  3. [...] -> iPhone Programming Tutorial: Animating A Game Sprite [...]

  4. [...] Tutorials beschäftigt sich mit den ersten “einfachen” Spiele-Animationen. Share this on [...]

  5. [...] from:  iPhone Programming Tutorial: Animating A Game Sprite | iCodeBlog Share and [...]

Post a Comment

Your email is never published nor shared. 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> <pre lang="" line="" escaped="">