<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Metal Fish Eggs &#187; iPhone</title>
	<atom:link href="http://blog.zincroe.com/category/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zincroe.com</link>
	<description>Ramblings from the team at zinc Roe</description>
	<lastBuildDate>Fri, 23 Jul 2010 20:45:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A big hello to the App Campers</title>
		<link>http://blog.zincroe.com/2010/04/a-big-hello-to-the-app-campers/</link>
		<comments>http://blog.zincroe.com/2010/04/a-big-hello-to-the-app-campers/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 18:44:04 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Kids Media]]></category>
		<category><![CDATA[Tickle Tap Apps]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=651</guid>
		<description><![CDATA[Right about now a number of notable folks in the world of children&#8217;s technology are on their way to the <a href="http://www.childrenssoftware.com/dustormagic/">Dust or Magic AppCamp</a>. Unfortunately I wasn&#8217;t able to make the trip. But I thought I&#8217;d use this as an&#8230;]]></description>
			<content:encoded><![CDATA[<p>Right about now a number of notable folks in the world of children&#8217;s technology are on their way to the <a href="http://www.childrenssoftware.com/dustormagic/">Dust or Magic AppCamp</a>. Unfortunately I wasn&#8217;t able to make the trip. But I thought I&#8217;d use this as an excuse to share a few of the lessons learned in developing <a href="http://www.tickletapapps.com">Tickle Tap Apps</a>.</p>
<p>We ran numerous testing sessions with kids throughout the development of our apps. Many very informal with friends, family and a few strangers here and there. With the help of mom and HCI consultant Deborah Ptak who works at University of Toronto we were able to gather a lot of useful feedback on the apps. Deb organized and ran a number of testing sessions with kids aged 3 to 6. We were able to make quite a few small improvements based on these sessions. Many of these issues can be grouped into three sets:</p>
<p><strong>Unintentional triggering of the buttons.</strong> Any buttons near the edge of the screen WILL be hit by kids by accident. Repeatable. The Tickle Tap Apps use a &#8216;back&#8217; button placed in the bottom right corner of the screen (all our preschool apps are landscape). Over and over again we watched as kids accidentally hit this button as they shifted their grip on the device. As a result we moved the placement of this button to the top left corner. So keep your buttons away from the edges of the screen and especially the bottom corners of the screen. And when it comes to do QA testing make sure your app survives all ten fingers mashing madly away at once.</p>
<p><strong>Unintentional touches blocking intentional touches.</strong> Unless you make special accommodations an active touch event will block the triggering of subsequent events. In other words if you are touching the edge of the screen accidentally the app won&#8217;t respond to intentional touches. A solution is to set up your apps as multitouch and write the code in such as a way the it can accept input even if a stray finger is resting somewhere else on the screen.</p>
<p><strong>Voice-over and animation overload.</strong> This came out only after longer game-play. Once kids got the hang of a game they charged ahead and suddenly the voice-overs went from helpful to annoying and the animations from novel and rewarding to just getting in the way. So we got smart with our voice-over. We took some of it out, we made some of it play only after an inactivity time-out and made some of it only play the first time through on a new game play. And we pared back the frequency of the little animations that are peppered throughout our apps. Getting this balance right is tricky and of course it&#8217;s not an issue that is limited to mobile apps.</p>
<p>So I hope all the AppCampers enjoy the Ocean views. Building apps for kids has been a tremendous experience and I&#8217;m sure I don&#8217;t need to tell you how liberating it is to break out of the browser and ditch the mouse and keyboard. Consider this an open invite to get in touch and share your questions and insights. Tickle Tap is just the start for us!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2010/04/a-big-hello-to-the-app-campers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obscure YouTube player bugs on the iPhone</title>
		<link>http://blog.zincroe.com/2010/03/obscure-youtube-player-bugs-on-the-iphone/</link>
		<comments>http://blog.zincroe.com/2010/03/obscure-youtube-player-bugs-on-the-iphone/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 16:06:50 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Tickle Tap Apps]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=637</guid>
		<description><![CDATA[While debugging our new <a href="http://tickletapapps.com/toddlerpack">Tickle Tap Toddler Pack</a> iPhone app, I had to fix a couple of obscure bugs caused by the YouTube video on the app&#8217;s info screen. After watching the video, none of the sound effects in <a href="http://tickletapapps.com/soundshaker">Sound Shaker</a> work&#8230;]]></description>
			<content:encoded><![CDATA[<p>While debugging our new <a href="http://tickletapapps.com/toddlerpack">Tickle Tap Toddler Pack</a> iPhone app, I had to fix a couple of obscure bugs caused by the YouTube video on the app&#8217;s info screen. After watching the video, none of the sound effects in <a href="http://tickletapapps.com/soundshaker">Sound Shaker</a> work and <a href="http://tickletapapps.com/fieldflier">Field Flier</a> just displays a blank white screen&#8230; very strange. After a bunch of digging around, it turns out that the YouTube video player isn&#8217;t a very good iPhone citizen. Oh sure, it&#8217;s very friendly and triggers all of the events and callbacks you&#8217;d expect when it opens. But when it closes, it doesn&#8217;t trigger anything, leaving the app wondering what the heck is going on.</p>
<p>The YouTube player breaks Sound Shaker because the app recieves an audio interruption event (<code>kAudioSessionBeginInterruption</code>) when the YouTube player opens, but never receives a corresponding event (<code>kAudioSessionEndInterruption</code>) when the player closes. Being a good citizen, the app deactivates it&#8217;s audio session (and suspends it&#8217;s OpenAL context) when the interruption begins, but the poor little guy never gets a chance to reactivate it again. Not cool.</p>
<p>The YouTube player breaks Field Flier because it creates a new key window when it opens and sets the key window to nil when it closes. When Field Flier goes looking for the key window, it&#8217;s nowhere to be found. Oh sure, the app could listen for a <code>UIWindowDidResignKeyNotification</code> notification to reset the key window – too bad the YouTube player doesn&#8217;t trigger that particular notification. I&#8217;m pretty sure the YouTube player has it&#8217;s thumbs in it&#8217;s ears going na nana nana na at this point. Again, not cool.</p>
<p>The hacktastic solution to both issues is to listen for a <code>UIWindowDidBecomeVisibleNotification</code> notification on the app&#8217;s main window and manually call the interruption listener callback and reset the key window. I put the relevant code in the app delegate, but if your app shows and hides the main window for some other reason, you&#8217;ll probably need to get a bit fancier.</p>
<p>Here&#8217;s the relevant code in <code>TickleTapToddlerPackAppDelegate.m</code>:</p>
<pre>
void interruptionListenerCallback (void *inUserData, UInt32 interruptionState ) {
  if(interruptionState == kAudioSessionBeginInterruption) {
    AudioSessionSetActive(NO);
    // suspend OpenAL context here...
  } else if(interruptionState == kAudioSessionEndInterruption) {
    UInt32 category = kAudioSessionCategory_MediaPlayback;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &#038;category);
    AudioSessionSetActive(YES);
    // resume OpenAL context here...
  }
}

- (void) applicationDidFinishLaunching: (UIApplication*) application {
  // initialize the audio session and register the interruption listener callback
  AudioSessionInitialize(NULL, NULL, interruptionListenerCallback, self);
  UInt32 category = kAudioSessionCategory_MediaPlayback;
  AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &#038;category);
}

- (void)didReceiveWindowDidBecomeVisibleNotification:(NSNotification *)notification {
  // manually call the interruption listener callback
  interruptionListenerCallback((void *)self, kAudioSessionEndInterruption);
  // manually set the key window
  [self.window makeKeyWindow];
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2010/03/obscure-youtube-player-bugs-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Preview Pattern Painter!</title>
		<link>http://blog.zincroe.com/2009/12/preview-pattern-painter/</link>
		<comments>http://blog.zincroe.com/2009/12/preview-pattern-painter/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 16:41:01 +0000</pubDate>
		<dc:creator>Suzanne</dc:creator>
				<category><![CDATA[Tickle Tap Apps]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=581</guid>
		<description><![CDATA[<a title="Pattern Painter" href="http://www.tickletapapps.com/patternpainter" target="_blank">Pattern Painter</a>, the perfect preschool puzzler is coming soon to the iTunes App Store! This brand new <a title="Tickle Tap Apps" href="http://www.tickletapapps.com/" target="_blank">Tickle Tap App</a> is a pattern, drawing and shape game all in one and features easy-to-follow tracing animations when children need extra help, along&#8230;]]></description>
			<content:encoded><![CDATA[<p><a title="Pattern Painter" href="http://www.tickletapapps.com/patternpainter" target="_blank">Pattern Painter</a>, the perfect preschool puzzler is coming soon to the iTunes App Store! This brand new <span style="text-decoration: underline;"><a title="Tickle Tap Apps" href="http://www.tickletapapps.com/" target="_blank">Tickle Tap App</a></span> is a pattern, drawing and shape game all in one and features easy-to-follow tracing animations when children need extra help, along with comic relief by Jinja the cat, Robin the bird and Harvey the dog. Check it out:</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/zL571xrJ5Fk&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/zL571xrJ5Fk&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/12/preview-pattern-painter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tickle Tap Apps Sneak Peek</title>
		<link>http://blog.zincroe.com/2009/10/tickle-tap-apps-sneak-peek/</link>
		<comments>http://blog.zincroe.com/2009/10/tickle-tap-apps-sneak-peek/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 19:17:30 +0000</pubDate>
		<dc:creator>Suzanne</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Tickle Tap Apps]]></category>
		<category><![CDATA[Websites]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=506</guid>
		<description><![CDATA[<a href="http://www.tickletapapps.com"></a>
Why would a three-year-old want to play games on an iPhone? Actually, let’s re-think that—why wouldn’t a three-year-old want to play games on an iPhone?
iPhones and iPod Touch devices are extremely attractive to small users in the three- to&#8230;]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tickletapapps.com"><img src="http://blog.zincroe.com/wp-content/uploads/2009/10/tickletapapps_slate_small.jpg" alt="Tickle Tap Apps" title="Tickle Tap Apps" width="399" height="170" /></a></p>
<p>Why would a three-year-old want to play games on an iPhone? Actually, let’s re-think that—why wouldn’t a three-year-old want to play games on an iPhone?</p>
<p>iPhones and iPod Touch devices are extremely attractive to small users in the three- to five-year-old snack bracket. These devices are easy for small hands to use—much easier than computers, keyboards and mice. Children can also use them anywhere. Think of the possibilities: while waiting in line with you, while traveling or commuting, in the car, during quiet moments at home. Anytime your child is looking for an activity. Anytime you’d like your child to be engaged and interested instead of frustrated or bored and distracted.</p>
<p>But if you’re going to hand over your iPhone or iPod Touch to your child to play with, you’re going to need some entertaining apps for him or her to play. That’s where <a href="http://www.tickletapapps.com">Tickle Tap Apps</a> come in. Tickle Tap Apps are age-appropriate educational games that encourage learning through practice and exploration. They take full advantage of the iPhone platform in ways that make game play exciting. They’re also easy to use, with audio instructions and visual cues so preschoolers can pick them up and start playing right away.</p>
<p>The first three Tickle Tap Apps will be available very soon from the iTunes App Store. Visit <a href="http://www.tickletapapps.com">TickleTapApps.com</a> to learn more. Plus get sneak peeks at game play by watching demo videos of <a href="http://www.tickletapapps.com/soundshaker">Sound Shaker</a>, <a href="http://www.tickletapapps.com/countcaddy">Count Caddy</a> and <a href="http://www.tickletapapps.com/sortslider">Sort Slider</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/10/tickle-tap-apps-sneak-peek/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AVAudioPlayer Memory Leak</title>
		<link>http://blog.zincroe.com/2009/06/avaudioplayer-memory-leak/</link>
		<comments>http://blog.zincroe.com/2009/06/avaudioplayer-memory-leak/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 19:20:54 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=240</guid>
		<description><![CDATA[While coding the sound for Arctic Shuffle 2, I ran into a non-obvious memory (to me, anyway) memory leak related to the AVAudioPlayer that took forever to track down.
Here was my original code, which leaks if an error occurs&#8230;]]></description>
			<content:encoded><![CDATA[<p>While coding the sound for Arctic Shuffle 2, I ran into a non-obvious memory (to me, anyway) memory leak related to the AVAudioPlayer that took forever to track down.</p>
<p>Here was my original code, which leaks if an error occurs in the <code>initWithData:error:</code> method:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>AVAudioPlayer <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>audioPlayerWithContentsOfFile<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>path <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithContentsOfFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>AVAudioPlayer alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>audioData error<span style="color: #002200;">:</span><span style="color: #a61390;">NULL</span><span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>If an error occurs in the <code>initWithData:error:</code> method (say because the file is missing), it returns nil. If it returns nil, autorelease gets called on nil, not on the AVAudioPlayer object, and the AVAudioPlayer object gets leaked.</p>
<p>Here&#8217;s the leak-free version:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>AVAudioPlayer <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>audioPlayerWithContentsOfFile<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>path <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithContentsOfFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;
    AVAudioPlayer <span style="color: #002200;">*</span>player <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>AVAudioPlayer alloc<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>player initWithData<span style="color: #002200;">:</span>audioData error<span style="color: #002200;">:</span><span style="color: #a61390;">NULL</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>player autorelease<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>player release<span style="color: #002200;">&#93;</span>;
        player <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">return</span> player;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>The leak-free version stores the pointer returned by <code>alloc</code>, rather than the pointer returned by <code>initWithData:error:</code>. That way, whatever happens, the player can still be released.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/06/avaudioplayer-memory-leak/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Artifacts in small textures on the iPhone</title>
		<link>http://blog.zincroe.com/2009/05/artifacts-in-small-textures-on-the-iphone/</link>
		<comments>http://blog.zincroe.com/2009/05/artifacts-in-small-textures-on-the-iphone/#comments</comments>
		<pubDate>Thu, 14 May 2009 20:26:51 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=229</guid>
		<description><![CDATA[For the next version of Arctic Shuffle, we&#8217;re using Open GL to speed things up. One problem we&#8217;re run into along the way is strange  artifacts in textures smaller than 64 pixels by 64 pixels. After a lot of head&#8230;]]></description>
			<content:encoded><![CDATA[<p>For the next version of Arctic Shuffle, we&#8217;re using Open GL to speed things up. One problem we&#8217;re run into along the way is strange  artifacts in textures smaller than 64 pixels by 64 pixels. After a lot of head scratching, an <a href="http://forums.macrumors.com/showpost.php?p=6946122&#038;postcount=4">obscure forum post</a> saved the day. It turns out there&#8217;s a bug in Apple&#8217;s GLSprite sample code (where our texture loading code came from).</p>
<p>Here&#8217;s the important bit from our texture loading code:</p>
<pre><code>if(image = [UIImage imageWithContentsOfFile:aPath].CGImage) {
  width = CGImageGetWidth(image);
  height = CGImageGetHeight(image);
  <strong>data = (GLubyte *) malloc(width * height * 4);</strong>
  context = CGBitmapContextCreate(data, width, height, 8, width * 4, CGImageGetColorSpace(image), kCGImageAlphaPremultipliedLast);
  CGContextDrawImage(context, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), image);
  CGContextRelease(context);
  glGenTextures(1, &#038;name);
  free(data);
}</code></pre>
<p>I have literally no idea how <code>malloc</code> works, but from what I gather it doesn&#8217;t clean out the memory that it allocates. For some reason, the memory allocated for textures smaller than 64 pixels by 64 pixels has a bunch of garbage in it, which shows up as artifacts in the texture. Switching from <code>malloc</code> to <code>calloc</code>, which explicitly sets all the bits in the allocated memory to zero got rid of the problem.</p>
<p>Here&#8217;s the working code:</p>
<pre><code>if(image = [UIImage imageWithContentsOfFile:aPath].CGImage) {
  width = CGImageGetWidth(image);
  height = CGImageGetHeight(image);
  <strong>data = (GLubyte *) calloc(width * height, 4);</strong>
  context = CGBitmapContextCreate(data, width, height, 8, width * 4, CGImageGetColorSpace(image), kCGImageAlphaPremultipliedLast);
  CGContextDrawImage(context, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), image);
  CGContextRelease(context);
  glGenTextures(1, &#038;name);
  free(data);
}</code></pre>
<p>Happy texturing!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/05/artifacts-in-small-textures-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Units in Box2D</title>
		<link>http://blog.zincroe.com/2009/05/units-in-box2d/</link>
		<comments>http://blog.zincroe.com/2009/05/units-in-box2d/#comments</comments>
		<pubDate>Thu, 14 May 2009 19:50:29 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=214</guid>
		<description><![CDATA[There were some good questions during my <a href="http://blog.zincroe.com/2009/05/iphone-and-box2d">presentation last night</a> and via email this morning about units in Box2D.
<a href="http://twitter.com/jasonkrogh">@jasonkrogh</a> asked what kind of units Box2D uses. Here&#8217;s the relevant bit about units from the <a href="http://www.box2d.org/manual.html#units">Box2D manual</a>:

Box2D works with floating point&#8230;]]></description>
			<content:encoded><![CDATA[<p>There were some good questions during my <a href="http://blog.zincroe.com/2009/05/iphone-and-box2d">presentation last night</a> and via email this morning about units in Box2D.</p>
<p><a href="http://twitter.com/jasonkrogh">@jasonkrogh</a> asked what kind of units Box2D uses. Here&#8217;s the relevant bit about units from the <a href="http://www.box2d.org/manual.html#units">Box2D manual</a>:</p>
<blockquote><p>
Box2D works with floating point numbers, so some tolerances have to be used to make Box2D perform well. These tolerance have been tuned to work well with meters-kilogram-second (MKS) units. In particular, Box2D has been tuned to work well with moving objects between 0.1 and 10 meters. So this means objects between soup cans and buses in size should work well.
</p></blockquote>
<p>When you&#8217;re working with on screen objects like balls and squares, what&#8217;s important is that the units are <em>not</em> pixels.</p>
<p><a href="http://twitter.com/satefan">@satefan</a> asked:</p>
<blockquote><p>
For my little demo I set the dimensions of the world to 320 meters wide by 480 meters high. This seems to work fine and I don&#8217;t have to do any coordinate translations. Just curious&#8230; was there a reason why you decided not to do this?
</p></blockquote>
<p>The short answer: the physics won&#8217;t look right because your bodies and shapes will be much larger, heavier and faster than Box2D is expecting. Here&#8217;s what the manual has to say:</p>
<blockquote><p>
Being a 2D physics engine it is tempting to use pixels as your units. Unfortunately this will lead to a poor simulation and possibly weird behavior. An object of length 200 pixels would be seen by Box2D as the size of a 45 story building. Imagine trying to simulate the movement of a high-rise building with an engine that is tuned to simulate ragdolls and barrels. It isn&#8217;t pretty.
</p></blockquote>
<p>Let&#8217;s do the math for the the balls in the <a href="http://blog.zincroe.com/wp-content/uploads/2009/05/mygame.zip">example game</a> on the iPhone. If we set the world size to match the screen, then the world would be 320 meters across, 480 meters tall and 1 pixel on screen would equal 1 meter in Box2D. If the ball had a diameter of 64 pixels (which is does), it would have a diameter of 64 meters in the physics engine – that&#8217;s pretty small on screen, but more than six times the size of Box2D&#8217;s recommend 10 meter maximum.</p>
<p>Here&#8217;s an example of where this becomes a problem: Box2D has setting for the maximum velocity any body can have and the default value is 200 meters per second (you can see all of Box2D&#8217;s settings in <a href="http://box2d.svn.sourceforge.net/viewvc/box2d/tags/Box2D-2.0.2/Source/Common/b2Settings.h">b2Settings.h</a>). Because things are so big, they&#8217;re also very heavy (think about how much a 64 meter wide ball would weigh!). To make them move, you have to crank gravity way, way up and apply a <em>lot</em> of force. You quickly run into the limit and everything ends up moving around at the same speed (which looks terrible, trust me). Rather than fiddling with the (many) settings, the best thing to do is a simple translation between screen coordinates and world coordinates:</p>
<pre><code>// MyGameViewController.h

#define SCREEN_TO_WORLD(n) ((n) / 30)
#define WORLD_TO_SCREEN(n) ((n) * 30)
</code></pre>
<p>In the macros above, 30 is an arbitrary value. The idea is to choose a value that will convert the size of an object in pixels to a value that falls in the 0.1 meter to 10 meter sweet spot. By dividing the ball&#8217;s 64 pixel screen diameter by 30 in the <code>SCREEN_TO_WORLD</code> macro gives it a diameter of 2.13 meters in the world. What is a relatively small object on screen is now a relatively small object in the world – it also weighs less, so you can use smaller forces and don&#8217;t run into the maximum velocity limit.</p>
<p>Just make sure that any time you set any linear value (position, size, force) in the world, convert from screen coordinates to world coordinates. When you read any linear value from the world, convert from world coordinates back to screen coordinates. I like to use custom accessors to make it easier:</p>
<pre><code>// Ball.m

- (CGPoint)position {
  if([self body]) {
    return CGPointMake(
      WORLD_TO_SCREEN(body->GetPosition().x),
      WORLD_TO_SCREEN(body->GetPosition().y)
    );
  } else {
    return CGPointMake(
        WORLD_TO_SCREEN(bodyDef->position.x),
        WORLD_TO_SCREEN(bodyDef->position.y)
    );
  }
}

- (void)setPosition:(CGPoint)aPosition {
  NSAssert(![self body], @"Cannot set position");
  [self bodyDef]->position.Set(
    SCREEN_TO_WORLD(aPosition.x),
    SCREEN_TO_WORLD(aPosition.y)
  );
}
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/05/units-in-box2d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Organization and Coding Conventions for iPhone Games</title>
		<link>http://blog.zincroe.com/2009/05/project-organization-and-coding-conventions-for-iphone-games/</link>
		<comments>http://blog.zincroe.com/2009/05/project-organization-and-coding-conventions-for-iphone-games/#comments</comments>
		<pubDate>Thu, 07 May 2009 19:23:48 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=179</guid>
		<description><![CDATA[Now that we&#8217;re knee deep in iPhone game development, we&#8217;re working with a number of different outside developers. Since everyone involved is pretty new to Objective-C, XCode and iPhone development, project organization and coding conventions in our projects have been&#8230;]]></description>
			<content:encoded><![CDATA[<p>Now that we&#8217;re knee deep in iPhone game development, we&#8217;re working with a number of different outside developers. Since everyone involved is pretty new to Objective-C, XCode and iPhone development, project organization and coding conventions in our projects have been all over the map. To improve the quality of our projects and make them easier to maintain and update, here&#8217;s a list of things to keep in mind when developing casual games for the iPhone. Most of them are common sense, but going back to basics every now and then never hurts.</p>
<ul class="tutorial">
<li>Remember that somebody else (who may not know all the ins and outs of XCode) will be working on the project with you. Take the time to keep things neat and organized. Create a Classes folder with all your source code and a Resources folder with nib files, images, sounds, etc. Keep the organization of the project and the organization of the files on disk as close as possible, it&#8217;s less confusing for everyone. Give all of your files consistent descriptive names. Delete files that aren&#8217;t being used anymore (<em>Tip:</em> Make bundles for any resources that don&#8217;t need to be compiled, like images and sounds. XCode doesn&#8217;t keep track of the contents of bundle files, which means when you add/remove/rename files in the bundle XCode will automatically see the changes so you don&#8217;t have to remember to add and remove them from the project). Simple stuff, but it makes a big difference.</li>
<li>Pushing updates to the App Store is a proven way of improving a game&#8217;s visibility, so make sure the project and the code are easy to update. Remember to slow down and do things well.</li>
<li>Use Foundation and UIKit classes wherever possible — it helps keep user interface elements consistent and it&#8217;s easy for another developer to quickly see what&#8217;s going on and make changes without learning another 3rd party framework. For example, use a UIView with UIButtons for game screens. The exception to the rule here is the game engine itself, where the benefits of using OpenGL or other open source code are worth the trouble.</li>
<li>Use Interface Builder wherever possible — this goes hand-in-hand with the last point. Using UIKit classes and Interface Builder makes it easy to adjust the layout of screens, labels for buttons, etc. without hunting through the code. Remember, the person making the adjustments may not be a programmer.</li>
<li>Use UILabels for interface text, rather than embedding text in images. Keeping text out of images makes the project much easier to update and localize. Using native text for everything also helps keep things consistent visually – your high score screen is going to need dynamic text and the app will look better if it matches everything else.</li>
<li>Memory management is very high priority on the iPhone. Use as little memory as possible. Don&#8217;t load things into memory until you need them. Release things from memory when you&#8217;re done with them. For example, rather than loading all of a games screens when the app launches and keeping them in memory for the life of the app, load each screen when it&#8217;s going to be shown and release it from memory after it&#8217;s hidden.</li>
<li>Test the app regularly in Instruments during development to find memory leaks and avoid wasting memory:
<ul>
<li>Check using Leaks — This will help you find good, old-fashioned memory leaks.</li>
<li>Check using Object Allocations — An object in memory may not technically be a leak, but if it doesn&#8217;t need to be there it&#8217;s wasted memory. When you&#8217;re playing the game, are any of the objects associated with the other screens in memory? When you&#8217;re showing the game over screen, are any of the objects associated with the game engine in memory?</li>
<li>Check using Memory Monitor — Apple doesn&#8217;t specify a hard limit on the amount of memory an app can use, but the general consensus is that 15Mb to 20Mb is fairly safe. If your app is using 25Mb of memory you should be concerned. If your app is using 45Mb of memory you have a very big problem.</li>
<li>Check OpenGL Texture Memory — OpenGL on the iPhone has a soft limit of 24Mb for all textures. If you go above the limit, there&#8217;s a massive performance hit. See: <a href="http://blog.zincroe.com/2009/04/how-to-check-iphone-texture-memory-usage-with-instruments/">How To Check iPhone Texture Memory Usage With Instruments</a></li>
</ul>
</li>
<li>Follow standard Objective-C naming conventions. They&#8217;re different from other languages, so take the time to read up on them. See: <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html">Coding Guidelines for Cocoa</a>, <a href="http://www.cocoadevcentral.com/articles/000082.php">Cocoa Style for Objective-C: Part I</a>, <a href="http://www.cocoadevcentral.com/articles/000083.php">Cocoa Style for Objective-C: Part II</a></li>
<li>Put the <code>dealloc</code> method at the top of the <code>@implementation</code> block for every class you write. <code>dealloc</code> is the most important method in every class, so show it some love.</li>
<li>Use accessor methods for <strong>everything</strong> — it&#8217;s the best way to avoid simple memory management bugs. Use accessor methods within classes, too. You can define private accessor methods in a category at the top of your implementation file. You can redefine a readonly property in the public interface as a readwrite property in the private category.</li>
<li>Mark properties as <code>nonatomic</code> unless you have a good reason not to.</li>
<li>Use square bracket syntax (i.e. <code>[self foo]</code>, <code>[self setFoo:@"bar"]</code>) instead of dot syntax (i.e. <code>self.foo</code>, <code>self.foo = @"bar"</code>) for accessing properties. Using one syntax keeps your code consistent, and makes it easier to see where you&#8217;re accessing a property of an Objective-C object as opposed to a member of a C struct or C++ class (which use dot notation).</li>
<li>Avoid subclassing UIViews. Build the view hierarchy in Interface Builder and put your logic in a UIViewController. If you have a lot of UIView subclasses, you should be concerned.</li>
<li>Remember to mark properties as <code>IBOutlet</code>s and methods as <code>IBAction</code>s wherever it makes sense.</li>
<li>Organize related methods and properties into groups in the source code (i.e. the UIViewController subclass for a game screen might have groups like button properties, action methods and overridden UIViewController methods). Mark the groups in both the header and the implementation using <code>#pragma mark <em>Label</em></code>. Organize methods within a group alphabetically. You&#8217;ll spend a bit of time organizing things and a lot less time looking for things.</li>
<li>Use <code>NSAssert()</code> liberally. If you intentionally stop the app when something unexpected occurs, it&#8217;s easier to find where the problem started and fix it. It takes a bit of time to write the assertions, but I guarantee it takes less time than tracking down a bug later on.</li>
</ul>
<p>The list above is by no means definitive, but it covers the basics. Let me know if I&#8217;ve left out anything obvious, or if there&#8217;s something that rubs you the wrong way. I&#8217;m always happy to learn a better way to do something.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/05/project-organization-and-coding-conventions-for-iphone-games/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Add Box2D To An iPhone XCode Project</title>
		<link>http://blog.zincroe.com/2009/05/how-to-add-box2d-to-an-iphone-xcode-project/</link>
		<comments>http://blog.zincroe.com/2009/05/how-to-add-box2d-to-an-iphone-xcode-project/#comments</comments>
		<pubDate>Thu, 07 May 2009 15:06:39 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=153</guid>
		<description><![CDATA[Using Box2D is a great way to add physics to a 2D iPhone game. Since Box2D is written in C++ rather than Objective-C, adding it to your XCode project and getting it to build cleanly can be a bit tricky.&#8230;]]></description>
			<content:encoded><![CDATA[<p>Using Box2D is a great way to add physics to a 2D iPhone game. Since Box2D is written in C++ rather than Objective-C, adding it to your XCode project and getting it to build cleanly can be a bit tricky. If you just want to get aquainted with Box2D, there is an sample XCode project in the Box2D svn repository that includes the Box2D testbed and basic debug drawing support for the iPhone. Once you get past some quick experiments, you&#8217;ll probably want to add Box2D to a clean XCode project with a minimum of cruft. It&#8217;s not tough, but there are a couple of gotchas along the way. Below are instructions for adding Box2D to a new iPhone XCode project and getting that project to build cleanly on a device (note: the project doesn&#8217;t actually do anything, that&#8217;s where you come in&#8230;).</p>
<p>The instructions below assume you&#8217;re a registered iPhone developer and have:</p>
<ul>
<li>Mac OS X 10.5</li>
<li>XCode 3.1.2</li>
<li>iPhone SDK 2.2.1</li>
<li>Box2D 2.0.2</li>
<li>A valid app id and development provisioning profile that you can use to build the project for a device.</li>
</ul>
<p>So, for my future reference and yours&#8230;.</p>
<ol class="tutorial">
<li>Create a new XCode project. I&#8217;m creating a <em>View-Based Application</em> called <em>MyGame </em> on my desktop.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/01.png"><img class="alignnone size-medium wp-image-154" title="01" src="http://blog.zincroe.com/wp-content/uploads/2009/05/01-450x326.png" alt="01" width="450" height="326" /></a></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/02.png"><img class="alignnone size-medium wp-image-155" title="02" src="http://blog.zincroe.com/wp-content/uploads/2009/05/02-450x348.png" alt="02" width="450" height="348" /></a></p>
</li>
<li>
	  Open the terminal and export Box2D 2.0.2 from the Box2D svn repository into your project folder:<br />
	  <code>svn export https://box2d.svn.sourceforge.net/svnroot/box2d/tags/Box2D-2.0.2 ~/Desktop/MyGame/Box2D-2.0.2</code>
  </li>
<li>Right click on <em>MyGame</em> under <em>Groups &amp; Files</em> and choose <em>Add &gt; Existing Files&#8230;</em>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/04.png"><img class="alignnone size-medium wp-image-156" title="04" src="http://blog.zincroe.com/wp-content/uploads/2009/05/04-450x319.png" alt="04" width="450" height="319" /></a></p>
</li>
<li>Browse to the your project directory, select the Box2D-2.0.2 folder and click <em>Add</em>.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/05.png"><img class="alignnone size-medium wp-image-157" title="05" src="http://blog.zincroe.com/wp-content/uploads/2009/05/05-450x364.png" alt="05" width="450" height="364" /></a></p>
</li>
<li>Make sure the <em>Copy items into destination group&#8217;s folder</em> checkbox is unchecked and click <em>Add</em>.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/06.png"><img class="alignnone size-full wp-image-158" title="06" src="http://blog.zincroe.com/wp-content/uploads/2009/05/06.png" alt="06" width="400" height="374" /></a></p>
</li>
<li>Expand the <em>Box2D-2.0.2</em> group and delete everything except the <em>Include</em> and <em>Source</em> groups. Whether you move the files to the trash or just delete the references is up to you.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/07a.png"><img class="alignnone size-medium wp-image-159" title="07a" src="http://blog.zincroe.com/wp-content/uploads/2009/05/07a-450x319.png" alt="07a" width="450" height="319" /></a></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/07c.png"><img class="alignnone size-medium wp-image-161" title="07c" src="http://blog.zincroe.com/wp-content/uploads/2009/05/07c-450x319.png" alt="07c" width="450" height="319" /></a></p>
</li>
<li>Expand the <em>Source</em> group and delete the Makefile.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/08a.png"><img class="alignnone size-medium wp-image-162" title="08a" src="http://blog.zincroe.com/wp-content/uploads/2009/05/08a-450x319.png" alt="08a" width="450" height="319" /></a></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/08b.png"><img class="alignnone size-medium wp-image-163" title="08b" src="http://blog.zincroe.com/wp-content/uploads/2009/05/08b-450x319.png" alt="08b" width="450" height="319" /></a></p>
</li>
<li>If you haven&#8217;t already, set the app id (in <em>Resources/Info.plist</em>) and the <em>Code Signing Identity</em> in the project build settings (in <em>Project &gt; Edit Project Settings &gt; Build</em>). Make sure you have <em>Device 2.2.1</em> and <em>Debug</em> selected in the menu at the top left corner of XCode (anyone know what this menu is called?). Finally, build the project (<em>Command-B</em>).</li>
<li>Open up the build results (<em>Command-Shift-B</em>), and you&#8217;ll see a whole bunch of errors, along the lines of:
<p><code>error: 'finite' was not delcared in this scope</code></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/09.png"><img class="alignnone size-medium wp-image-164" title="09" src="http://blog.zincroe.com/wp-content/uploads/2009/05/09-450x250.png" alt="09" width="450" height="250" /></a></p>
</li>
<li>Open the project build settings (<em>Project &gt; Edit Project Settings &gt; Build</em>) and find the <em>Other C Flags</em> setting. Add the following flag, which tells Box2D that it&#8217;s being compiled for the iPhone so that it knows where to find the standard C++ libraries.
<p><code>-DTARGET_OS_IPHONE</code></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/10.png"><img class="alignnone size-medium wp-image-165" title="10" src="http://blog.zincroe.com/wp-content/uploads/2009/05/10-412x450.png" alt="10" width="412" height="450" /></a></p>
</li>
<li>Build the project again (<em>Command-B</em>). It will build cleanly, but we&#8217;re not quite out of the woods yet.</li>
<li>Open <em>MyGameViewController.m</em> and add the following line at the top of the file:
<p><code>#import "Box2D.h"</code></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/11.png"><img class="alignnone size-medium wp-image-166" title="11" src="http://blog.zincroe.com/wp-content/uploads/2009/05/11-450x319.png" alt="11" width="450" height="319" /></a></p>
</li>
<li>Build the project again (<em>Command-B</em>). Yay, more errors:
<p><code>error: initializer element is not constant</code></p>
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/12.png"><img class="alignnone size-medium wp-image-167" title="12" src="http://blog.zincroe.com/wp-content/uploads/2009/05/12-450x250.png" alt="12" width="450" height="250" /></a></p>
</li>
<li>Select all of the <code>.m</code> files in your project (yes, all of them).
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/13a.png"><img class="alignnone size-medium wp-image-168" title="13a" src="http://blog.zincroe.com/wp-content/uploads/2009/05/13a-450x319.png" alt="13a" width="450" height="319" /></a></p>
</li>
<li>Click the <em>Info</em> button in the toolbar, go to the <em>General</em> tab and find the <em>File Type</em> dropdown.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/13b.png"><img class="alignnone size-medium wp-image-169" title="13b" src="http://blog.zincroe.com/wp-content/uploads/2009/05/13b-412x450.png" alt="13b" width="412" height="450" /></a></p>
</li>
<li>Change the filetype from <code>sourcecode.c.objc</code> to <code>sourcecode.cpp.objcpp</code>. This tells XCode to compile the files as Objective-C++ (mixed Objective-C and C++ code) instead of plain Objective-C code.
<p class="screenshot"><a href="http://blog.zincroe.com/wp-content/uploads/2009/05/13c.png"><img class="alignnone size-medium wp-image-170" title="13c" src="http://blog.zincroe.com/wp-content/uploads/2009/05/13c-412x450.png" alt="13c" width="412" height="450" /></a></p>
</li>
<li>Build the project again (<em>Command-B</em>). That&#8217;s it!</li>
</ol>
<p>So there you go, you&#8217;re ready to start using Box2D on the iPhone. Just remember to change the file type from <code>sourcecode.c.objc</code> to <code>sourcecode.cpp.objcpp</code> for any <code>.m</code> files you add to the project.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/05/how-to-add-box2d-to-an-iphone-xcode-project/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>How to check iPhone texture memory usage with Instruments</title>
		<link>http://blog.zincroe.com/2009/04/how-to-check-iphone-texture-memory-usage-with-instruments/</link>
		<comments>http://blog.zincroe.com/2009/04/how-to-check-iphone-texture-memory-usage-with-instruments/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 15:19:16 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=124</guid>
		<description><![CDATA[
When developing iPhone games, one of the biggest performance optimizations you can make is to use OpenGL ES for rendering (instead of CoreGraphics or UIKit). For a 2D game like Arctic Shuffle, this means loading all of the animation into&#8230;]]></description>
			<content:encoded><![CDATA[<div>
<p>When developing iPhone games, one of the biggest performance optimizations you can make is to use OpenGL ES for rendering (instead of CoreGraphics or UIKit). For a 2D game like Arctic Shuffle, this means loading all of the animation into Open GL as textures, and drawing them onto simple rectangular shapes.</p>
<p>There are two caveats to this approach. First, disk access on the device is dirt slow, so you can forget about loading textures on the fly – all of the textures need to be loaded before gameplay begins. Second, OpenGL ES on the iPhone has a texture memory limit of 24MB. If you try to load more than 24MB of textures (including any buffers, like the framebuffer), the device has to start swapping them in and out of memory, and you go over a performance cliff, so to speak.</p>
<p>With that in mind, it&#8217;s very helpful to know how much texture memory is being used by your game – this is where Instruments comes in (the instructions below assume that your device is plugged into your development machine and you already have a working debug build of your game on the device).</p>
<p>1. Open Instruments (/Developer/Applications/Instruments.app) and choose the &#8220;Blank&#8221; template.</p>
<p><a href="http://blog.zincroe.com/wp-content/uploads/2009/04/step1.png"><img class="alignnone size-medium wp-image-125" style="border: 1px solid black;" title="Step 1" src="http://blog.zincroe.com/wp-content/uploads/2009/04/step1-450x329.png" alt="Step 1" width="450" height="329" /></a></p>
<p>2. In the bottom-left corner of instruments, click on the gear icon, then choose <em>Add Instrument &gt; Memory Monitory</em>. Click the gear icon again and choose <em>Add Instrument &gt; OpenGL ES</em>.</p>
<p><a href="http://blog.zincroe.com/wp-content/uploads/2009/04/step2.png"><img class="alignnone size-full wp-image-126" style="border: 1px solid black;" title="Step 2" src="http://blog.zincroe.com/wp-content/uploads/2009/04/step2.png" alt="Step 2" width="438" height="280" /></a></p>
<p>3. Click on the OpenGL ES instrument&#8217;s <em>info</em> icon, and make sure that <em>GARTResident Object Size</em> is checked.</p>
<p><a href="http://blog.zincroe.com/wp-content/uploads/2009/04/step3.png"><img class="alignnone size-medium wp-image-127" style="border: 1px solid black;" title="Step 3" src="http://blog.zincroe.com/wp-content/uploads/2009/04/step3-396x450.png" alt="Step 3" width="396" height="450" /></a></p>
<p>4. Choose the device and application you wan to check. My device is named <em>Barracuda</em> and the application is ArcticShuffle2.</p>
<p><a href="http://blog.zincroe.com/wp-content/uploads/2009/04/step4.png"><img class="alignnone size-medium wp-image-128" style="border: 1px solid black;" title="Step 4" src="http://blog.zincroe.com/wp-content/uploads/2009/04/step4-450x252.png" alt="Step 4" width="450" height="252" /></a></p>
<p>5. Click the record button. This will launch the application on the device, and start monitoring it&#8217;s memory and OpenGL ES usage. The GARTResident Object Size column shows the amout of texture memory used, in bytes. Divide that by 1024 (i.e. amount / 1024 / 1024) to convert the number to megabytes. Notice how the <em>Frames Per Second</em> drops dramatically while the textures are loading.</p>
<p><a href="http://blog.zincroe.com/wp-content/uploads/2009/04/step5.png"><img class="alignnone size-medium wp-image-129" style="border: 1px solid black;" title="Step 5" src="http://blog.zincroe.com/wp-content/uploads/2009/04/step5-421x450.png" alt="Step 5" width="421" height="450" /></a></p>
<p>Happy Optimizing!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/04/how-to-check-iphone-texture-memory-usage-with-instruments/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
