<?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; Luke</title>
	<atom:link href="http://blog.zincroe.com/author/luke/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>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>Books, Music and TV for Preschoolers</title>
		<link>http://blog.zincroe.com/2009/08/books-music-and-tv-for-preschoolers/</link>
		<comments>http://blog.zincroe.com/2009/08/books-music-and-tv-for-preschoolers/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 21:29:28 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Show and Tell]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=418</guid>
		<description><![CDATA[Most content made for preschoolers is awful. Harsh? Maybe, but when your little monster wants to read a book, listen to a song, or watch a show on repeat, you have plenty of opportunity to notice. As a parent, finding&#8230;]]></description>
			<content:encoded><![CDATA[<p>Most content made for preschoolers is awful. Harsh? Maybe, but when your little monster wants to read a book, listen to a song, or watch a show on repeat, you have plenty of opportunity to notice. As a parent, finding a gem that&#8217;s rich, well-crafted and can make you laugh (even on repeat) can make your day. And week. And Month.</p>
<p>Since my son Owen was born a year and a half ago, only a handful of great books and tv shows plus a CD or two have become things we love and come back to again and again. So, without further ado, a few of my (and Owen&#8217;s) favourite preschool things.</p>
<h3>TV Shows</h3>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/3hlkRcTmFxY&#038;hl=en&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/3hlkRcTmFxY&#038;hl=en&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>Sid The Science Kid</strong></p>
<p><em>What I love about this show:</em> The characters have lots of depth and the voice actors do a great job of bringing them to life. The humour and attention to detail make it genuinely enjoyable to watch, the science is fun and accessible and finds the fine line between educational content and something kids would actually choose to watch.</p>
<p><em>Where to find it:</em>The show airs on TVO (in Ontario) and on PBS Kids in the US. It&#8217;s also available <a href="http://www.amazon.com/Sid-Science-Kid-Change-Happens/dp/B001NLJ3R6">on DVD from Amazon</a>.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/EcrLJGT6ZVU&#038;hl=en&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/EcrLJGT6ZVU&#038;hl=en&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>Word World</strong></p>
<p><em>What I love about this show:</em> The character designs are brilliant – seriously, how do they make <em>everything</em> out of letters?! Learning about words and reading is worked into the plot in a really, really clever way – in my favourite episode, everyone&#8217;s afraid of a Shark, except Duck, because he mis-pronounces it as Sa-Hark.</p>
<p><em>Where to find it:</em> The show airs on TVO (in Ontario) and on PBS Kids in the US. It&#8217;s also available <a href="http://www.amazon.com/WordWorld-Welcome-Word-World/dp/B000S5NV5S/ref=pd_bxgy_d_text_b">on DVD from Amazon</a>.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/CH5Ykpt9sqA&#038;hl=en&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/CH5Ykpt9sqA&#038;hl=en&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>Pocoyo</strong></p>
<p><em>What I love about this show:</em> The simple character designs and plain white backdrop let you focus on the wonderfully detailed movement and sound – every nod, jump and step has a sound that helps tell the story – which is great for kids who haven&#8217;t got words yet. Also, I wish Stephen Fry (the show&#8217;s narrator) would read <em>me</em> bedtime stories and this is as close as I&#8217;ll ever get.</p>
<p><em>Where to find it:</em> Pocoyo airs on Treehouse (in Canada) and is available <a href="http://www.amazon.com/Pocoyo-Meet/dp/B000UZDO76">on DVD from Amazon</a>.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/cBnOCG_7mmU&#038;hl=en&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/cBnOCG_7mmU&#038;hl=en&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>Kids&#8217; CBC Friends</strong></p>
<p><em>What I love about this show:</em> It&#8217;s Canadian content that isn&#8217;t lame! Mama Yamma&#8217;s kitchen in Kensington Market feels a bit like the best parts of Sesame Street, the characters are well-written and funny (my personal favourite is the Breakfast Froog&#8217;s non-sequitur ribbit) and the hosts aren&#8217;t over the top. The Youtube video above really doesn&#8217;t do the show justice – Kids&#8217; CBC, get with the times and make your content easy to find, embed and link to!</p>
<p><em>Where to find it:</em> Kids&#8217; CBC Friends isn&#8217;t a show, per-se, but short segments that get played between shows (instead of commercials). Kids&#8217; CBC Friends airs on CBC in Canada (there&#8217;s more info on the <a href="<br />
http://www.cbc.ca/kidscbc/#/friends/">Kids&#8217; CBC website</a>).</p>
<h3>Music</h3>
<p><a href="http://www.amazon.com/Longs-Lullabies-Curious-George-Johnson/dp/B000CR7RDE"><img src="http://www.covershare.com/album/2116_1227466858.jpg" alt="Sing-A-Longs &#038; Lullabies for the Film Curious George" /></a></p>
<p>The only music that&#8217;s become a staple in our house is <a href="http://www.amazon.com/Longs-Lullabies-Curious-George-Johnson/dp/B000CR7RDE">Sing-A-Longs &#038; Lullabies for the Film Curious George</a> by Jack Johnson. The album has a good mix of accoustic songs and fun bluesy stuff (like the adaptation of Three Is A Magic Number about the three R&#8217;s). The lyrics are geared towards kids without being eye-gougingly repetitive, so listening on repeat is no problem.</p>
<h3>Books</h3>
<p><a href="http://www.amazon.com/Amazing-Machines-Truckload-Tony-Mitton/dp/0753461544/ref=pd_cp_b_1"><img src="http://media.us.macmillan.com/jackets/500H/9780753461549.jpg" alt="The Amazing Machines Truckload of Fun" /></a></p>
<p><strong>The Amazing Machines Truckload of Fun</strong><br />
by Tony Mitton and Ant Parker</p>
<p><em>What I love about these books:</em> The words-to-pictures ratio is just about perfect – one or two short sentences per page – which means you can read everything before flipping the page! The text on each page reads like a poem and is fun to read just for the rhythm and the way it rolls off your tongue. If I had to pick just one, I&#8217;d have to go with <a href="http://www.amazon.com/Dazzling-Diggers-Amazing-Machines-Parker/dp/0753451050/ref=ed_oe_h">Dazzling Diggers</a>.</p>
<p><a href="http://www.amazon.com/Haiku-Baby-Betsy-E-Snyder/dp/0375843957"><img src="http://4.bp.blogspot.com/_Ng2-Z-qJzcw/SDyHPI21WSI/AAAAAAAAAOc/5vUSvP0BaWc/s400/HB_COVER_BETSYSNYDER.jpg" alt="Haiku Baby" /></a></p>
<p><strong>Haiku Baby</strong><br />
by Betsy E. Snyder</p>
<p><em>What I love about this book:</em> The beautiful illustrations and pretty little poems are fun to read over and over. Hands down our most-read book.</p>
<p><a href="http://www.amazon.com/Board-Books-Leslie-Patricelli-board/dp/0763641588/ref=sr_1_3?ie=UTF8&#038;s=books&#038;qid=1248723579&#038;sr=8-3"><img src="http://ecx.images-amazon.com/images/I/51a3pKCAl2L._SS400_.jpg" alt="Yes Yes! A Box of Board Books" /></a></p>
<p><strong>Yes Yes! A Box of Board Books</strong><br />
by Leslie Patricelli</p>
<p><em>What I love about these books:</em> The text on each page is so simple, it means you get to make up a story to go along with the illustration (umm&#8230; no, no hitting other kids with hammers?). Simple illustrations on plain backgrounds keep the distractions to a minimum. It&#8217;s a toss-up between <em>No No, Yes Yes</em> and <em>Yummuy Yucky</em> for which one gets read the most.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/08/books-music-and-tv-for-preschoolers/feed/</wfw:commentRss>
		<slash:comments>2</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>iPhone and Box2D</title>
		<link>http://blog.zincroe.com/2009/05/iphone-and-box2d/</link>
		<comments>http://blog.zincroe.com/2009/05/iphone-and-box2d/#comments</comments>
		<pubDate>Wed, 13 May 2009 20:11:25 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=200</guid>
		<description><![CDATA[For the next version of Arctic Shuffle, we&#8217;re using an open source 2D physics engine called <a href="http://www.box2d.org">Box2D</a> to improve the gameplay. There seems to be a lot of interest in Box2D for the iPhone, but I haven&#8217;t found a great overview&#8230;]]></description>
			<content:encoded><![CDATA[<p>For the next version of Arctic Shuffle, we&#8217;re using an open source 2D physics engine called <a href="http://www.box2d.org">Box2D</a> to improve the gameplay. There seems to be a lot of interest in Box2D for the iPhone, but I haven&#8217;t found a great overview anywhere, so I&#8217;ve put together a presentation for tonight&#8217;s  Toronto <a href="http://www.streamingcolour.com/blog/2009/04/20/next-toronto-iphone-meetup-may-13th">iPhone Developer Meetup</a>. </p>
<p>Here are the slides and the source code for the <a href='http://blog.zincroe.com/wp-content/uploads/2009/05/mygame_h264.mov'>example game</a> I&#8217;ll be using in the presentation. I&#8217;ve included two versions of the slides, a short version that I&#8217;ll be using tonight, and a longer version that covers collision detection and using the accelerometer. The source code includes everything described in the longer version.</p>
<ul>
<li><a href='http://blog.zincroe.com/wp-content/uploads/2009/05/iphoneandbox2d.pdf'>Slides (Long Version)</a></li>
<li><a href='http://blog.zincroe.com/wp-content/uploads/2009/05/iphoneandbox2dshort.pdf'>Slides (Short Version)</a></li>
<li><a href='http://blog.zincroe.com/wp-content/uploads/2009/05/mygame.zip'>Example Game Source Code</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/05/iphone-and-box2d/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
<enclosure url="http://blog.zincroe.com/wp-content/uploads/2009/05/mygame_h264.mov" length="583470" type="video/quicktime" />
		</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>
		<item>
		<title>ConnectToSharedDrive.app</title>
		<link>http://blog.zincroe.com/2009/02/connecttoshareddriveapp/</link>
		<comments>http://blog.zincroe.com/2009/02/connecttoshareddriveapp/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 20:23:06 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://blog.zincroe.com/?p=67</guid>
		<description><![CDATA[Here in the office, we use a network drive (called Betsy) to store all of our files. Because I&#8217;m too lazy to manually connect to Betsy drive each time I turn on my computer, I use a little AppleScript to&#8230;]]></description>
			<content:encoded><![CDATA[<p>Here in the office, we use a network drive (called Betsy) to store all of our files. Because I&#8217;m too lazy to manually connect to Betsy drive each time I turn on my computer, I use a little AppleScript to do it for me (ip address changed to protect the innocent):</p>

<div class="wp_syntax"><div class="code"><pre class="applescript" style="font-family:monospace;"><span style="color: #ff0033; font-weight: bold;">tell</span> <span style="color: #0066ff;">application</span> <span style="color: #009900;">&quot;Finder&quot;</span>
	<span style="color: #ff0033; font-weight: bold;">if</span> <span style="color: #ff0033;">not</span> <span style="color: #000000;">&#40;</span><span style="color: #0066ff;">exists</span> <span style="color: #0066ff;">disk</span> <span style="color: #009900;">&quot;betsy&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #ff0033; font-weight: bold;">then</span>
		mount volume <span style="color: #009900;">&quot;afp://luke@127.0.0.1/betsy&quot;</span>
	<span style="color: #ff0033; font-weight: bold;">end</span> <span style="color: #ff0033; font-weight: bold;">if</span>
<span style="color: #ff0033; font-weight: bold;">end</span> <span style="color: #ff0033; font-weight: bold;">tell</span></pre></div></div>

<p>Here&#8217;s how to do it&#8230;</p>
<p>Paste the above AppleScript code into the Script Editor (<em>/Applications/AppleScript/Script Editor.app</em>), then chose <em>File > Save As&#8230;</em> and save it as <em>ConnectToBetsy.app</em>. Make sure to choose <em>Application</em> instead of <em>Script</em> as the file format.</p>
<p><img src="http://play.zincroe.com/luke/betsy/ConnectToBetsy.gif" alt="Screenshot of Save As... settings in Script Editor." /></p>
<p>Then, add <em>ConnectToBetsy.app</em> to your login items.  Open <em>System Preferences > Accounts</em>, select your account and choose the <em>Login Items</em> tab. Click the <em>+</em> icon at the bottom to add a new login item, and browse to <em>ConnectToBetsy.app</em>.</p>
<p><img src="http://play.zincroe.com/luke/betsy/LoginItems.gif" alt="Screenshot of Login Items after adding ConnectToBetsy.app" /></p>
<p>That&#8217;s it, you&#8217;re done! The next time you start up your computer, it will automatically connect to the network drive (It&#8217;ll ask you for your password the first time. Just make sure to check the <em>Remember my password</em> checkbox so it won&#8217;t ask you every time). If the network drive ever gets disconnected, you can just double click <em>ConnectToBetsy.app</em> and presto, you&#8217;re reconnected.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zincroe.com/2009/02/connecttoshareddriveapp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
