<?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>Fancy Rat Studios</title>
	<atom:link href="http://fancyratstudios.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fancyratstudios.com</link>
	<description>A Fancy Rat Blog</description>
	<lastBuildDate>Mon, 15 Mar 2010 21:34:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Fun with cocosDenshion and Audio Metering [Update]</title>
		<link>http://fancyratstudios.com/2010/02/programming/cocos2d/fun-with-cocosdenshion-and-audio-metering/</link>
		<comments>http://fancyratstudios.com/2010/02/programming/cocos2d/fun-with-cocosdenshion-and-audio-metering/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 05:15:50 +0000</pubDate>
		<dc:creator>Lam</dc:creator>
				<category><![CDATA[cocos2d]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=242</guid>
		<description><![CDATA[For those of you that have gotten a chance to use CocosDenshion, it is the sound engine written by Steve Oldmeadow. It&#8217;s great since loading audio effects and music for us was quite a task beforehand. Here&#8217;s a little demo of what we are going to make in this article shown running on the iPhone [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you that have gotten a chance to use <strong>CocosDenshion</strong>, it is the sound engine written by Steve Oldmeadow.<br />
It&#8217;s great since loading audio effects and music for us was quite a task beforehand.</p>
<p>Here&#8217;s a little demo of what we are going to make in this article shown running on the iPhone simulator.</p>
<div class="video-embedded">
<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/GgORVtsyEuU&#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/GgORVtsyEuU&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>
</div>
<p>Well today what we&#8217;ll look at is the <strong>CDAudioManager</strong> class of the <strong>CocosDenshion</strong> package itself and see if we can produce some neat effects to spice up our games.<br />
<span id="more-242"></span></p>
<p>Let&#8217;s understand <strong>CDAudioManager</strong> a bit by looking at the comments in the source.<br />
</p>
<pre style="background:white;">
/** CDAudioManager is a wrapper around AVAudioPlayer.
 CDAudioManager is basically a thin wrapper around an AVAudioPlayer object used for playing
 background music and a CDSoundEngine object used for playing sound effects. It manages the
 audio session for you deals with audio session interruption. It is fairly low level and it
 is expected you have some understanding of the underlying technologies. For example, for
 many use cases regarding background music it is expected you will work directly with the
 backgroundMusic AVAudioPlayer which is exposed as a property.

 Requirements:
 - Firmware: OS 2.2 or greater
 - Files: CDAudioManager.*, CocosDenshion.*
 - Frameworks: OpenAL, AudioToolbox, AVFoundation
 @since v0.8
 */
</pre>
<p>Since it&#8217;s a wrapper around <strong>AVAudioPlayer</strong> we have some functionality for obtaining data that you can use for playback-level metering.</p>
<p>The methods to use for level metering are:</p>
<ul>
<li>the <em>meteringEnabled</em>  property</li>
<li>-(void)updateMeters</li>
<li>-(float)averagePowerForChannel:(NSUInteger)channelNumber</li>
<li>-(float)peakPowerForChannel:(NSUInteger)channelNumber</li>
</ul>
<p>Since we&#8217;re just quickly setting up some background audio, let&#8217;s do this as simple as possible by using <strong>SimpleAudioEngine</strong>.</p>
<h2>Accessing CDAudioManager</h2>
<p><strong>SimpleAudioEngine</strong> (as of this post) won&#8217;t give us direct access to the audio manager for our background music so let&#8217;s quickly add a get method to return the audio manager.</p>
<h3>SimpleAudioEngine.m</h3>
<pre class="brush: objc; title: ;">
-(CDAudioManager*)audioManager
{
	return am;
}
</pre>
<p><em>Update: The alternative for accessing is through the sharedInstance of audio manager and I&#8217;ve now reworked the code to use that instead. So now you don&#8217;t need to modify SimpleAudioEngine anymore.</em></p>
<p>We needed access to CDAudioManager so we can get access to AVAudioPlayer to access metering methods. We do this below:</p>
<p><em>Updated for performance by weak referencing the <strong>AVAudioPlayer</strong> instance into a class variable.</em></p>
<pre class="brush: objc; title: ;">
audioPlayer_ = [[SimpleAudioEngine sharedEngine] audioManager].backgroundMusic;
audioPlayer_.meteringEnabled = YES;
</pre>
<p>Well we have enabled metering but what we now need to do is call <em>updateMeters</em> every time we need<br />
to get meter level values. Cocos2D has functionality for scheduling timers so we set that up and call <em>updateMeters</em>.</p>
<pre class="brush: objc; title: ;">
-(void)tick:(ccTime) dt
{
	[audioPlayer_ updateMeters];
}
</pre>
<p>While still in the loop where we update our meter, we can now get values for the average and peak power of our background music.</p>
<pre class="brush: objc; title: ;">
-(void)tick:(ccTime) dt
{
	[audioPlayer_ updateMeters];
	double peakPowerForChannel = 0.f, avgPowerForChannel = 0.f;

	for(ushort i = 0; i &amp;lt; audioPlayer_.numberOfChannels; ++i){
		//	convert the -160 to 0 dB to [0..1] range
		peakPowerForChannel = pow(10, (0.05 * [audioPlayer_ peakPowerForChannel:i]));
		avgPowerForChannel = pow(10, (0.05 * [audioPlayer_ averagePowerForChannel:i]));

		filteredPeak_[i] = filterSmooth_ * peakPowerForChannel + (1.0 - filterSmooth_) * filteredPeak_[i];
		filteredAverage_[i] = filterSmooth_ * avgPowerForChannel + (1.0 - filterSmooth_) * filteredAverage_[i];
	}
}
</pre>
<p>What I&#8217;ve done is set all this up in the class <strong>AudioVisualization</strong> which will handle all the background audio metering for you. You access the class through the <em>sharedAV</em> method which returns a shared singleton instance.</p>
<p>All you need to do is add your delegate with the method:</p>
<pre class="brush: objc; title: ;">
-(void)addDelegate:(id&amp;lt;AudioVisualizationProtocol&amp;gt;)delegate forChannel:(ushort)channel;
</pre>
<p>The forChannel argument specifies the channel you want to meter for your background music. If it is mono then just set it to 0.</p>
<p>Now you just need to implement one of the <em>AudioVisualizationProtocol</em>&#8216;s to receive level values for your delegate.</p>
<pre class="brush: objc; title: ;">
-(void)avAvgPowerLevelDidChange:(float)level channel:(ushort)aChannel;
</pre>
<p><a href="http://fancyratstudios.com/wp-content/uploads/2010/02/MeterLevelDemoScreen.jpg"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/MeterLevelDemoScreen.jpg" alt="" title="MeterLevelDemoScreen" width="317" height="479" class="aligncenter size-full wp-image-264" /></a></p>
<p>That&#8217;s pretty much it! Hope you find this as cool as I did when I figured it out.</p>
<p>Just download the example demo file below to try it out.</p>
<div class="clearfix download-wrapper">
<a href="http://dl.dropbox.com/u/271717/DenshionAudioVisualDemo.zip"><span class="xcode-download-icon" style="vertical-align:text-top;"></span></a><br />
<a class="download" href="http://dl.dropbox.com/u/271717/DenshionAudioVisualDemo.zip">Download the XCode Demo</a>
</div>
<p>This demo uses the fast, easy and open source cocos2d framework.<br />
CocosDenshion is the sound engine for the cocos2d framework if you didn&#8217;t know that from reading this whole post =/.<br />
<a href="http://www.cocos2d-iphone.org/"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/official-cocos-logo-landscape-happy-300x89.png" alt="" title="cocos2d" width="300" height="89" class="alignnone size-medium wp-image-195" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/02/programming/cocos2d/fun-with-cocosdenshion-and-audio-metering/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>on silhouettes</title>
		<link>http://fancyratstudios.com/2010/02/games/on-silhouettes/</link>
		<comments>http://fancyratstudios.com/2010/02/games/on-silhouettes/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 21:48:44 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[On Silhouettes]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=236</guid>
		<description><![CDATA[on silhouettes is Fancy Rat Studios first puzzle game on the market. This extremely simple game will be sure to cause some head scratching as you play through 320 levels in 5 different modes of play. The on silhouettes games page hasn&#8217;t yet been created but you can get the game on iTunes right now. [...]]]></description>
			<content:encoded><![CDATA[<p>on silhouettes is Fancy Rat Studios first puzzle game on the market.  This extremely simple game will be sure to cause some head scratching as you play through 320 levels in 5 different modes of play.  The on silhouettes games page hasn&#8217;t yet been created but you can get the game on iTunes right now.<br />
<a class="app-store-99" href="http://itunes.apple.com/us/app/on-silhouettes/id352805744?mt=8&#038;uo=6"><span class="no-display">Get it for only $0.99</span></a><br />
How do you play on silhouettes? Simple, just identify and name the hidden silhouette in each level, it&#8217;s not as easy as it sounds though.</p>
<div class="video-embedded">
<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/Io7bSa7NHRY&#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/Io7bSa7NHRY&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>
</div>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/02/games/on-silhouettes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Memory Management in Objective-C</title>
		<link>http://fancyratstudios.com/2010/02/programming/memory-management-in-objective-c/</link>
		<comments>http://fancyratstudios.com/2010/02/programming/memory-management-in-objective-c/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 18:30:56 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Objective C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[alloc]]></category>
		<category><![CDATA[dealloc]]></category>
		<category><![CDATA[memory management]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=211</guid>
		<description><![CDATA[Looking at memory management in Objective-C for the first time can be a little bit strange whether you have programming experience or not. Some memory seems to be auto-magically handled for you; other times you need to comb through code looking for allocations and releases. I&#8217;ll attempt in this tutorial to concisely go over key [...]]]></description>
			<content:encoded><![CDATA[<p>Looking at memory management in Objective-C for the first time can be a little bit strange whether you have programming experience or not.  Some memory seems to be auto-magically handled for you; other times you need to comb through code looking for allocations and releases.  I&#8217;ll attempt in this tutorial to concisely go over key starting points in memory management and focus on the Objective-C beginner.  One major thing I will leave out or gloss over is retain count for this tutorial, I find it&#8217;s much easier to begin without thinking about retain count and just following some more general rules.  Make sure you do eventually learn about retain count though as it can be important in programming and debugging.  Let&#8217;s get started!<br />
<span id="more-211"></span></p>
<h2>Creating, Initializing, Allocating</h2>
<p>The first major thing that jumps out to those new to Obj-C is the little plus (+) or minus (-) sign sitting in front of methods. I&#8217;ll make use of the NSNumber class throughout this tutorial since it&#8217;s simple and it can also be useful in real programming.<br />
If you look into the Apple documentation for NSNumber you&#8217;ll find both &#8220;Creating an NSNumber Object&#8221; and &#8220;Initializing an NSNumber Object&#8221;. What the heck is the difference there?  Take a look!</p>
<pre class="brush: objc; title: ;">
// These would be found as part of the interface of NSNumber
// Creating an NSNumber
+ (NSNumber *)numberWithInt:(int)value;

// Initializing an NSNumber
- (id)initWithInt:(int)value;
</pre>
<p>Hmmmm, there isn&#8217;t much difference there but those little (+/-) are very important.  First off a little bit of terminology, those methods starting with the (+) are called class methods and the ones with (-) are called instance methods.  In simple terms this means you need to have an instance of a class to be able to use the (-) instance methods.  This means that to use those initialization instance methods we have to first allocate our class.  It&#8217;s easiest to see if we look at an example.</p>
<pre class="brush: objc; title: ;">
// Use a class method to get a new NSNumber
// Using
//	+ (NSNumber *)numberWithInt:(int)value;
NSNumber *newNumber = [NSNumber numberWithInt:5];

// Calling an instance method on our new number
NSLog(@&quot;%d&quot;, [newNumber intValue]);

// Allocating and initialization of NSNumber
// Using
//	- (id)initWithInt:(int)value;
NSNumber *newAllocedInitNumber = [[NSNumber alloc] initWithInt:5]];

// Calling an instance method on our other new number
NSLog(@&quot;%d&quot;, [newAllocedInitNumber intValue]);
</pre>
<p>So we can see the difference in use here, but initially it looks like we get the same usage for both of our new numbers, the NSLog calls in both cases will print out a &#8220;5&#8243;.  So why should we care about all of this?  If this was all the code we have then our program would have a memory leak! Despicable! A memory leak in such a simple little piece of code.  That [NSNumber alloc] call is the issue here, this means that our newAllocedInitNumber is being retained; it will hang around forever. We can look at a quick fix for this and hopefully it should make a little more sense.  There&#8217;s also some nuances about our newNumber object but we&#8217;ll go over that in a little bit.</p>
<pre class="brush: objc; title: ;">
// Allocating and initialization of NSNumber
// Using
//	- (id)initWithInt:(int)value;
NSNumber *newAllocedInitNumber = [[NSNumber alloc] initWithInt:5]];

// Calling an instance method on our other new number
NSLog(@&quot;%d&quot;, [newAllocedInitNumber intValue]);

// All done with our new number, lets smash that memory leak
[newAllocedInitNumber release];
</pre>
<p>Fixed! In this case it&#8217;s really just that simple and gives us a great general rule to follow. If you alloc you must release. Make sure you&#8217;ve always got that one in the back of your brain. If you alloc you must release.  </p>
<p>Now let&#8217;s get back to the newNumber object and see what&#8217;s happening there.  There&#8217;s no memory leak for this guy. In fact there&#8217;s nothing wrong with it at all, so what is there to talk about? Autorelease.  When you create an object in this way it will be automatically released for you.  Sounds great; and it is!  For the beginner and for a lot of programs that&#8217;s all you need to know and you won&#8217;t really need to worry about manually managing your memory.  Nothing in life is free though and the same is true for auto release.  You must remember that you can&#8217;t be sure about how long any auto released object will hang around for so it might possibly sit around for awhile taking up memory before it gets released.  If you&#8217;re writing a game or some other memory intensive program this may matter to you.</p>
<h2>Dealloc to the Rescue!</h2>
<p>Now that we understand a little bit about how our memory is or isn&#8217;t being managed we can look at an another important example that you&#8217;ll be sure to come across.  You want to make a spiffy new class that holds onto an NSNumber so you can do fancy things with it at a later time.  What does that look like?  Maybe something like this.</p>
<pre class="brush: objc; title: ;">
// Declare our spiffy new class
@interface SpiffyClass : NSObject {
	NSNumber *fancyNumber_;
}
@end

// Implement our spiffy new class
@implementation SpiffyClass
- (id) init {
	// A little bit of initialization, this is generally how most of your init methods will start
	if ((self=[super init])) {
		fancyNumber_ = [[NSNumber alloc] initWithInt:111];
	}
	return self;
}

// Doing fancy things with a fancy number
- (void)fancyPants {
	NSLog(@&quot;Fancy %d pants&quot;, [fancyNumber_ intValue]);
}
@end
</pre>
<p>Alright, we have a sparkly new SpiffyClass declaration with our fancyNumber_ object and a call to our fancyPants method will result in the logged message &#8220;Fancy 111 pants&#8221;.  Everything looks fine and dandy here, let&#8217;s move on. Wait! Another memory leak is lurking here.  We were so close!  Remember our little rule, if you alloc you must release.  We&#8217;re missing our release. Let&#8217;s try again.</p>
<pre class="brush: objc; title: ;">
// . . . interface is the same

// Implement our spiffy new class
@implementation SpiffyClass
- (id) init {
	// A little bit of initialization, this is generally how most of your init methods will start
	if ((self=[super init])) {
		fancyNumber_ = [[NSNumber alloc] initWithInt:111];
	}
	return self;
}

// Doing fancy things with a fancy number
- (void)fancyPants {
	NSLog(@&quot;Fancy %d pants&quot;, [fancyNumber_ intValue]);

	// We must remember, if we alloc then we release
	[fancyNumber_ release];
}
@end
</pre>
<p>Hmmm. Not too bad, we remembered our rule. Let&#8217;s try printing our fancy pants message 2 times.  Crash, burn, blech!  What happened?  Trying to call fancyPants more than once will try to release the fancyNumber_ object more than once.  Since it&#8217;s already been released and it was only allocated once this can cause some problems. (This would be a good point to look up retain count, but I won&#8217;t go over it here).  How then do we know when to release our fancyNumber_ object?  We probably want to hold onto fancyNumber_ until SpiffyClass dies.</p>
<pre class="brush: objc; title: ;">
// . . . interface is the same
// . . . init is the same

// Ahhhh, I'm dying!
- (void)dealloc {
	[fancyNumber_ release];

	// You'll pretty much always need this
	[super dealloc];
}

// Doing fancy things with a fancy number
- (void)fancyPants {
	NSLog(@&quot;Fancy %d pants&quot;, [fancyNumber_ intValue]);
}
@end
</pre>
<p>Adding the dealloc method is what we need here.  dealloc is called automatically whenever an instance of an object gets released.  No more memory leaks, no more crashing. Fantastic!</p>
<p>Hopefully this little beginner tutorial is helpful to get you started on the road to understanding memory management in Objective-C.  Pages and pages could be written about memory management and some key topics that I skipped over include, retain count, what is super dealloc, and more about auto release and auto release pools.  In the future we&#8217;ll be covering more of these topics in depth and piece-meal so check back often.</p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/02/programming/memory-management-in-objective-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ProgressTimer for cocos2d</title>
		<link>http://fancyratstudios.com/2010/02/programming/progresstimer-for-cocos2d/</link>
		<comments>http://fancyratstudios.com/2010/02/programming/progresstimer-for-cocos2d/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 23:49:45 +0000</pubDate>
		<dc:creator>Lam</dc:creator>
				<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bar]]></category>
		<category><![CDATA[indicator]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[progress]]></category>
		<category><![CDATA[radial]]></category>
		<category><![CDATA[timer]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=126</guid>
		<description><![CDATA[Every Monday, Wednesday and Friday I will put my thoughts on game design concepts and ideas into words so for today let&#8217;s focus on a topic that I hope many games will use. A Loading indicator! The problem at hand Sometimes we will need to process data or have an in-game wait or delay. We [...]]]></description>
			<content:encoded><![CDATA[<p>Every Monday, Wednesday and Friday I will put my thoughts on game design concepts and ideas into words so for today let&#8217;s focus on a topic that I hope many games will use. A Loading indicator!</p>
<h2>The problem at hand</h2>
<p>Sometimes we will need to process data or have an in-game wait or delay. We can&#8217;t let users wait without any visual indication so generally we&#8217;ll implement a loading progress image. This simple concept is shown below.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/progress-timer-1.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/progress-timer-1.png" alt="" title="progress-timer-1" width="271" height="64" class="alignnone size-full wp-image-135" /></a><br />
If that&#8217;s what you are also aiming to do then read ahead!<br />
<span id="more-126"></span></p>
<h2>Discovery</h2>
<p>We want a solution that can work for any image type and is setup for cocos2d-iphone. A really neat idea is that we can map triangles using opengl to show certain portions of the image.</p>
<p>We see that for the mapping to work, we&#8217;ll use:</p>
<ol>
<li>the midpoint vertex (vertex 0)</li>
<li>the 12 o&#8217;clock vertex (vertex 1)</li>
<li>each corner edge up-to, (vertex 2-5)</li>
<li>the point created from the progress percentage (vertex 6)</li>
</ol>
<p><a href="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png" alt="" title="texture-mapping-triangles" width="209" height="231" class="alignnone size-full wp-image-181" /></a><br />
Not too hard when we really get down to solving it.</p>
<h2>Let&#8217;s implement the thing</h2>
<p>First we setup a <strong>ProgressTimer</strong> class that inherits a <strong>CCNode</strong> so we can add it to the engine.<br />
<strong>ProgressTimer</strong>, at it&#8217;s core, will hold the percentage value, a texture, and the vertex data so we can render the object in opengl. (Note that the sample below has more because I&#8217;ve implemented the option to change its opacity and color. I&#8217;ve also added different progress timer types.)</p>
<h3>ProgressTimer.h</h3>
<pre class="brush: objc; title: ;">
typedef enum {
	kProgressTimerTypeRadialCCW,
	kProgressTimerTypeRadialCW,
	kProgressTimerTypeHorizontalBarLR,
	kProgressTimerTypeHorizontalBarRL,
	kProgressTimerTypeVerticalBarBT,
	kProgressTimerTypeVerticalBarTB,
} ProgressTimerType;

@interface ProgressTimer : CCNode {
	ProgressTimerType	type_;
	float				percentage_;
	CCTexture2D			*texture_;

	int					vertexDataCount_;
	ccV2F_C4F_T2F		*vertexData_;

	int					indicesCount_;
	GLubyte				*indices_;

	GLubyte				opacity_;
	ccColor3B			color_;
	ccBlendFunc			blendFunc_;
}
///
//	Change the percentage to change progress.
///
@property ProgressTimerType type;
///
//     The percentage of progress from 0..100
///
@property float percentage;
@property (retain) CCTexture2D *texture;
@property ccColor3B color;
@property GLubyte opacity;
@property ccBlendFunc blendFunc;

///
//	Creates a progress timer with the texture as the shape the timer goes through
///
+ (id) progressWithTexture:(CCTexture2D*) aTexture;
- (id) initWithTexture:(CCTexture2D*) aTexture;

@end
</pre>
<p>We&#8217;ll skip the basic initializing and destruction of variables and get right to the most important piece. The mapping of the image in order to create the radial indicator.</p>
<p>Every time a user changes the percentage we will update the ProgressTimer vertex data.</p>
<pre class="brush: objc; title: ;">

-(void)setPercentage:(float) percentage
{
	if(percentage_ &lt; 0.f)
		percentage_ = 0.f;
	else if(percentage &gt; 100.0f)
		percentage_  = 100.f;
	else
		percentage_ = percentage;

	[self updateProgress];
}
</pre>
<p><strong>ProgressTimer</strong>&#8216;s <em>updateProgress</em> will call <em>updateRadial</em> if our type is set to <em>kProgressTimerTypeRadialCCW</em> or <em>kProgressTimerTypeRadialCCW</em>. Radial type is our pie slice indicator and the CW/CCW suffix represents it&#8217;s rotation direction (clockwise or counter-clockwise).</p>
<p>What we will do is understand the implementation details of developing the radial slices.</p>
<p>Every radial update, we will release all vertex data memory on the heap.</p>
<h3>ProgressTimer.m <em>updateRadial</em></h3>
<pre class="brush: objc; title: ;">
	//	release all previous information
	if(vertexData_){
		free(vertexData_);
		vertexData_ = 0;
		vertexDataCount_ = 0;
	}

	if(indices_){
		free(indices_);
		indices_ = 0;
		indicesCount_ = 0;
	}

	//	If percentage is zero it's quicker not to create the vertexData
	if(percentage_ == 0.f)
		return;
</pre>
<h3>Finding that midpoint</h3>
<p>The easiest vertex point to find on the image is the midpoint and as an added bonus we will use a <strong>CCNode</strong>&#8216;s <em>anchorPoint</em> so we have a choice for the center. The midpoint has to be adjusted by the actual texture maximums since we don&#8217;t always deal with texture sizes with powers of 2. Once we have the midpoint we now have enough information to find the next needed vertex.</p>
<pre class="brush: objc; title: ;">
	CGPoint tMax = ccp(texture_.maxS,texture_.maxT);
	CGPoint midpoint = ccpCompMult(self.anchorPoint, tMax);
</pre>
<p>ccCompMult is just a multiplying each component of the two points together</p>
<pre class="brush: objc; title: ;">
CGPoint ccpCompMult(CGPoint a, CGPoint b)
{
	return ccp(a.x * b.x, a.y * b.y);
}
</pre>
<h3>The percentage point</h3>
<p>Now we find the vertex point based on the <strong>ProgressTimer</strong> percentage.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-rotation-point.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-rotation-point.png" alt="" title="finding-rotation-point" width="201" height="204" class="alignnone size-full wp-image-168" /></a></p>
<p>We can find the angle needed to rotate from the 12 o&#8217;clock position.<br />
Taking that angle, the point of rotation is found by doing a vector rotation from the vertex at the 12 o&#8217;clock to the percentage point.</p>
<pre class="brush: objc; title: ;">
	float alpha = percentage_ / 100.f;
	//	Otherwise we can get the angle from the alpha
	float angle = 2.f*M_PI * ( type_ == kProgressTimerTypeRadialCW? alpha : 1.f - alpha);

	//	We find the vector to do a hit detection based on the percentage
	//	We know the first vector is the one @ 12 o'clock (top,mid) so we rotate
	//	from that by the progress angle around the midpoint pivot
	CGPoint percentagePt = ccpRotateByAngle(ccp(midpoint.x, 0.f), midpoint, angle);
</pre>
<p>ccpRotateByAngle takes our point and a pivot and rotates it around the pivot by the angle.</p>
<pre class="brush: objc; title: ;">
CGPoint ccpRotateByAngle(CGPoint v, CGPoint pivot, float angle) {
	CGPoint r = ccpSub(v, pivot);
	float t = r.x;
	double cosa = cosf(angle), sina = sinf(angle);
	r.x = t*cosa - r.y*sina;
	r.y = t*sina + r.y*cosa;
	r = ccpAdd(r, pivot);
	return r;
}
</pre>
<p>We&#8217;re almost there but the rotated point isn&#8217;t the correct point needed for the vertex data. What we really need is the intersection point from the line edge of the texture and the percentage line.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-hit-point.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-hit-point.png" alt="" title="finding-hit-point" width="221" height="217" class="alignnone size-full wp-image-169" /></a></p>
<p>How I attacked this problem is that the texture coordinates need to be in an array so we can quickly find the correct edge for the intersection test.</p>
<pre class="brush: cpp; title: ;">
#define kProgressTextureCoordsCount 4
const CGPoint kProgressTextureCoords[kProgressTextureCoordsCount] = {{0,0},{0,1},{1,1},{1,0}};
</pre>
<p><a href="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-corner-vertex.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-corner-vertex.png" alt="" title="texture-corner-vertex" width="228" height="244" class="alignnone size-full wp-image-174" /></a><br />
As I finished writing this I noted that maximum texture coordinate values are always 0 and 1 so let&#8217;s represent the array as a sequence of bits 00011110 (which corresponds to 0x1e).</p>
<p>So I rewrote the array as</p>
<pre class="brush: cpp; title: ;">
#define kProgressTextureCoordsCount 4
const char kProgressTextureCoords = 0x1e;
</pre>
<p>And a function that will give me the corresponding texture coordinates for an index value. It pretty much operates at the bit level to retrieve the correct value (if this is confusing I may write a lesson on bit operations).</p>
<pre class="brush: objc; title: ;">
-(CGPoint)boundaryTexCoord:(char)index
{
	if (index &lt; kProgressTextureCoordsCount) {
		switch (type_) {
			case kProgressTimerTypeRadialCW:
				return ccp((kProgressTextureCoords&gt;&gt;((index&lt;&lt;1)+1))&amp;1,(kProgressTextureCoords&gt;&gt;(index&lt;&lt;1))&amp;1);
			case kProgressTimerTypeRadialCCW:
				return ccp((kProgressTextureCoords&gt;&gt;(7-(index&lt;&lt;1)))&amp;1,(kProgressTextureCoords&gt;&gt;(7-((index&lt;&lt;1)+1)))&amp;1);
			default:
				break;
		}
	}
	return CGPointZero;
}
</pre>
<p>Now we have the texture corner coordinates; we now need the edge of the texture and the percentage point line.</p>
<p>We can find the nearest edge based on the alpha value. Since we need 2 points for the line, we grab the previous index and make sure the previous index is wrapped within our array bounds.</p>
<pre class="brush: objc; title: ;">
	int index = roundf(kProgressTextureCoordsCount*alpha);
	int pIndex = (index + (kProgressTextureCoordsCount - 1))%kProgressTextureCoordsCount;

	CGPoint edgePtA = [self boundaryTexCoord:index % kProgressTextureCoordsCount];
	CGPoint edgePtB = [self boundaryTexCoord:pIndex];
</pre>
<p>The percentage line is just the midpoint and the percentage point.</p>
<p><em>ccpLineIntersect</em> returns true if an intersection occurred. We pass it 4 points that make up 2 lines.<br />
L1 = p2 &#8211; p1<br />
L2 = p4 &#8211; p3<br />
Then we grab the hit point using the returned &#8216;s&#8217; or &#8216;t&#8217; value.<br />
hit = midpoint + (percentagePoint &#8211; midpoint)*t;</p>
<pre class="brush: cpp; title: ;">
bool ccpLineIntersect(CGPoint p1, CGPoint p2,
								 CGPoint p3, CGPoint p4,
								 float *s, float *t){
	CGPoint p13, p43, p21;
	float d1343, d4321, d1321, d4343, d2121;
	float numer, denom;

	p13 = ccpSub(p1, p3);

	p43 = ccpSub(p4, p3);

	//Roughly equal to zero but with an epsilon deviation for float
	//correction
	if (ccpFuzzyEqual(p43, CGPointZero, kCGPointEpsilon))
		return false;

	p21 = ccpSub(p2, p1);

	//Roughly equal to zero
	if (ccpFuzzyEqual(p21,CGPointZero, kCGPointEpsilon))
		return false;

	d1343 = ccpDot(p13, p43);
	d4321 = ccpDot(p43, p21);
	d1321 = ccpDot(p13, p21);
	d4343 = ccpDot(p43, p43);
	d2121 = ccpDot(p21, p21);

	denom = d2121 * d4343 - d4321 * d4321;
	if (fabs(denom) &lt; kCGPointEpsilon)
		return false;
	numer = d1343 * d4321 - d1321 * d4343;

	*s = numer / denom;
	*t = (d1343 + d4321 *(*s)) / d4343;
	return true;
}
</pre>
<p>We pass the points into our intersect formula (notice we multiply the corner components by tMax since we need the actual texture coordinates and sometimes we&#8217;ll have images that are not powers of 2.</p>
<pre class="brush: objc; title: ;">
//	s and t are returned by ccpLineIntersect which explains how to use them
	float s = 0, t = 0;
	ccpLineIntersect(ccpCompMult(edgePtA,tMax), ccpCompMult(edgePtB,tMax),
					 midpoint, percentagePt, &amp;s, &amp;t);

	//	get the hit point
	CGPoint hit = ccpAdd(midpoint, ccpMult(ccpSub(r2, midpoint),t));
</pre>
<p>We have all our needed points calculated! Now all that&#8217;s left is creating the vertex data.</p>
<h2>Creating Our Vertex Data</h2>
<p>To create the vertex data we first need to convert texture coordinates (in the 0..1) range to actual vertex coordinates [0..imageSize] which I have written below.</p>
<pre class="brush: objc; title: ;">
///
//	@returns the vertex position from the texture coordinate
///
-(CGPoint)vertexFromTexCoord:(CGPoint) texCoord
{
	if (texture_) {
		float min = 0, maxW = texture_.contentSize.width, maxH = texture_.contentSize.height;
		return ccp(lerp(min, maxW, texCoord.x/texture_.maxS),
				   lerp(min, maxH, (1.f -(texCoord.y/texture_.maxT))));
	} else {
		return CGPointZero;
	}
}
</pre>
<p>Now we have all that we need to create our vertex data what we&#8217;ll do is first store the midpoint position. Then the point at 12 o&#8217;clock on the texture.</p>
<p>Now we add each corner of the texture into the vertex array until we reach the hit point and we add the hit point last.</p>
<p>After the vertex data is complete we begin creating the triangle by setting up the indexes. Let&#8217;s take a look at our original setup of vertex data.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png" alt="" title="texture-mapping-triangles" width="209" height="231" class="alignnone size-full wp-image-181" /></a><br />
To create triangles from the example vertexes above we can see that the indexes will hold.</p>
<pre>
indices_ = {0,1,2, 0,2,3, 0,4,5, 0,5,6};
</pre>
<p>The code is shown below:</p>
<pre class="brush: objc; title: ;">
	//	The size of the vertex data is the index from the hitpoint
	//	the 3 is for the midpoint, 12 o'clock point and hitpoint position.
	vertexDataCount_ = index + 3;
	vertexData_ = malloc(vertexDataCount_ * sizeof(ccV2F_C4F_T2F));

	//	First we populate the array with the midpoint, then all
	//	vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
	vertexData_[0].texCoords = (ccTex2F){midpoint.x, midpoint.y};
	vertexData_[0].vertices = [self vertexFromTexCoord:midpoint];

	vertexData_[1].texCoords = (ccTex2F){midpoint.x, 0.f};
	vertexData_[1].vertices = [self vertexFromTexCoord:ccp(midpoint.x, 0.f)];

	for(int i = 0; i &lt; index; ++i){
		CGPoint texCoords = ccpCompMult([self boundaryTexCoord:i], tMax);

		vertexData_[i+2].texCoords = (ccTex2F){texCoords.x, texCoords.y};
		vertexData_[i+2].vertices = [self vertexFromTexCoord:texCoords];
	}

	//	hitpoint will go last
	vertexData_[vertexDataCount_ - 1].texCoords = (ccTex2F){hit.x, hit.y};
	vertexData_[vertexDataCount_ - 1].vertices = [self vertexFromTexCoord:hit];	

	indicesCount_ = 3 * (index + 1);
	indices_ = malloc(indicesCount_ * sizeof(GLubyte));

	//	We only go up to index since we do three increments
	for(int i=0;i &lt; indicesCount_/3; ++i){
		indices_[3*i] = 0;
		indices_[3*i + 1] = i + 1;
		indices_[3*i + 2] = i + 2;
	}
</pre>
<p>The only thing left to do is draw our vertex data</p>
<h3><strong>ProgressTimer</strong> <em>draw</em></h3>
<pre class="brush: objc; title: ;">
	glBindTexture(GL_TEXTURE_2D, texture_.name);
	glVertexPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &amp;vertexData_[0].vertices);
	glTexCoordPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &amp;vertexData_[0].texCoords);
	glColorPointer(4, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &amp;vertexData_[0].colors);
	glDrawElements(GL_TRIANGLES, indicesCount_, GL_UNSIGNED_BYTE, indices_);
</pre>
<p>And now we have a ProgressTimer indicator. If you want to see the demo file of this tutorial then just click on the link.</p>
<div class="clearfix download-wrapper">
<a href="http://dl.dropbox.com/u/271717/ProgressDemo.zip"><span class="xcode-download-icon" style="vertical-align:text-top;"></span></a><br />
<a class="download" href="http://dl.dropbox.com/u/271717/ProgressDemo.zip">Download the XCode Demo</a>
</div>
<p>This demo uses the fast, easy and open source cocos2d framework.<br />
<a href="http://www.cocos2d-iphone.org/"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/official-cocos-logo-landscape-happy-300x89.png" alt="" title="cocos2d" width="300" height="89" class="alignnone size-medium wp-image-195" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/02/programming/progresstimer-for-cocos2d/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Pile Some Pixels!</title>
		<link>http://fancyratstudios.com/2010/01/games/pile-some-pixels/</link>
		<comments>http://fancyratstudios.com/2010/01/games/pile-some-pixels/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 20:46:23 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Pixel Pile]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=117</guid>
		<description><![CDATA[Pixel Pile is now in the App store and ready for download! Grab it now for only $0.99. There&#8217;s already some fancy pants updates in the works that make the game even more fancy and perhaps more pantsy. There&#8217;s already some people on the high score leader board so get to it and pile those [...]]]></description>
			<content:encoded><![CDATA[<p>Pixel Pile is now in the App store and ready for download!  Grab it now for only $0.99.  There&#8217;s already some fancy pants updates in the works that make the game even more fancy and perhaps more pantsy.  There&#8217;s already some people on the high score leader board so get to it and pile those pixels to the sky!</p>
<p><a class="app-store-99" href="http://itunes.apple.com/us/app/pixel-pile/id349146093?mt=8&#038;uo=6"><span class="no-display">Get for only $0.99</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/01/games/pile-some-pixels/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pixel Pile &#8211; New Video</title>
		<link>http://fancyratstudios.com/2010/01/games/pixel-pile-new-video/</link>
		<comments>http://fancyratstudios.com/2010/01/games/pixel-pile-new-video/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 21:30:04 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Pixel Pile]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=90</guid>
		<description><![CDATA[Stupendous! A brand new Pixel Pile video as promised. There are still some difficulties with the screen capture causing some of the colours to be washed out and blurry when recording from the iPhone simulator. The full retail game will be more vibrant and clear to be sure!]]></description>
			<content:encoded><![CDATA[<p>Stupendous! A brand new Pixel Pile video as promised.  There are still some difficulties with the screen capture causing some of the colours to be washed out and blurry when recording from the iPhone simulator.  The full retail game will be more vibrant and clear to be sure!</p>
<div class="video-embedded">
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/QkaI80H9TSs&#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/QkaI80H9TSs&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
</div>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/01/games/pixel-pile-new-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pixel Pile</title>
		<link>http://fancyratstudios.com/2010/01/games/pixel-pile/</link>
		<comments>http://fancyratstudios.com/2010/01/games/pixel-pile/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 22:07:05 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Pixel Pile]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=74</guid>
		<description><![CDATA[Pixel Pile has been sent in to Apple and so we must wait for their approval before we see the game up in the App store. Pixel Pile will be Fancy Rat Studios second game for the iPhone, and will be available for the low price of $0.99. For now here is a short demo [...]]]></description>
			<content:encoded><![CDATA[<p>Pixel Pile has been sent in to Apple and so we must wait for their approval before we see the game up in the App store.  Pixel Pile will be Fancy Rat Studios second game for the iPhone, and will be available for the low price of $0.99.  For now here is a short demo of the game in it&#8217;s not quite finished state. A new video has been recorded and will be posted soon.</p>
<div class="video-embedded">
<object  width="425" height="344"><param name="movie" value="http://www.youtube.com/v/9VxtvpmHSqE&#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/9VxtvpmHSqE&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
</div>
<p> We found during the recording of this short Pixel Pile demo that the screen capture didn&#8217;t work out perfectly so the video is a little bit washed out.  Rest assured that the retail game will be bright and vibrant and those stars pulsing to the beat of the music will definitely stand out.  We were really lucky to find music from <a href="http://www.mattmcfarland.com">mattmcfarland.com</a>, be sure to check it out for some great music if you happen to be developing an indie game.</p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/01/games/pixel-pile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pirates vs Ninjas Available</title>
		<link>http://fancyratstudios.com/2010/01/games/pirates-vs-ninjas-available/</link>
		<comments>http://fancyratstudios.com/2010/01/games/pirates-vs-ninjas-available/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 23:23:33 +0000</pubDate>
		<dc:creator>fancy rat</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Pirates vs Ninjas]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=53</guid>
		<description><![CDATA[Get Pirates vs Ninjas for Free right here. This is Fancy Rat Studios very first game, a quick little pick up and play whac-a-mole style shooter. Be a Pirate, kill some Ninjas. Be a Ninjas, kill some Pirates. Unlock achievements, multiple levels, catch items and try for a high score.]]></description>
			<content:encoded><![CDATA[<p>Get Pirates vs Ninjas for Free right <a href="http://itunes.apple.com/ca/app/pirates-vs-ninjas/id348773128?mt=8">here</a>.  This is Fancy Rat Studios very first game, a quick little pick up and play whac-a-mole style shooter.  Be a Pirate, kill some Ninjas. Be a Ninjas, kill some Pirates.  Unlock achievements, multiple levels, catch items and try for a high score.</p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/01/games/pirates-vs-ninjas-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pirates vs Ninjas Submitted</title>
		<link>http://fancyratstudios.com/2010/01/games/pirates-vs-ninjas-submitted/</link>
		<comments>http://fancyratstudios.com/2010/01/games/pirates-vs-ninjas-submitted/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 16:56:38 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Pirates vs Ninjas]]></category>
		<category><![CDATA[pvn]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/2010/01/uncategorized/pirates-vs-ninjas-submitted/</guid>
		<description><![CDATA[Our very first free game has just been submitted to Apple for review. After a few hiccups with our developer account the binary is finally uploaded and we are patiently waiting at Fancy Rat Studios. We aren&#8217;t sitting idle while waiting for news on Pirates vs Ninjas, Fancy Rat Studios has other games in the [...]]]></description>
			<content:encoded><![CDATA[<p>Our very first free game has just been submitted to Apple for review.  After a few hiccups with our developer account the binary is finally uploaded and we are patiently waiting at Fancy Rat Studios.  We aren&#8217;t sitting idle while waiting for news on Pirates vs Ninjas, Fancy Rat Studios has other games in the works and we hope to get more information on all our projects up on the website soon.</p>
<p>More information on Pirates vs Ninjas will be added soon to the <a href="http://fancyratstudios.com/games/pirates-vs-ninjas/">PvN Page</a>, if you would like to receive updates or contact us about the game you can reach us at <a href="mailto:pvn@fancyratstudios.com">pvn@fancyratstudios.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/01/games/pirates-vs-ninjas-submitted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pirates vs Ninjas Free</title>
		<link>http://fancyratstudios.com/2009/12/games/pirates-vs-ninjas-free/</link>
		<comments>http://fancyratstudios.com/2009/12/games/pirates-vs-ninjas-free/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 16:36:56 +0000</pubDate>
		<dc:creator>Terrance</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Pirates vs Ninjas]]></category>
		<category><![CDATA[Free]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=5</guid>
		<description><![CDATA[Our upcoming title for the iPhone and iPod Touch, Pirates vs Ninjas, will be released for free! We will be releasing the game for free in order to test the waters as the title is our first foray into the Apple App Store marketplace. The Fancy Rat Studios page will be updated soon with media [...]]]></description>
			<content:encoded><![CDATA[<p>Our upcoming title for the iPhone and iPod Touch, Pirates vs Ninjas, will be released for free!  We will be releasing the game for free in order to test the waters as the title is our first foray into the Apple App Store marketplace.  The Fancy Rat Studios page will be updated soon with media for Pirates vs Ninjas and more information.</p>
<p>Arrrrrr.</p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2009/12/games/pirates-vs-ninjas-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.888 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-04 15:01:27 -->

