<?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>Angry Fish Studios</title>
	<atom:link href="http://www.AngryFishStudios.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.AngryFishStudios.com</link>
	<description></description>
	<lastBuildDate>Sun, 10 Jul 2011 18:23:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Open GL ES: Part 1.5</title>
		<link>http://www.AngryFishStudios.com/2011/06/open-gl-es-part-1-5/</link>
		<comments>http://www.AngryFishStudios.com/2011/06/open-gl-es-part-1-5/#comments</comments>
		<pubDate>Fri, 24 Jun 2011 04:46:15 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=376</guid>
		<description><![CDATA[There&#8217;s good news and bad news. I&#8217;ve made a lot of progress in getting a simple engine running is the good news. And even better news is that now that the 2011 WWDC videos are online there&#8217;s some awesome new videos about GLKit. I&#8217;d recommend checking them out if you&#8217;re a developer because some of [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s good news and bad news. I&#8217;ve made a lot of progress in getting a simple engine running is the good news. And even better news is that now that the 2011 WWDC videos are online there&#8217;s some awesome new videos about GLKit. I&#8217;d recommend checking them out if you&#8217;re a developer because some of the features seem very nice, I&#8217;ll definitely be upgrading to OpenGLES 2.0 when iOS 5.0 comes out.</p>
<p>The bad news is that I had an eye appointment earlier today where my eyes were dilated so I can&#8217;t really see.  I was starting to think I wouldn&#8217;t be able to finish my post for today but it&#8217;s starting to come back so I can make a short post.  I&#8217;m getting LASIK done next month because I&#8217;m nearsighted enough that I can&#8217;t even use a computer without my glasses/contacts. I&#8217;ve always hated feeling so dependent on them. Getting my eyes dilated has effectively made me farsighted for the past 7 hours and it&#8217;s pretty much just as bad. The real annoying part is that I have to wear my glasses or I can&#8217;t see anywhere! It&#8217;s a really interesting juxtaposition.</p>
<p>So for today&#8217;s post I&#8217;m going to talk about the files that are in the template I posted last week. If you haven&#8217;t seen it, get it at the bottom of the page here: <a href="http://www.angryfishstudios.com/2011/06/opengl-es-part-1/">OpenGL ES: Part 1</a></p>
<p><span id="more-376"></span></p>
<h2>App Delegate</h2>
<p>The app delegate is pretty much as straight forward as it could be. When the app is launched MainWindow.xib creates the app delegate, a window and one view. The view is a subclass of EAGLView. The only code in the body of OpenGLES2DAppDelegate is:</p>
<pre lang="objc">- (void)applicationDidFinishLaunching:(UIApplication *)application {
	[glView startAnimation];
}

- (void)applicationWillResignActive:(UIApplication *)application {
	[glView stopAnimation];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
	[glView startAnimation];
}

- (void)applicationWillTerminate:(UIApplication *)application {
    [glView stopAnimation];
}</pre>
<p>This should be pretty obvious but what it does is start and stop the EAGLView&#8217;s animation whenever the app launches or terminates. It also does it when the app goes into or out of the background beacuse OpenGL isn&#8217;t allowed to run on apps in the background. The way it does this is by calling a method which stops the timer that calls the render method every frame. Or in the case of startAnimation it creates the timer.</p>
<h2>EAGLView</h2>
<p>The EAGLView does the bulk of the work. Lets just dive into the init:</p>
<pre lang="objc">- (id)initWithCoder:(NSCoder*)coder
{
	if((self = [super initWithCoder:coder])) {
		// Get the layer
		CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;

		eaglLayer.opaque = YES;
		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
										[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; //OpenGL ES 1.1

		if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) {
			//[self release];
			return nil;
		}

		animating = FALSE;
		animationFrameInterval = 1;
		displayLink = nil;

        [self setupView];
	}

	return self;
}</pre>
<p>First off the reason we use initWithCoder is because it&#8217;s getting created from a nib. If you plan on creating it programmatically you&#8217;d need to implement something else. The first thing we do is get the layer, now because we implmented the class method &#8220;layerClass&#8221; and returned &#8220;[CAEAGLLayer class]&#8221; our view was created with a layer that is a CAEAGLLayer already. The layer is set to opaque because there can be performance issues if it&#8217;s set to transparent, note: this isn&#8217;t something I&#8217;ve looked into, just read, so if you need it to be transparent who knows it might work?  Next we set the drawable properties, this is a dictionary containing only the two properties you see here. Retained Backing makes it so frames are saved and drawn over next time, we&#8217;ll be redrawing the entire screen each frame so there&#8217;s no need to waste the extra memeory. The color format can be either kEAGLColorFormatRGBA8, which means 8 bits each for red, blue, green and alpha (transparency) or kEAGLColorFormatRGB565 a 16-bit format with 5 bits for both red and blue, and 6 for green. So a screen buffer that&#8217;s 320&#215;480 is 153,600 pixels, meaning it would take ~300KB of memory in 16-bit or ~600 in 32-bit. It&#8217;s another area where you need to access your needs.  It&#8217;s important to note that this has to be called before renderbufferStorage:fromDrawable: is called. This should make sense because the size of the storage is going to depend on the color format, also should you change these options you&#8217;ll have to call renderbufferStorage:fromDrawable: again.</p>
<p>Ok next we generate an EAGLContext and you&#8217;ll see that it&#8217;s an OpenGL ES 1.1 context being created. This context is what manages the state of OpenGL, so when you&#8217;re changing things you need to make sure it&#8217;s set as the current context. The if conditional makes sure that all three of these things happen: the context was created, it&#8217;s successfully set, and it sucessfully creates a framebuffer. If any of these fail the initilization of your EAGLView fails. There should be better error handling for what to do when this happens but I figure that might vary app to app.</p>
<p>Finally we set some ivars and call setupView, then return the newly created EAGLView.</p>
<pre lang="objc">- (BOOL)createFramebuffer {
	glGenFramebuffersOES(1, &amp;defaultFramebuffer); //Create the Frame Buffer
	glGenRenderbuffersOES(1, &amp;colorRenderbuffer); //Create the Render Buffer

	glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); //Bind the Frame Buffer
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); //Bind the Render Buffer
	[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)self.layer]; //Create the storage based on the layer
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); 

	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &amp;backingWidth); //Get the width of the renderbuffer
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &amp;backingHeight); //Get the height of the renderbuffer

	if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
		NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
		return NO;
	}

	return YES;
}</pre>
<p>This method got sneakly called after the creation of our context in that if statement. It also gets called whenever layoutSubviews happens (Which for most cases should only be once). The goal of it is to create the framebuffer and the renderbuffer. Because Apple can probably explain it better than I can here&#8217;s their definition of the two:</p>
<ul>
<li>A renderbuffer is a simple 2D graphics image in a specified format. This format usually is defined as color, depth or stencil data. Renderbuffers are not usually used in isolation, but are instead used as attachments to a framebuffer.</li>
<li>Framebuffer objects are the ultimate destination of the graphics pipeline. A framebuffer object is really just a container that attaches textures and renderbuffers to itself to create a complete configuration needed by the renderer.</li>
</ul>
<p>So the framebuffer is a chunk of memory which is big enoug to contain the data for a pixel (32 or 16 bits) for each pixel we need (320&#215;480). The renderbuffer is a little harder to grasp but it&#8217;s kind of like a scratchpad for the framebuffer. The renderbufferStorage:fromDrawable: method is what sets aside the chunk of memory based on the size of the layer.</p>
<pre lang="objc">- (void) setAnimationFrameInterval:(NSInteger)frameInterval {
	// Frame interval defines how many display frames must pass between each time the
	// display link fires. The display link will only fire 30 times a second when the
	// frame internal is two on a display that refreshes 60 times a second. The default
	// frame interval setting of one will fire 60 times a second when the display refreshes
	// at 60 times a second. A frame interval setting of less than one results in undefined
	// behavior.
	if (frameInterval &gt;= 1)
	{
		animationFrameInterval = frameInterval;

		if (animating)
		{
			[self stopAnimation];
			[self startAnimation];
		}
	}
}

#pragma mark - Animation methods

- (void) startAnimation {
	if (!animating)
	{
        displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)];
        [displayLink setFrameInterval:animationFrameInterval];
        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

        animating = TRUE;
	}
}

- (void)stopAnimation {
	if (animating)
	{
        [displayLink invalidate];
        displayLink = nil;

		animating = FALSE;
	}
}</pre>
<p>These three methods set up the timer for rendering. We want to render at some framerate usually 30 or 60fps. CADisplayLink is the ideal method because it gets called in sync with the screen refresh rate. The screen on an iPhone refreshes at 60fps, the interval has to be a natural number. So at 1 it&#8217;s 60fps, 2 it&#8217;s 30, 3 would be 20, etc. This is only an attempted framerate though so if you end up taking too long for drawing code it will skip to the next update. When we start and stop the animation we add or remove the displayLink which causes drawView to get called.</p>
<pre lang="objc">- (void)setupView
{
	// Sets up matrices and transforms for OpenGL ES
	glViewport(0, 0, backingWidth, backingHeight);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrthof(-1.0f, 1.0f, 1.5f, -1.5f, -1.0f, 1.0f);
	glMatrixMode(GL_MODELVIEW);

	// Clears the view with gray
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

	// Sets up pointers and enables states needed for using vertex arrays and textures
	glVertexPointer(2, GL_FLOAT, 0, spriteVertices);
	glEnableClientState(GL_VERTEX_ARRAY);
	glTexCoordPointer(2, GL_SHORT, 0, spriteTexcoords);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    //Load the texture from an image
    UIImage *mitchImage = [UIImage imageNamed:@"Mitch.png"];
    mitchTexture = [[Texture2D alloc] initWithImage:mitchImage filter:GL_LINEAR];

    // Enable use of the texture
    glEnable(GL_TEXTURE_2D);
    // Set a blending function to use
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    // Enable blending
    glEnable(GL_BLEND);
}</pre>
<p>SetupView gets called once and does some things that only need to be done once. I&#8217;m not really going to go into the difference between all the levels of model view, projection view, view port because some of the tutorials I listed earlier can explain it better than me. The important part is that we set the viewport to the size of the renderbuffer we made before. The projection matrix is set to be a coordinate system from -1,1 on the x, -1.5,1.5 on the y, and -1,1 on the z. The reason for Y being 1.5 is that 480:320 is a 1.5:1 ratio so this keeps everything square. The z dimention will be largely not used because we&#8217;re working in 2D.</p>
<p>glClearColor sets the color that the background will be when we clear it, this is one of the easiest ways to check that you&#8217;ve set up everything properly.</p>
<p>The next series of calls are what we set up to draw the image. This is just demo code and will get moved out as I expand the template. glVertexPointer is how we pass in the vertexes to draw. The first parameter, 2, says how many values per vertex (x,y). Next is the type of the values. Third the stride, so say we had an array with vertex positions followed by the color values so XYRGBXYRGB and so on. We would enter a stride of 3 so it would read the first two (XY) then skip the next three (RGB) then read the next 2 (second XY). And finally we pass in the array with the verticies. glEnableClientState makes it so when we actually do a draw command it uses the vertex array we just passed, likewise one line down calling it on GL_TEXTURE_COORD_ARRAY enables drawing textures from the texture array we pass to glTexCoordPointer.</p>
<p>One important thing to note is that you probably don&#8217;t want to use imageNamed in your actual code. The reason being that iOS caches images loaded with imageNamed in preperation of the image being loaded again. We&#8217;re loading it to a texture so there&#8217;s no need to retain it at all. So after loading the image we create a Texture2D from it. Then enable the context to draw 2D textures and belending.</p>
<pre lang="objc">- (void)drawView
{
	// Make sure that you are drawing to the current context
	[EAGLContext setCurrentContext:context];

	glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

	glClear(GL_COLOR_BUFFER_BIT);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}</pre>
<p>Finally drawView is what gets called every time the displayLink fires. The first call is relatively trivial in this example but if you had multiple contexts you&#8217;d want to make sure you&#8217;re using the right one. Now we bind the framebuffer, clear it to the clear color, and use glDrawArrays to draw all four vertices in two triangles. The zero here is the starting index in the array. All that&#8217;s left is to bind the renderbuffer and present it to the screen through the CAEAGLLayer.</p>
<h2>Texture 2D</h2>
<p>As I said last time this is a pretty barebones. I figure it&#8217;s not really worth expanding upon until it&#8217;s actually needed so if you want to use pvr files you&#8217;re on your own for now.</p>
<pre lang="objc">- (id)initWithImage:(UIImage*)content filter:(GLenum)filter {

    self = [super init];
    if(self) {

        // Creates a Core Graphics image from an image file
        CGImageRef contentRef = content.CGImage;
        // Get the width and height of the image
        width = CGImageGetWidth(contentRef);
        height = CGImageGetHeight(contentRef);
        // Texture dimensions must be a power of 2. If you write an application that allows users to supply an image,
        // you'll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2.

        if(contentRef) {
            // Allocated memory needed for the bitmap context
            GLubyte *contentData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
            // Uses the bitmap creation function provided by the Core Graphics framework.
            CGContextRef contentContext = CGBitmapContextCreate(contentData, width, height, 8, width * 4, CGImageGetColorSpace(contentRef), kCGImageAlphaPremultipliedLast);
            // After you create the context, you can draw the sprite image to the context.
            CGContextDrawImage(contentContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), contentRef);
            // You don't need the context at this point, so you need to release it to avoid memory leaks.
            CGContextRelease(contentContext);

            // Use OpenGL ES to generate a name for the texture.
            glGenTextures(1, &amp;name);
            // Bind the texture name.
            glBindTexture(GL_TEXTURE_2D, name);

            // Set the texture parameters to use a the specified filter
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);

            // Specify a 2D texture image, providing the a pointer to the image data in memory
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, contentData);
            // Release the image data
            free(contentData);

        }
    }

    return self;
}</pre>
<p>So the first step is to get a CGImageRef form the UIImage. Next we get it&#8217;s dimentions, this texture loader only works with images that are a power of 2. I plan on making any as texture atlases in zwoptex so I didn&#8217;t bother implementing a feature to make them power 2 if they weren&#8217;t. It also doesn&#8217;t actually check if they are powers of two, but again I expect it to get replaced. Basically here we get the bitmap data from the image then create a texture from it. The Texture2D stores it&#8217;s name of the texture which is what OpenGL calls it&#8217;s handle or identifier. One thing to add is that when Texture2D dealloc&#8217;s we should remove the texture from OpenGL because a texture will only be used through it&#8217;s Texture2D so once the Texture2D is gone we can free it up from OpenGL.</p>
<h2>Conclusion</h2>
<p>Phew, maybe that wasn&#8217;t as short as I though it would be. My eyesight is actually noticably better, I can almost read my phone without looking like I&#8217;m 90. Next week should be my last week on iDevBlogADay so I&#8217;ll try to have a nice fat post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/06/open-gl-es-part-1-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenGL ES: Part 1</title>
		<link>http://www.AngryFishStudios.com/2011/06/opengl-es-part-1/</link>
		<comments>http://www.AngryFishStudios.com/2011/06/opengl-es-part-1/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 23:39:52 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=366</guid>
		<description><![CDATA[Well it&#8217;s certainly been an interesting Week! WWDC was this week and Apple has released the preliminary documentation for iOS 5.0.  Because of that what I was going to write about this week actually changed. I was going to talk about setting up an OpenGL project and getting an image on the screen. Well, I [...]]]></description>
			<content:encoded><![CDATA[<p>Well it&#8217;s certainly been an interesting Week! WWDC was this week and Apple has released the preliminary documentation for iOS 5.0.  Because of that what I <em>was</em> going to write about this week actually changed. I was going to talk about setting up an OpenGL project and getting an image on the screen. Well, I am still going to talk about that but less in depth than I was going to. You see, iOS 5 has some new classes in it that are going to make using OpenGL even easier! GLKit is a new framework that will make it much easier to set up views with OpenGL. It also looks like it will provide a texture loader which is nice.</p>
<p>However that&#8217;s not out yet and covered under NDA so that&#8217;s not what I&#8217;ll be talking about! Though it is really nice that it&#8217;s coming because one of the biggest barriers to entry is how much initial setup you have to do before you can start tinkering. I definitely learn from seeing and doing so getting something up and running is pretty important to me. Because of this I created an Xcode template which I think will speed the process along. It&#8217;s really simple, it consists of an EAGLView and a Texture2D class that can be used to load images into OpenGL to be used as textures.</p>
<p><span id="more-366"></span></p>
<p>Now the first thing I want to say is that the goal of this template is just to be a place to get stuff up and running and to draw something to the screen. It makes it easy to tinker and start getting a feel for OpenGL.  A real application is going to want to structure certain parts differently.  You&#8217;ll want a way to manage your textures, and batch objects to be drawn. Binding textures is an expensive operation so you want to do it as infrequently as possible.</p>
<p>Consider this quazi-Tetris puzzle game of some sort I have below. Now imagine each of those shapes is its own sprite. If you wanted to render this board one easy to implement way would be to simply start in the top left and move left to right, top to bottom rendering each object you haven&#8217;t yet drawn the first time you get to it. That would look something like this:</p>
<p><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/06/Texture-Swaps-1.png"><img class="aligncenter size-full wp-image-367" title="Texture-Swaps-1" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/06/Texture-Swaps-1.png" alt="" /></a></p>
<p>You can see in this example that almost every time we have to swap which texture is current being used by OpenGL.  Only in one case are we drawing the same texture twice in a row. This results in a lot of texture swapping which is very poor for performance. So instead what we might do is make a queue of all the objects that need to be drawn and then sort that queue. The benefit to this is that we&#8217;re drawing all instances of one texture concurrently minimizing the number of texture swaps:<br />
<a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/06/Texture-Swaps-2.png"><img class="aligncenter size-full wp-image-368" title="Texture-Swaps-2" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/06/Texture-Swaps-2.png" alt="" /></a></p>
<p>Now taking this to it&#8217;s logical conclusion the best scenario would be if we just loaded one texture and never swapped it out for another. But how would we do this? Well the solution is to make a texture atlas combining all of your sprites onto a single image. Then when you go to render one of the sprites you only render a portion of the total texture. The benefit is that you only have to load one texture:</p>
<p><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/06/Texture-Swaps-3.png"><img class="aligncenter size-full wp-image-369" title="Texture-Swaps-3" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/06/Texture-Swaps-3.png" alt="" /></a></p>
<p>The drawbacks are that it&#8217;s going to take more memory to store that texture, if you have a large game with lots of sprites you might not be able to make them all fit on one atlas. The iPhone 3GS and up support textures of 2048px x 2048px. Also you might have certain images that are used consistently while others are dependent on the progress of the game. Consider a platformer, you might have the level elements in one atlas and the character&#8217;s sprites in a separate atlas. Thats why the best approach is a hybrid between 2 and 3.</p>
<p>I actually don&#8217;t have time to write as much as I would like to this week because I&#8217;ve got to get going to watch a friend of mine do standup. I&#8217;m going to post the template I made even though I haven&#8217;t explained what&#8217;s going on yet. All it does is set up OpenGL and draw an image to the screen. You can use this for starting OpenGL projects to play around.  It&#8217;s going to be a work in progress and as I give things more structure I&#8217;m going to improve it.</p>
<p>I should add that the Texture2D class is really simple. It expects only images who&#8217;s height and width are powers of 2. Once I saw that Apple would have their own texture loader class I figured it wasn&#8217;t really worth putting the effort into making it super complex.</p>
<p>Just download the template here: <a href="http://www.AngryFishStudios.com/downloads/OpenGL ES 1.1 2D Application.xctemplate.zip">&lt;&lt; TEMPLATE &gt;&gt;</a></p>
<p>and extract it to this folder:<br />
~/Library/Developer/Xcode/Templates/Project Templates/</p>
<p>If the Project Templates folder doesn&#8217;t exist just make one.</p>
<p>All of the tutorials I posted last week explain what&#8217;s going on here setting up OpenGL. So if you&#8217;re confused with anything I&#8217;d check them out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/06/opengl-es-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting started in OpenGL ES</title>
		<link>http://www.AngryFishStudios.com/2011/05/getting-started-in-opengl-es/</link>
		<comments>http://www.AngryFishStudios.com/2011/05/getting-started-in-opengl-es/#comments</comments>
		<pubDate>Thu, 26 May 2011 19:45:14 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=359</guid>
		<description><![CDATA[Lately I&#8217;ve been really diving into OpenGL ES and it actually has been much easier than I was expecting. OpenGL is always referred to with the feeling that it&#8217;s some kind of complicated voodoo. Now, it might just be because of all the great resources I&#8217;ve found from people who are much more pioneering than [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been really diving into OpenGL ES and it actually has been much easier than I was expecting. OpenGL is always referred to with the feeling that it&#8217;s some kind of complicated voodoo. Now, it might just be because of all the great resources I&#8217;ve found from people who are much more pioneering than me but so far it&#8217;s been quite reasonable. Now I&#8217;m sure some of you are reading this saying &#8220;But a few weeks ago you were raving about how CoreAnimation is plenty powerful enough to make a 2D game&#8221; and the answer is &#8220;It is&#8221;.  However quickly into prototyping my mole game I was realizing that I am probably going to want more power for cool effects to make it really look awesome. CoreAnimation is still a very reasonable approach, and it was great for prototyping the game up fairly quickly. If you&#8217;re the kind of person that thinks they would drown in a highly technical subject like OpenGL then CoreAnimation is a very valid option. I, on the other hand, am the kind of person to keep clawing my way up if there are better techniques out there. (And even here &#8220;better&#8221; isn&#8217;t necessarily the right word, it&#8217;s &#8220;more powerful&#8221; in this context.)</p>
<h2>The Plan</h2>
<p>The plan over the next couple weeks of blog posts is to talk about using OpenGL ES for creating a 2D game. There are a lot of OpenGL resources out there, but most of them are about OpenGL and cover topics that OpenGL ES doesn&#8217;t support. Of the remaining ones that <em>do</em> talk about OpenGL ES they tend to be about 3D. So I hope to address some of the topics more relevant to making a 2D game in OpenGL ES on the iPhone.</p>
<h2>Resources</h2>
<p>So, as I was saying over this past weekend I went through a multitude of OpenGL ES tutorials, guides, and videos. When learning something as complicated as OpenGL I really feel like reading through multiple sources is beneficial. It&#8217;s such a complex subject it&#8217;s unlikely that one source will talk hit every topic, or explain everything in a way that clicks for you.  When you read several descriptions of something each one can fill in the blanks for the other.</p>
<p>Without further ado I present my recommended sources for someone trying to learn OpenGL ES for the iPhone:</p>
<p><a href="http://www.71squared.com/iphone-tutorials/">71 Squared&#8217;s iOS Tutorials</a><br />
These tutorials from 71 squared&#8217;s Mike Daley are excellent. There&#8217;s 14 videos of Mike basically starting from scratch with OpenGL so it&#8217;s absolutely packed with information! A couple notes though: They are a little dated so there are better ways of doing some things (CADisplayLink for one). Also he is learning as he goes, so you really need to watch the whole process because he address as lot of potential problems later in the series.</p>
<p><a href="http://www.informit.com/store/product.aspx?isbn=0321699424">Learning iOS Game Programming </a><br />
Also by Mike is a book he wrote after the video series.  This book addresses both of the problems I listed up above. It goes through the process of making a game with OpenGL as a whole. I really can&#8217;t say enough good things about this book, if there&#8217;s one resource you should get it&#8217;s this! I hear a second one is in the works with follow up concepts, can&#8217;t wait!</p>
<p><a href="http://iphonedevelopment.blogspot.com/2010/10/opengl-es-20-for-ios-chapter-1.html">Jeff Lamarche&#8217;s OpenGL Book Chapters</a><br />
Jeff Lamarche was in the process of writing an OpenGL book when it got canceled.  He generously posted the first four chapters he had already written on his blog. Though they mostly deal with OpenGL ES 2.0 I would say it&#8217;s one of the best resources for explaining shaders and the features from ES 2.0. It&#8217;s actually a shame this book never got finished.</p>
<p><a href="http://db-in.com/blog/2011/01/all-about-opengl-es-2-x-part-13/">All About OpenGL ES 2.x</a><br />
Another OpenGL ES 2.0 tutorial, this time by Diney Bomfim. I actually didn&#8217;t find this one <em>as</em> helpful as the others, but I expect everyone learns differently so your mileage my vary. It&#8217;s definitely worth looking at.</p>
<p><a href="https://developer.apple.com/videos/wwdc/2010/">Apple&#8217;s WWDC videos from 2010.</a><br />
You need to log into the developer portal to access them but if you haven&#8217;t seen these yet let me tell you: They are a goldmine. There&#8217;s so much information here about all things iPhone. I hope you have many free hours to watch videos because you won&#8217;t want to stop.</p>
<p><a href="http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/Introduction/Introduction.html">Apple&#8217;s OpenGL ES Programming Guildline</a><br />
This is definitely worth looking through as it has a lot to do with the specifics of the platform. Especially helpful are the tips about optimizing.</p>
<p><a href="http://www.raywenderlich.com/3664/opengl-es-2-0-for-iphone-tutorial">Ray Wenderlich&#8217;s Blog (New!)</a><br />
Ray&#8217;s site is full of great tutorials so if you haven&#8217;t seen it yet be sure to check it out. This one is actually hot off the presses, posted just this week. Again it&#8217;s dealing with mostly ES 2.0 and 3D but covers many topics you&#8217;ll need to learn.</p>
<p>Phew, if those can keep you busy for a while then you have way too much time on your hands!</p>
<h2>OpenGL ES 1.1 vs 2.0</h2>
<p>One topic that&#8217;s going to come up a lot is the difference between OpenGL ES 1.1 and 2.0.  First off the actual difference between the two is that 2.0 has a programable pipeline while 1.1 is a fixed pipeline. If you&#8217;ve read anything about OpenGL already you&#8217;ve probably heard these terms before. The short answer is that in 2.0 you have to write your own shaders while 1.1 uses pre-programmed shaders.  Shaders are functions written in GLSL (GL Shader Language, similar to C) and basically control how things are rendered. If you want a better explanation about what shaders are read Jeff Lamarche&#8217;s blog linked above.</p>
<p>OpenGL 2.0 isn&#8217;t available on the iPhone 3G, only the 3GS and 4. This is a relevant factor though it&#8217;s becoming less relevant every day. I&#8217;m going to be starting out dealing only with ES 1.1. For 2D games the fixed pipeline will be all you need for 90% of what you do (warning: made up statistic).</p>
<p>Here&#8217;s a few examples of the kinds of 2D effects you could do with custom shaders in 2.0:<br />
Depth of field &#8211; Blurring objects in the background<br />
Bloom &#8211; When an intense light source bleeds around edges<br />
Distortion effects &#8211; Ripples, bending<br />
Motion Blur &#8211; Blur from high speed movement<br />
Filters &#8211; Crosshatching, other visual styles<br />
Various lighting and shadow effects</p>
<p>There are definitely some cool things you could do with 2.0 and I suspect I&#8217;ll be upgrading to 2.0 at some point, but again I want to start small and iterate upwards.</p>
<h2>Shades of Gray</h2>
<p>For this project I&#8217;m going to be working on a top down spaceship shooter game. It will be like a bullet hell except the fights will be mostly, if not completely, duels between you and an enemy. The concept of the game is that you live in a colorful world where things that are gray simply disappear. By shooting colored paint at your enemy you can change it&#8217;s color, you need to balance shooting RGB colors to make them Gray and thus disappear! I&#8217;ll be playing around with the actual gameplay during the process.</p>
<p>Hopefully next blog entry I&#8217;ll talk about getting some basic sprites set up and drawn with OpenGL ES 1.1!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/05/getting-started-in-opengl-es/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qualitative Game Design</title>
		<link>http://www.AngryFishStudios.com/2011/05/qualitative-game-design/</link>
		<comments>http://www.AngryFishStudios.com/2011/05/qualitative-game-design/#comments</comments>
		<pubDate>Thu, 12 May 2011 22:43:13 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=344</guid>
		<description><![CDATA[Because sometimes solving a math problem just isn't what you're looking for.]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Lately I&#8217;ve been thinking about game design a lot and what makes good games. Now, as if you couldn&#8217;t tell from the title, this post is going to be pretty subjective so feel free to take anything I say with a grain of salt. As programmers + designer hybrids I think it can be really easy to get too caught up in the implementation of a game rather than the design of it.  Implementation tends to be mostly qantitative in nature, things have health, scores get added, you earn coins, or add time. These all are very important to a game and can take a lot of careful balancing and tuning but rarely do I feel like they are exciting. Having numbers to tweak is great for balancing but one way or another they tend to boil down to formulas and not strategy. In order to obscure these forumlas they are generally made more complex. Complexity is not inherently equal to interesting or fun, there is a difference between an elegantly complex system with meaningful interactions and something that&#8217;s simply complex to for the sake of making it harder to model.</p>
<p style="text-align: left;"><span id="more-344"></span></p>
<p style="text-align: left;">Now I should say that I&#8217;m not afraid of math or anything like that. I play WoW and regularly keep up with the theorycrafting that goes on for that game. The mechanics of combat are extremely complicated to the point where maximizing dps (damage per second) requires full on simulations which can only hope to give a decent statistical model. It&#8217;s this level of complexity I often wonder about, how helpful is it really to the game? It&#8217;s very interesting to &#8220;solve the problem&#8221; but then again is your goal to design a game or a math problem? Now in a lot of ways WoW has improved in this aspect over the years. Tanking and healing are generally much more open for debate about what kind of gear is most beneficial because there are many aspects that depend on simply how one plays. For example: As a healer the amount of mana regeneration you need depends entirely on what spells you cast most often, some spells are slower, cost less and tend to be more proactive while others are fast, expensive and reactive. But alas when it comes to damage dealing there is still generally &#8220;the answer&#8221; that comes up with the highest number for a particular class or spec.</p>
<p>Yet, despite all this, if you ask most players what their favorite move is I suspect it won&#8217;t be some skill with a very high &#8220;quantity&#8221;, be that damage or healing, but it will be a skill or talent with an interesting quality to it.  They are abilities with a &#8220;cool&#8221; factor to them, maybe you can do something no other class can, or maybe it&#8217;s not even combat related like being able to teleport from city to city. Now a game like WoW (and most RPGs) is based around having a very math heavy combat system which begs the question: What would a qualitative combat system look like? It might seem like an odd question, but really we all know the answer:</p>
<p style="text-align: left;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/rock_paper_scissors-250.jpg"><img class="size-full wp-image-345 alignright" title="rock_paper_scissors-250" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/rock_paper_scissors-250.jpg" alt="" width="250" height="249" /></a>Rock, Paper, Scissors is probably one of the simplest qualitative &#8220;combat&#8221; systems. Each choice has a single quality that can vary, its type. It&#8217;s a game that&#8217;s completely deterministic yet in a way it feels random. I&#8217;m sure if you ask the people in the World RPS Society they will assure you there&#8217;s very little luck involved (Yeah, <a href="http://www.worldrps.com/">that exists</a>). RPS is the type of game where you can really form a strategy versus someone. I once intentionally tied my girlfriend 9 times in a row because I could guess what she would do next based on recent results. I just understood how she though strategically. While I don&#8217;t think there&#8217;s much of a market for &#8220;Rock Paper Scissors the RPG&#8221; it&#8217;s an interesting launching point. It could definitely stand to have a little more variation and a little less randomness on the first throw. But again even different profiles of people apparently are more likely to throw different signs (there&#8217;s an <a href="http://dailyinfographic.com/wp-content/uploads/2010/08/How-Do-I-Win-Rock-Paper-Scissors-Every-Time.jpg">infographic!</a>).</p>
<div class="mceTemp mceIEcenter" style="text-align: left;">
<dl id="attachment_346" class="wp-caption aligncenter" style="width: 610px;">
<dt class="wp-caption-dt"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/super-rps.jpg"><img class="size-full wp-image-346" title="super rps" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/super-rps.jpg" alt="" width="600" height="609" /></a></dt>
<dd class="wp-caption-dd" style="text-align: center;">Not quite what I meant&#8230;</dd>
</dl>
</div>
<p style="text-align: center;">
<p>If you really think about it though, most great games of the past don&#8217;t involve much math. While people good at logical thinking undoubtedly had an edge over the years many of the oldest games are about strategy or even luck. Chess is a great example. It&#8217;s widely renown even to this day as being on of the ultimate games for the intelligent but there&#8217;s not a number in sight. In fact each piece on the board only differs in one quality from each other: movement. It doesn&#8217;t take two pawns to take down a rook, or three for a queen. Each piece has the same attacking strength and the same amount of life: 1.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/chess.jpg"><img class="size-full wp-image-350" title="chess" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/chess.jpg" alt="" width="600" height="437" /></a><p class="wp-caption-text">Poor pawns, always left out</p></div>
<p style="text-align: center;">It&#8217;s not just chess either, most games that have lived through the ages have very little to do with numbers. In fact if you look at <a href="http://en.wikipedia.org/wiki/Senet">Senet</a>, <a href="http://en.wikipedia.org/wiki/Go_%28game%29">Go</a>, <a href="http://en.wikipedia.org/wiki/Chess">Chess</a>, and <a href="http://en.wikipedia.org/wiki/Scrabble">Scrabble</a> the game about words and letters is also the one with by far the most math. I find that kind of funny. A lot of it clearly has to do with the improved education of the general public in recent years (recent as in the last century).</p>
<h2 style="text-align: left;">Can&#8217;t We All Just Get Along?</h2>
<div id="attachment_351" class="wp-caption alignright" style="width: 330px"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/Sword-Poker-Straight.jpg"><img class="size-full wp-image-351 " title="Sword-Poker-Straight" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/05/Sword-Poker-Straight.jpg" alt="" width="320" height="480" /></a><p class="wp-caption-text">GAIA&#39;s Sword and Poker</p></div>
<p style="text-align: left;">The two areas of design are by no means mutually exclusive. Take a deck of cards, cards which vary in two qualities. Now I&#8217;m sure there are card games out there that can play out like a game of chess, that is purely strategic, bust most involve randomization and sets. Poker being the classic example. In poker the winner of a hand is decided ultimately by the quality of one&#8217;s hand. This is what brings a lot of interaction to the table, reading your opponent, gauging the strength of your own hand. On the flip side the randomization of the cards and sets of multiple cards bring in statistics: what are the odds of making your hand if you need one card? Two cards? Maybe you&#8217;re going for a flush but could hit a lesser hand as back up?</p>
<p>Going even further are hybrid games like Sword &amp; Poker and Puzzle Quest. These games fully marry the two trains of thought by having classic RPG type stats with highly strategic board/card games in order to make your attacks. One of my favorite qualitative variations to RPGs are elemental types. Using a water type attack on a fire enemy might do double damage but be ineffective against other  water enemies. It&#8217;s extremely flavorful and can add another element of variety to a game but even this can just boil down to be a formula if not handled right.</p>
<p>One thing I want to explore is developing a much less quantitative combat system for an RPG. I know there are tactical RPGs but often I feel like the battles are too drawn out, not the quick duals and encounters in turn based games. It&#8217;s certainly a challenge, if it wasn&#8217;t it would probably be well established already, not to say there aren&#8217;t versions out there.</p>
<h2 style="text-align: left;">Homework:</h2>
<p style="text-align: left;">What are your thoughts? What types of moves do usually like most in RPGs? What&#8217;s your favorite combat system from a game? Leave a comment with your answers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/05/qualitative-game-design/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Adventures in Bitmasking</title>
		<link>http://www.AngryFishStudios.com/2011/04/adventures-in-bitmasking/</link>
		<comments>http://www.AngryFishStudios.com/2011/04/adventures-in-bitmasking/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 21:17:01 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=330</guid>
		<description><![CDATA[I decided to go with a bit of a different format today. I&#8217;m not sure what gave me the idea to make an infographic but I was making a lot of images for the post anyway and I thought &#8220;Hey, why not?&#8221;  Hopefully that image mostly speaks for itself but in case it doesn&#8217;t here&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Bitmask-Infographic.png"><img class="aligncenter size-full wp-image-329" title="Bitmask-Infographic" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Bitmask-Infographic.png" alt="" /></a></p>
<p>I decided to go with a bit of a different format today. I&#8217;m not sure what gave me the idea to make an infographic but I was making a lot of images for the post anyway and I thought &#8220;Hey, why not?&#8221;  Hopefully that image mostly speaks for itself but in case it doesn&#8217;t here&#8217;s a quick rundown of the process:</p>
<p><span id="more-330"></span></p>
<p>In order to know which graphical tile we need to render for a particular space we need to somehow take a look at the spaces around it.  Now this could be accomplished by lots of if or case statements but using a little math it&#8217;s much easier to handle.  We&#8217;re using a 4 bit number to create a hash for each space that identifies what the tiles around it look like. If the space has a value of 14 that means there is no tile above it but one to it&#8217;s left, one to it&#8217;s right and one below it. This will always be the case for a tile of value 14, and all tiles in this situation will have a value of 14. Once we have this value, you know which graphic tile it needs and if you designed your graphics well it will all fit together for any combination. The graphic set I made here is just designed to illustrate which of the 4 sides have a connection and which don&#8217;t.</p>
<h2>Moving to 8 Bit</h2>
<p>This is great for some cases but it can be graphically kind of limiting.  What happens if you care about the corners? Well that&#8217;s what I had to deal with for my digging game.  The graphics for this game are actually inverted from how I drew them on the info graphic because you&#8217;re cutting out tunnels from otherwise solid land.  Luckily we can just use 8 bits (4 for NSEW and 4 for the corners) and have every case available! Now for those of you good at binary math you might have realized that would lead to 256 different combinations! That&#8217;s way too many graphics to make but we can cut it down to 48 unique tiles because not every situation cares about all the corners.  In fact if you just draw some examples out for yourself you&#8217;ll notice that we only care about a corner with both sides adjacent to the corner are empty.  Take a look at this example:</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Tilemap-Corner-Example1.png"><img class="aligncenter size-full wp-image-337" title="Tilemap-Corner-Example" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Tilemap-Corner-Example1.png" alt="" width="600" height="219" /></a></p>
<p>Here you can see how in the first and second pictures you can see how the lower right corner matters for the center piece&#8217;s shape. On the other hand between the second and third picture you can see how the other corners don&#8217;t affect the shape of the center piece at all.  That simplifies from 256 case to just the 48 cases you can see here in my tilemap: (Plus some other tiles for various other things)</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/TileReference1.png"><img class="aligncenter size-full wp-image-318" title="TileReference" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/TileReference1.png" alt="" width="400" height="400" /></a></p>
<p>There&#8217;s still two problems.<br />
1. I made the tilemap art in the way that was easiest from the art side, not the coding side or the order is all over the place.<br />
2. We need to somehow map the 256 possibilities to the correct 48 graphic values.</p>
<p>Both of these problems can be dealt with at the same time by using a look-up table.  The job of this look-up table is to map from 0-255 -&gt; 0-47 depending conditionally on the corner pieces. You can implement this however you want, probably an array where the indexes 0-255 correspond to the result of the bitmasking and it spits out the graphic tile value 0-47.  So, first lets talk about the bitmask we&#8217;re going to use for the 8-bit case.</p>
<p><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/8Bit-Masking.png"><img class="aligncenter size-full wp-image-334" title="8Bit-Masking" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/8Bit-Masking.png" alt="" /></a></p>
<p>The way I&#8217;ve broken it up is so if you just look at the non-corner bits (4 most significant) you&#8217;ll get a base case, then you add the corner case to it and you end up with a unique value. This makes it easier to come up with the look-up table because the non-corner cases are largely what defines the tile&#8217;s shape and they will be next to each other.  Next I made a table which defined how all 256 values translate:</p>
<p><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Tilemap-Lookup.png"><img class="aligncenter size-full wp-image-335" title="Tilemap Lookup" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Tilemap-Lookup.png" alt="" /></a></p>
<p>You can see how some bits have an X instead of 0 or 1. These are the corners that don&#8217;t matter for that particular base case.  The &#8220;Lower Bits Sum&#8221; column shows all values that row accounts for when you do all combinations of 0 and 1 for any x&#8217;s.  Hopefully this table makes sense, the first 4 numbers (including x&#8217;s) give the 0-256 value that results from bitmasking and the final value column is the index on the tileset graphic I posted above.  You can see they are all out of order because like I said I made them before really thinking about this.</p>
<p>Hopefully this helps people if you need to use something like this in the future. It&#8217;s not too complicated once you lay it all out and it&#8217;s much easier and cleaner than having all kinds of branching and crazy logic in your code.</p>
<h2>Beta testing</h2>
<p>The mole digging game I&#8217;m making is almost ready to have people start beta testing. It&#8217;s very much a prototype at the moment, the core functions are mostly in there but there&#8217;s no real aspects to make it a game at this point, I suppose it&#8217;s a mole digging simulation.  I want to start getting feedback early and try to be really iterative in the game design process so if you want to help follow this link to sign up on testflight:</p>
<p>(Edit: I took the link out because I&#8217;m pretty sure bots were spamming it. If you&#8217;re interested e-mail me)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/04/adventures-in-bitmasking/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tile Map Using CoreAnimation</title>
		<link>http://www.AngryFishStudios.com/2011/04/tile-map-using-coreanimation/</link>
		<comments>http://www.AngryFishStudios.com/2011/04/tile-map-using-coreanimation/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 05:54:19 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=319</guid>
		<description><![CDATA[This week I&#8217;m going to talk about how I implemented a tilemap in Objective-C using CoreAnimation. I&#8217;d like to take the time to once again say that this code is definitely not optimized so your milage may vary. It&#8217;s funny because a tile map in some ways feels like a very dated beast. I suppose [...]]]></description>
			<content:encoded><![CDATA[<p>This week I&#8217;m going to talk about how I implemented a tilemap in Objective-C using CoreAnimation. I&#8217;d like to take the time to once again say that this code is definitely not optimized so your milage may vary. It&#8217;s funny because a tile map in some ways feels like a very dated beast. I suppose in a lot of ways it is, but it definitely has a unique feel that can give a very nostalgic vibe. Much in the same way a physical oil painting can compare to digital paintings.  But enough about why you might want to use a tile map, I&#8217;m sure you already have strong feelings for them one way or another.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/ShhA0eM3JCc?hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/ShhA0eM3JCc?hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><span id="more-319"></span></p>
<p>In case you haven&#8217;t seen in, there&#8217;s an alpha video of the latest game I&#8217;m working on. It&#8217;s a 2D sidescroller digging game and it uses a tile map for levels. I tried to keep a very MVC friendly approach when implementing my tile map. The basic way it works is that you have a model class which stores the value determining which square each tile should have. Below you can see my tile map with the values overlaid on top of them. I&#8217;m not going to talk about the model side very much here because you can implement it however you want, 2d array, dictionary, etc. I used a dictionary with the keys being a simple hash made from the X and Y coordinates, eg. &#8220;X6Y10&#8243;</p>
<p><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/TileReference1.png"><img class="aligncenter size-full wp-image-318" title="TileReference" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/TileReference1.png" alt="" /></a></p>
<p>For the view portion of the system there are two parts: Tiles and the Tile Map. The Tiles are very similar to the AFSprite class I talked about <a href="http://www.angryfishstudios.com/2011/04/sprites-using-only-coreanimation/#more-308">last post</a> so definitely head over there if you haven&#8217;t read it already.  Each tile basically works the same way the sprite did to only show one of the tiles from the tile set above based on the index specified.</p>
<pre lang="objc">
+ (id) tileWithTexture:(NSString *)texture {
	return [[[AFTile alloc] initWithTexture:texture] autorelease];
}

//Initializes the texture for the image with some basic properties
- (id) initWithTexture:(NSString*)texture {
	self = [super init];
	if (self) {
		UIImage *tileset = [UIImage imageNamed:texture];
		self.contents = (id)(tileset.CGImage);
		textureWidth = tileset.size.width;
		textureHeight = tileset.size.height;
		tileWidth = 32;
		tileHeight = 32;
		index = -1;
	}
	return self;
}

#pragma mark Sprite Stuff

//Update the display on changes to properties
+ (BOOL) needsDisplayForKey:(NSString *)key {
	if ([key isEqualToString:@"index"] || [key isEqualToString:@"tileWidth"] || [key isEqualToString:@"tileHeight"]) {
		return YES;
	}

	return [super needsDisplayForKey:key];
}

- (void) display {
	//Set the boundries to show the specified tile
	self.bounds = CGRectMake(0,0,tileWidth,tileHeight);

	//Converting the linear index to X Y coordinates
	int x = (index % (textureWidth/tileWidth)) * tileWidth;
	int y = floor((double)index / (textureWidth/tileWidth)) * tileHeight;

	//[0,1] values for the position and width
	self.contentsRect = CGRectMake((float)x/textureWidth, (float)y/textureHeight, (float)tileWidth/textureWidth, (float)tileHeight/textureHeight);

	(index < 0) ? [self setHidden:YES] : [self setHidden:NO];;
}

- (id <CAAction>) actionForKey:(NSString *)key {
	//if ([key isEqualToString:@"bounds"]||[key isEqualToString:@"position"])
		return nil;
	//return [super actionForKey:key];
}

#pragma mark setters

//Set needs display when the index changes
- (void) setIndex:(int)i {
	index = i;
	[self setNeedsDisplay];
}

//Or the width
- (void) setTileWidth:(int)width {
	tileWidth = width;
	[self setNeedsDisplay];
}

//Or the height
- (void) setTileHeight:(int)height {
	tileHeight = height;
	[self setNeedsDisplay];
}
</pre>
<p>As I said most of this should make sense if you read my last post. The next class is the tile map which holds a bunch of tiles and displays the portions of the model that are viewable on screen.  I like to think of it as a lens in a way, when you hold it over the model it shows the images of the appropriate tiles. Now one option is to use a static grid of tiles that never move. In this case the minimum movement of the background would be one full tile width or height. This is a totally legitimate option and can really simplify things. I&#8217;d recommend thinking about whether or not it could work for you. But for my case I want the world to scroll smoothly as the character moves around.</p>
<p>Now depending on the size of the world you&#8217;re talking about maybe you can just create a tile instance for each coordinate of your world. Perhaps you&#8217;re making a Bomberman style game and you only need the arena slightly larger than the screen. That might work but for my game I don&#8217;t even know how big the levels are going to be but I want to keep my options open incase I go with &#8220;BIG&#8221;. At some point creating a tile for each coordinate of the world just isn&#8217;t going to be feasible anymore. So I leaned towards something I&#8217;ve used a lot during iOS development: Tables.  The UITableView work really well at handling indefinitely long list and in my opinion is implemented pretty well. Tables are so versatile they&#8217;re used often when you can&#8217;t tell something is a table.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/1YmWuqCoMmI?hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/1YmWuqCoMmI?hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>I made this quick little video to hopefully help people visualize what&#8217;s going on. Basically I make one screen worth of tiles then reuse them when they get scrolled off screen to avoid having to make new instances.  It&#8217;s just like a 2D table.  Actually I make an extra 1 tile border around the screen&#8217;s worth of tiles just to help prevent any flickering on the edges before the reused tiles are there.</p>
<pre lang="objc">
+ (id) tilemapFromModel:(AFLevelModel*)model {
	return [[[AFTileMap alloc] initFromModel:model] autorelease];
}

- (id) initFromModel:(AFLevelModel*)model {
	self = [super init];
    if (self){
		self.texture = [model tileset];
		self.tileWidth = [model tileWidth];
		self.tileHeight = [model tileHeight];
		self.mapModel = model;

		visibleTiles = [NSMutableSet new];
		recycledTiles = [NSMutableSet new];
		tilesByCoord = [NSMutableDictionary new];
		self.frame = CGRectMake(0, 0, self.tileWidth*[model mapWidth], self.tileHeight*[model mapHeight]);
	}
	return self;
}
</pre>
<p>The initialization is pretty straight forward. There are two NSMutableSet&#8217;s which will hold the tiles.  The tilesByCoord dictionary is one of the very unoptimized parts of this code currently as I needed a faster way to be able to locate a specific tile based on its X,Y coordinates and sets have no order or keys inherently to them. tilesByCoord and visibleTiles will get combined at some point.</p>
<pre lang="objc">
- (void) updateTileAtCoord:(AFCoord*)coord {
    //update the tile
    [[tilesByCoord objectForKey:[NSNumber numberWithInt:10000*coord.x+coord.y]] setIndex:[self.mapModel getValueForTileAt:coord]];
}
</pre>
<p>This method is for changing a specific tile called when the model changes. You can see the tilesByCoord dictionary stores each tile with an NSNumber key based off its X,Y coordinates. This is one of the latest things I&#8217;ve added and the reason why I needed to be able to locate the tile via X,Y. Tiles don&#8217;t change often so this targeted approach seemed to give the best performance while not taking a lot of implementation time (Something that&#8217;s important when working on a game solo as a side project to a 40h a week job!).</p>
<pre lang="objc">
- (void) configureTile:(AFTile*)tile forCoord:(AFCoord*)coord {
    //Sets the properties for the new/reused tile
	[tile setPosition:CGPointMake((coord.x+0.5)*tileWidth,(coord.y+0.5)*tileHeight)];

	[tile setTileWidth: tileWidth];
	[tile setTileHeight:tileWidth];
	[tile setCoord:coord];
	[tile setIndex: [self.mapModel getValueForTileAt:coord]];
}
</pre>
<p>This method sets up new tiles once their created. Everything is pretty self explanatory here I think. AFCoord is a simple class made to basically wrap an X,Y coordinate and provide a few methods commonly used with them. It&#8217;s an interesting discussion of whether something as small as this should just be a struct but that&#8217;s a discussion for another post. I&#8217;ve stated before the approach I&#8217;m taking with this project is to default every thing to Objective-C and then go back and change things that need to be changed once things are implemented and profiled.</p>
<pre lang="objc">
- (AFTile*) dequeueRecycledTile {
	//Grab an object from the recycled tiles and return it (Or nil if none)
	AFTile* recycledTile = [recycledTiles anyObject];
	if (recycledTile) {
		[[recycledTile retain] autorelease];
		[recycledTiles removeObject:recycledTile];
	}
	return recycledTile;
}
</pre>
<p>This method grabs any object from the recycledTile&#8217;s set and returns it. All the tiles in recycledTiles are offscreen and up for grabs, we don&#8217;t care which one it is. The [[recycledTile retain] autorelease] line is there to prevent the object from having a retain count of 0 after it&#8217;s removed from the set while also making it so we don&#8217;t have to worry about releasing it somewhere later.</p>
<pre lang="objc">
- (id <CAAction>) actionForKey:(NSString*)key {
	return nil;
}
</pre>
<p>You&#8217;ve seen this before, it&#8217;s just to disable the implicit animations CALayer provides for us.</p>
<p>So now for the meat of the class:</p>
<pre lang="objc">
//Update the tiles to the new position.
- (void) updateTiles {

	//Find the XY ranges visible
	CGRect visibleBounds = self.superlayer.bounds;
	visibleBounds = CGRectInset(visibleBounds, -tileWidth, -tileHeight); //Buffer of one tile around the outside
	int minX = (int) floorf( visibleBounds.origin.x / tileWidth);
	int maxX = (int) floorf((visibleBounds.origin.x + visibleBounds.size.width) / tileWidth);
	int minY = (int) floorf( visibleBounds.origin.y / tileHeight);
	int maxY = (int) floorf((visibleBounds.origin.y + visibleBounds.size.height) / tileHeight);

	//Remove offscreen tiles
	for (AFTile *tile in visibleTiles) {
		if (!CGRectIntersectsRect(visibleBounds, tile.frame)) {
			//The quite literal corner case (And edge case)
			if (CGRectGetMinX(visibleBounds) != CGRectGetMaxX(tile.frame) &#038;&#038;
				CGRectGetMinY(visibleBounds) != CGRectGetMaxY(tile.frame) &#038;&#038;
				CGRectGetMaxX(visibleBounds) != CGRectGetMinX(tile.frame) &#038;&#038;
				CGRectGetMaxY(visibleBounds) != CGRectGetMinY(tile.frame)) {

				[recycledTiles addObject:tile];
				[tile removeFromSuperlayer];
				[tilesByCoord removeObjectForKey:[NSNumber numberWithInt:tile.coord.x*10000+tile.coord.y]];
			}
		}
	}

	//Remove them from visible set
	[visibleTiles minusSet:recycledTiles];

	for (int i = minX; i <= maxX; i++) {
		for (int j = minY; j <= maxY; j++) {
            //Coord for the location
   			AFCoord *tileLocation = [AFCoord coordWithX:i andY:j];

            //Check if the tile is displayed already
			if ([tilesByCoord objectForKey:[NSNumber numberWithInt:10000*i+j]] == nil) {
                //Dequeue a tile or create a new one if none are available
				AFTile *newTile = [self dequeueRecycledTile];

				if (newTile == nil) {
					newTile = [AFTile tileWithTexture:texture];
				}

				[self configureTile:newTile forCoord:tileLocation];
				[self addSublayer:newTile];

				[visibleTiles addObject:newTile];
				[tilesByCoord setObject:newTile forKey:[NSNumber numberWithInt:10000*i+j]];
			}
		}
	}

}
</pre>
<p>Lets start from the top and work our way through it. The first chunk of code is some math to determine what portion of the world is visible on the screen and also convert that to the tile space. Note the Inset of negative tileWidth and tileHeight, this adds that one tile border I mentioned earlier. Next we remove any tiles that aren't on screen. Each tile is compared with the screen to see if it's still there. If it's not we add the tile to the recycledTiles set marking that it's offscreen and ready to be reused. Now you might ask why I'm doing a set subtraction after the loop instead of removing it from the set individually like I do with the tilesByCoord dictionary. The answer to that lies in the for loop. We're iterating through the objects in visibleTiles so we don't want to modify visibleTiles within the loop or bad things can happen.</p>
<p>Next there's a 2d loop which loops through the visible X,Y coordinates at the beginning of the method. Now for each coordinate it checks if a tile is being displayed for that coordinate, if there isn't it first requests a dequeued tile. If no dequeued tile was supplied, e.g. when the tile map is first created, it will make a new one. Either way this tile gets configured and added to the layer.</p>
<p>It's pretty simple when you break it down into individual tasks, but there's still plenty of room for improvement. For one the visibleTiles and tilesByCoord are redundant and need to be combined. Second, it's probably not necessary to loop through all the coordinates and check them individually when I'm looping through visible tiles earlier in the method. One idea is to keep a cache of the coordinates of tiles that are still visible when I remove offscreen tiles. Then I can only loop through the coordinates that need tiles instead of going through all of them. Either way I'm not going to worry about it too much until I get it more complete and profile it. It seems to be running fine for now.</p>
<p>Not sure what the topic for next blog will be but be sure to check back in two weeks to find out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/04/tile-map-using-coreanimation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sprites using only CoreAnimation</title>
		<link>http://www.AngryFishStudios.com/2011/04/sprites-using-only-coreanimation/</link>
		<comments>http://www.AngryFishStudios.com/2011/04/sprites-using-only-coreanimation/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 04:33:13 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=308</guid>
		<description><![CDATA[Today I&#8217;m going to talk about the development of my likely to be next released game codenamed Mitch Digger. First I want to talk about something I think can be one of the biggest problems for an independent developer: Too many technologies! While it&#8217;s a great thing in general I think it can both be [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;m going to talk about the development of my likely to be next released game codenamed Mitch Digger.  First I want to talk about something I think can be one of the biggest problems for an independent developer: Too many technologies!  While it&#8217;s a great thing in general I think it can both be overwhelming and potentially waste a lot of time just learning new technologies.  Look at developing for iOS alone. In the process of deciding to work on a platformer I looked into cocos2d, openGL ES, corona, unity and more. Deciding on any one resulted in trade offs; Time to learn, capabilities, ease of use.  In every case I felt like I was making the wrong choice.  In the end I decided for now I&#8217;m going to stick with what I know already and see if it was really possible to make a game in just CoreAnimation.</p>
<p><span id="more-308"></span></p>
<p>Random aside: I used to build combat robots as a hobby and there was one guy who claimed you could build anything with just a drill, a hack saw and enough ingenuity. He knew this because he did! And these weren&#8217;t poorly built either, they were better than most of the robots built by people with poor craftsmanship and better tools.  The moral of the story is don&#8217;t get too caught up in tools.</p>
<p>With that decision hammered out of the way I started to work on the game. I knew what the game would be already, it&#8217;s something I&#8217;ve wanted to make for a while and first proposed it for the 360iDev Game Jam with some concept art. I made up some art first because I&#8217;m backwards like that. For me the art is easier to get done and it also serves to give me a lot of motivation. If I have some great art done it will really help me envision the game and keep me working on it.</p>
<p>Ok so, 2D platformer huh? Where to start? Well the first question is whether or not I could even make it work in CoreAnimation. What would I need for a platformer? In my mind, two things: Animated Sprites and a Tilemap.  So that&#8217;s where I started. Today I&#8217;m going to talk about the sprite class I made and how it works.  Fair warning: I&#8217;m by no means the best programmer and this code is by no means optimized.  The concept of avoiding premature optimization makes a lot of sense to me so that&#8217;s what I&#8217;m working with. Once I have a game running I&#8217;ll go back, profile and improve what needs to be improved to make it work on older devices. My I have a BS in electrical engineering and a BA in studio art so my programming is mostly self taught.  I provide the following code with no claims of its superiority.</p>
<pre lang="objc">- (id) initWithName:(NSString *)sprite {
    self = [super init];
	if (self) {
		//The name of the file .png, @2x.png, and .plist files
		[self setSpriteName:sprite];
	}

	return self;
}

+ (id) spriteWithName:(NSString *)sprite {
	return [[[AFSprite alloc] initWithName:sprite] autorelease];
}</pre>
<p>Here we have some basic initialization stuff. My sprite is a subclass of CALayer with my custom methods and overrides to give it some basic &#8220;sprite&#8221; functionality. I&#8217;ve been making my spritesheets in zwoptex so it expects there to be a zwoptex png output (also 2x) and a zwoptex plist file. I just use one plist for the normal and 2x sizes but care must be taken to make sure they are exactly the same. Make sure the padding on the 2x is twice the padding on the 1x and for now I&#8217;ve been making sure the images are untrimmed because that has been throwing them off. I&#8217;ll probably try to streamline that process a bit in the future.</p>
<pre lang="objc">#pragma mark loadAnimation

- (void) setAnimation:(NSString*)animation fromPlist:(NSString*)file forKey:(NSString*)key {

	//If not the current animation clear the current then add it
	if (![currentAnimation isEqualToString:animation]) {

		//Clear the current animation
		[self removeAllAnimations];

		NSString* animationPath = [[NSBundle mainBundle] pathForResource:file ofType:@"plist"];
		NSDictionary* animationDict = [NSDictionary dictionaryWithContentsOfFile:animationPath];

		NSMutableArray *frames = [[animationDict objectForKey:animation] mutableCopy];
		if (frames){
			float duration = [[frames lastObject] floatValue];
			[frames removeLastObject];

			CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"spriteFrame"];
			[keyframeAnimation setValues:frames];
			[keyframeAnimation setDuration:duration];
			[keyframeAnimation setRepeatCount:HUGE_VAL];
			[keyframeAnimation setCalculationMode:kCAAnimationDiscrete];

			[self addAnimation:keyframeAnimation forKey:key];
			currentAnimation = animation;
		}

        [frames release];
	}
}</pre>
<p>This is what I&#8217;m using to animate the sprites. I create a plist for each different type of sprite there is. These each contain a dictionary with the keys being names of various animations, &#8220;stand&#8221;, &#8220;walk&#8221;, &#8220;jump&#8221;, etc. The value for each of those keys is a series of frames and the amount of time each one should display for like so:</p>
<p><img class="aligncenter size-full wp-image-302" title="Screen shot 2011-04-01 at 12.05.17 AM" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/04/Screen-shot-2011-04-01-at-12.05.17-AM.png" alt="" /></p>
<p>This method grabs those frames and creates a keyframe Animation to loop between them at the desired frequency.  Looking at this function it&#8217;s likely I should be caching the dictionary of animations instead of loading it from file each time but this is the kind of thing I&#8217;ll go back and profile before I worry about it.</p>
<pre lang="objc">#pragma mark Setters

- (void) setSpriteName:(NSString *)sprite {
	//retain the new release the old
	[spriteName release];
	spriteName = [sprite retain];

	//Load the new sprite image file in
	[self setContents: (id)([UIImage imageNamed:[sprite stringByAppendingString:@".png"]].CGImage) ];

	//Get the sprite attributes from the plist
	NSString* zwoptexPath = [[NSBundle mainBundle] pathForResource:self.spriteName ofType:@"plist"];
	NSDictionary *zwoptexDict = [NSDictionary dictionaryWithContentsOfFile:zwoptexPath];
	NSString* sizeString = [[zwoptexDict objectForKey:@"metadata"] objectForKey:@"size"];

	self.attributesDict = zwoptexDict;

	//Set the texturesize to the full texture
	sizeString = [sizeString stringByReplacingOccurrencesOfString:@" " withString:@""];
	sizeString = [sizeString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"{}"]];

	NSArray *sizeArray = [sizeString componentsSeparatedByString:@","];

	self.textureSize = CGSizeMake([[sizeArray objectAtIndex:0] intValue],
								  [[sizeArray objectAtIndex:1] intValue]);

	//Load all the frames into a better dictionary for reference
	NSDictionary *sourceFramesDict = [self.attributesDict objectForKey:@"frames"];
	self.framesDict = [NSMutableDictionary dictionary];

	for (NSString *singleFrameKey in sourceFramesDict) {
		NSDictionary *singleFrame = [sourceFramesDict objectForKey:singleFrameKey];

		NSString *textureString = [singleFrame objectForKey:@"textureRect"];
		textureString = [textureString stringByReplacingOccurrencesOfString:@"{" withString:@""];
		textureString = [textureString stringByReplacingOccurrencesOfString:@" " withString:@""];
		textureString = [textureString stringByReplacingOccurrencesOfString:@"}" withString:@""];
		NSArray *strings = [textureString componentsSeparatedByString:@","];

		int originX = [[strings objectAtIndex:0] intValue];
		int originY = [[strings objectAtIndex:1] intValue];
		int sizeWidth = [[strings objectAtIndex:2] intValue];
		int sizeHeight = [[strings objectAtIndex:3] intValue];

		[self.framesDict setValue:[NSValue valueWithCGRect:CGRectMake(originX, originY, sizeWidth, sizeHeight)] forKey:singleFrameKey];
	}
}</pre>
<p>This one is a little messy, but it&#8217;s for changing the sprite.  This gets called upon initilization and if you wanted to change the sprite file (though I doubt that will happen often). The first thing it does is set the contents of the CALayer, as you&#8217;ll see later we change the bounds to limit it to only show one of the sprite frames at a time instead of the whole sheet. Next it loads the dictionary of the frame information from zwoptex&#8217;s plist. This is what it uses to figure out where each frame lies on the sheet. I store the full size of the texture because later I have to reference things in a [0,1] proportional way instead of by points or pixels. The last part is just soring things more directly in a dictionary instead of as strings. zwoptex stores the information in formats like &#8220;{ X, Y }&#8221; and I&#8217;ll be needing to access those values constantly so this results in some processing savings by not doing it over and over again. (This is a case where I did profile it already and sped things up).</p>
<pre lang="objc">#pragma mark SpriteEnabling

+ (BOOL) needsDisplayForKey:(NSString*)key {
	//If the spriteFrame changes redisplay the sprite
	if ([key isEqualToString:@"spriteFrame"])
		return YES;
	return [super needsDisplayForKey:key];
}</pre>
<p>This makes the CALayer set the needDisplay property whenever the spriteFrame changes. This will cause it to actually call the display method where we can actually change which frame is being displayed.</p>
<pre lang="objc">//Used to change the frame when updating the sprite
- (void)display {
	//Get the current frame that's being displayed
	NSString* currentSpriteFrame = ((AFSprite*)[self presentationLayer]).spriteFrame;

	if (!currentSpriteFrame)
		return;

	[self changeSpriteFrame:currentSpriteFrame];
}</pre>
<p>Display is the meat and potatos. This is what gets called whenever the image being displayed needs to be updated. The reason we need to grab the current frame from the presentation layer is because of how animations work. When you create an animation for some property on a layer that property is going to have either the initial value or the final value depending on how the animation got created. The presentation layer is where the animation actually &#8220;happens&#8221; this is where the value gets changed each time the animation ticks, thus if we grab the frame from the presentation layer it contains whichever frame should be showing [i]right now[/i]. Once we have that we call the next method&#8230;</p>
<pre lang="objc">- (void)changeSpriteFrame:(NSString *)frameString {

	CGRect frameBounds = [[self.framesDict valueForKey:[frameString stringByAppendingString:@".png"]] CGRectValue];

	//Set the bounds and contents rec to the frame on the texture
	self.bounds = CGRectMake(0,0,frameBounds.size.width,frameBounds.size.height);
	self.contentsRect = CGRectMake(frameBounds.origin.x   /textureSize.width,
								   frameBounds.origin.y   /textureSize.height,
								   frameBounds.size.width /textureSize.width,
								   frameBounds.size.height/textureSize.height);

}</pre>
<p>This method changes the actual portion of the spritesheet being displayed. The frame bounds is the rectangle on the spritesheet we want to display. We set the width and the height on the bounds equal to the point value width and height of the sprite.  Then the contentsRect is a rectangle defined in &#8220;unit space&#8221; which is the portion of the full image we want to draw. Thus for x and y: [0,0] would be the top left and [1,1] would be the bottom right. And for width and height: [0.5,0.5] one quarter of the total image (half width * half height) and [1,1] would be the full image.</p>
<pre lang="objc">//Used to disable the animating of the change of contentsRect on the "texture"
+ (id )defaultActionForKey:(NSString *)aKey;
{
	//If contentsRect is being changed, do nothing instead
    //if ([aKey isEqualToString:@"contentsRect"] || [aKey isEqualToString:@"bounds"])
        return (id )[NSNull null];

   // return [super defaultActionForKey:aKey];
}</pre>
<p>Finally this just disables all the implicit animations that CALayers normally have. They&#8217;re a great feature, but when animating at 30-60FPS you don&#8217;t want things animating, you just want them to instantly change.</p>
<p>And that&#8217;s it! And here it is in action:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/ShhA0eM3JCc?hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/ShhA0eM3JCc?hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>You can see in that video that it seems entirely possible to make a simple platformer in CoreAnimation.  The red box is the collision rect for Mitch and the blue box is the last tile collsion that was checked. Also ignore the fact that I appear to suck at playing my own game, it was hard playing and recording at the same time! That being said I think the 2 buttons + tilt controls works very well for a platformer, it feels really intuitive when playing and like I said isn&#8217;t anything like I make it look in this video.</p>
<p>In two weeks I&#8217;ll be talking about how I did the tilemap and hopefully have some more gameplay progress to show. My homework until then: Think of a name&#8230; why is that always the hardest part?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/04/sprites-using-only-coreanimation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thoughts from PAX East.</title>
		<link>http://www.AngryFishStudios.com/2011/03/thoughts-from-pax-east/</link>
		<comments>http://www.AngryFishStudios.com/2011/03/thoughts-from-pax-east/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 02:00:15 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=276</guid>
		<description><![CDATA[This past weekend was PAX East in Boston and at the last minute I decided to go. I think it was jealousy from hearing about everyone on twitter talking about GDC but I figured I should take advantage of the fact that I live about a half hour from Boston.  PAX was, in one word, [...]]]></description>
			<content:encoded><![CDATA[<p>This past weekend was PAX East in Boston and at the last minute I decided to go. I think it was jealousy from hearing about everyone on twitter talking about GDC but I figured I should take advantage of the fact that I live about a half hour from Boston.  PAX was, in one word, excellent. The one downside it had was that it was packed. I think I read somewhere that over 3 days there were around 70,000 people there. Thats a lot of gamers! The venue was nice and big so it didn’t really feel that packed inside the expo floor but the lines, oh the lines.  At any given time there were talks going on about all kinds of topics: Games, dev, writing, media, communities, etc, and each one would have a line form up before it.  Most of the talks reached capacity in the line well before the start of the talk, I didn’t even try to make it to most of the main events. What I did want to go there for were several talks being held by the IGDA in a room called the IGDA Dev Center.  One thing, this room held 80 people. Thats right, 80. Eighty people in an event where there’s several thousand at any given time is leaning towards the ridiculous side of things but luckily for me I caught on to this and got there plenty early making it to most of the talks I wanted to go to.<br />
<span id="more-276"></span><br />
<strong>There’s a whole other world out there</strong></p>
<p>Lately I’ve been focusing so much on iOS I’ve almost forgotten about other consoles.  I’ve been on sites like TouchArcade.com and gearing up for games like <a href="http://www.caseyscontraptions.com/">Casey’s Contraptions</a> but there’s so much more out there. I do love how accessible the iOS app store is to developers, and I really hope this is a trend that continues making it easier to release games on all kinds of platforms.</p>
<p>Some of the most exciting things for me at PAX:</p>
<ul>
<li>Battleblock Theater (A new game by Behem0th if you haven’t seen the <a href="http://www.youtube.com/watch?v=AL-25TrqEOY">opening</a> yet check it out, it’s hilarious )</li>
<li>Portal 2</li>
<li>Duels of the Planeswalkers 2012 (Single Player MTG game)</li>
<li>Starwars: The Old Republic</li>
<li>Pokemon TCG Online (I’m a sucker for TCGs, I’ll play the single player probably)</li>
<li>The Nintendo 3DS&#8230;..</li>
</ul>
<p>Which leads me to a brief tangent. I don’t like the whole 3D trend.  I’ve tried it, It seems like it only has gimmick value.  In my opinion it plays out in two ways: It’s badly done and thus distracts from the film or it’s done well and you stop noticing it after your eyes adjust defeating the purpose. The best argument I’ve heard on the subject, though I can’t remember who wrote it, said that: Movies (and games) are already three dimensional, when you see a Train go off into the distance you don’t say “Oh that train is shrinking”.  I imagine when I play games on the 3DS I’ll just turn the 3D off, new Zelda, new Mario? Lets be honest I will. The one thing I am impressed by is the lack of glasses, if you’re going to do it that’s how to do it right.</p>
<p>Ok aside over.</p>
<p>So yeah, it’s easy to lose track of all the other aspects of gaming when focusing on mobile games so much but it’s important to keep track of your roots and the things you love.</p>
<p><strong>What it means to touch</strong></p>
<p>One of the best talks I went to was pretty directly related to mobile gaming. It was by Grant Shonkwiler (<a href="http://twitter.com/#!/g_shonk">@g_shonk</a>) who’s a game designer at Megatouch Games in PA.  Megatouch is a company that makes those bar top game systems in, well, bars.</p>
<p>I think controls are arguably the most important aspect of a game. Having great controls can make a game feel really intuitive and help lessen the amount of explaining someone needs. Where as bad controls and make it hard to understand what’s going on, frustrating or just clunky. Lets look at the tools of the trade on the iPhone:</p>
<p>Touch:</p>
<p>Most commonly used for buttons, simple single taps can be really great but they are also the most abused.  We’ve all seen console ports with an on screen controller and personally I hate them.  They have two major flaws. 1) Your fingers block the screen, I have pretty small hands compared to some people and it can be pretty bad for me. 2) The lack of physical feedback. For buttons this isn’t so bad but I absolutely hate a d-pad or joystick on screen. So how do you use touch right? Well for starters touch is great for clicking on specific things, when you tap an item in your inventory, you know they wanted something to do with that item. I do think it’s important to not overload the user with choices though. When at all possible, I think simpler is better.</p>
<p>Double Touch:</p>
<p>Using two finger taps is a great way to differentiate some action from another without overloading the screen with different buttons.  Maybe to move a character you tap but to attack you tap with two fingers. This is something I think is underused a lot right now and I want to look into integrating it more into my games.</p>
<p>Gestures:</p>
<p>Gestures are great for commands. This is another area where I feel like there’s a lot of room to grow.  I know there are some games out there that do this (<a href="http://itunes.apple.com/us/app/infinity-blade/id387428400?mt=8">Infinity blade</a> for one) but I really think this is a way mobile devices can really take advantage of the format and really break out.  It can get kind of chaotic if you have to make commands too often so I think it’s important to keep a balance.</p>
<p>Multitouch:</p>
<p><a href="http://twitter.com/#!/g_shonk">@g_shonk</a> made a great point about how few games out there use multitouch correctly. Multitouch should be used for two actions that have to be done at the same time not things that can be done sequentially.  He pointed out that <a href="http://itunes.apple.com/us/app/cut-the-rope/id380293530?mt=8">Cut the Rope</a> is a great example of how it should be used. There are times you have to cut two ropes at the same time and there’s no way to do it with just one finger.</p>
<p>Acceleration:</p>
<p>This is something that’s seen a good amount of use already there are tons of games out there that use tilt controls. One of my favorites is <a href="http://itunes.apple.com/us/app/tilt-to-live/id335454448?mt=8">Tilt to Live</a>, a game that is really fast paced but still manages to keep really fine control possible to weave in an out of the waves of evil red dots. I think tilt controls are really useful for platformers and side scrollers too. <a href="http://itunes.apple.com/us/app/hoggy/id338547319?mt=8">Hoggy</a> is a pretty great example of a platformer that just feels good on the iPhone if you haven’t played it I recommend checking it out.</p>
<p>Common Pitfalls</p>
<p>The biggest area of fail when it comes to touch controls is the problem of covering the screen. It’s a fine balance between interacting with the screen and getting visual information from it. <a href="http://itunes.apple.com/us/app/battleheart/id394057299?mt=8">Battleheart</a> is a game I love, but after you get a bunch of skills for each of the four characters it can get pretty chaotic and you have to keep pushing skills and dragging party members around, most of the time your hand is covering the screen. There’s a couple ways you can deal with this: First don’t put buttons on the top of the screen. As Grant pointed out in his talk <a href="http://itunes.apple.com/us/app/plants-vs-zombies/id350642635?mt=8">Plants vs Zombies</a> did this right on their iPhone port of the game. Originally the plant buttons were on the top, but on the iPhone they are on the left. Second, limit the amount you have to be touching things on the screen. If you have to make a gesture/tap/selection per attack consider having half as many attacks for twice the damage, it won’t slow the pace of the game down but it slow the flow of input you have to supply.</p>
<p>Overall Im looking forward to all the new innovative ways people keep finding for pushing the boundaries on controls.  Next time you’re working on a game think if there’s a way you can make your controls more innovative and intuitive.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/03/thoughts-from-pax-east/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Buffet of Thoughts</title>
		<link>http://www.AngryFishStudios.com/2011/03/a-buffet-of-thoughts/</link>
		<comments>http://www.AngryFishStudios.com/2011/03/a-buffet-of-thoughts/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 20:23:51 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Tripolar]]></category>
		<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=213</guid>
		<description><![CDATA[I know I&#8217;m probably unknown to most of you so I wanted to do an intro post but with the two week rotation of iDevBlogADay I feel like it would be a bit unfulfilling. So what I&#8217;ve decided to do is well… both. The first half of this entry is going to be about me [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">
<p style="text-align: left;">I know I&#8217;m probably unknown to most of you so I wanted to do an intro post but with the two week rotation of <a href="http://www.iDevBlogADay.com" target="_blank">iDevBlogADay</a> I feel like it would be a bit unfulfilling. So what I&#8217;ve decided to do is well… both.  The first half of this entry is going to be about me and Angry Fish Studios. The second half is going to be about using Illustrator&#8217;s Recolor Artwork feature. Let&#8217;s dive right in.</p>
<h2 style="text-align: left;">Angry Fish &#038; Me</h2>
<p style="text-align: left;">Who am I?</p>
<p style="text-align: left;">Well, my name is Alex and along with my long time friend Joe I started Angry Fish Studios.  Our goal is quite simply to make games we want to play. We both work other full-time jobs so development can take a backseat sometimes. It&#8217;s pretty easy for it to grind to a halt when life gets busy especially if you&#8217;re like me and like to have a nice big chunk of time to really get into stuff. We try to maximize our time when we do devote time to it there are a few ways you can help doing that. Make lists of concrete tasks, by keeping a list of very specific tasks it makes it easier to focus on what you need to do and knock stuff out. When we were nearing the first release of Tripolar we had a one column list on a whiteboard. By the time we crossed out 90% of that column we had a second, and by the time we crossed out 90% of that one we had a third. It really gave a sense of progress and helped us keep focused with what needed to be done for release. It&#8217;s easy to say &#8220;I need to do the settings screen&#8221; but what does that really entail? It&#8217;s much more useful to write down specific tasks like &#8220;Add settings button to the main menu&#8221;, &#8220;Make spring/summer/fall/winter theme icons&#8221; and etc. It certainly gives you a much better approximation of how long it&#8217;s actually going to take to finish.</p>
<p style="text-align: left;">What do I do?</p>
<p style="text-align: left;">I do all the art and graphics for Angry Fish Studios, including this website. I also work primarily on the game design and do some programming. On my new solo project I&#8217;ll be doing everything! I&#8217;m a true jack of all trades in that I&#8217;m also a master of none, I do my best but I&#8217;m constantly learning and by no means should you take anything I say as gospel. Be sure to check out our 100% factual bios on the <a href="http://www.AngryFishStudios.com/About" target="_blank">About</a> page.</p>
<h2 style="text-align: left;">Tripolar<a href="itms://itunes.apple.com/us/app/tripolar/id369581788?mt=8"><img class="size-full wp-image-193 alignnone" style="margin-top: -15px; margin-bottom: -15px;" title="App_Store_Badge_EN" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/App_Store_Badge_EN-e1299179078796.png" alt="" width="100" height="40" /></a></h2>
<p style="text-align: left;">We released our first game Tripolar back in October of &#8217;10, so somewhat recently. You probably haven&#8217;t heard of it and well the truth is we didn&#8217;t do too much of a push on it. You shoot gems at the board hitting a 3&#215;3 area which clears any gems of the same color as the shooter and swaps the other gems. It&#8217;s a somewhat simple mechanic thats easy to learn but hard to master. By the time we released it we already had some pretty major plans for an update for it including: new mechanics, a new play mode, game center, achievements, a whole ton of puzzle levels, an iPad version and a free version.  Part of the reason we didn&#8217;t push on it is we realized pretty quickly that we wanted to get a free version out there. There wasn&#8217;t a great way to divide the current release into a free version while really showing it off so we decided to wait for the update. That being said I&#8217;m still really happy with the first release of Tripolar. I&#8217;ve always admired things that look really polished and professional and I feel we accomplished that. For the first game I&#8217;ve ever really made it&#8217;s something I can say I&#8217;m proud of.</p>
<p style="text-align: left;">So lets talk about this update. I can&#8217;t give any definite timelines because, as I said, work on it is sporadic but Joe and I are working on it as often as we can. I&#8217;m really excited about it because while I think Tripolar&#8217;s first release was a solid foundation this update will really expand upon that.  There&#8217;s going to be several new gem types and shooters which is going to be a blast for puzzle mode. I think puzzle mode is really one of its strengths and something we didn&#8217;t devote enough to the first time around so this time there&#8217;s going to be a plethora of new levels. Below are a few screenshots showing some of the new features from the update. For now you&#8217;ll just have to guess how they work though <img src='http://www.AngryFishStudios.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/BlackBlockSS.png"><img title="BlackBlockSS" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/BlackBlockSS.png" alt="" width="160" height="240" /></a><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/PhaseBlocksSS.png"><img title="PhaseBlocksSS" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/PhaseBlocksSS.png" alt="" width="160" height="240" /></a><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/BBombSS.png"><img title="BBombSS" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/BBombSS.png" alt="" width="160" height="240" /></a></p>
<h2 style="text-align: left;">Mitch Digger</h2>
<p style="text-align: left;">First thing&#8217;s first, don&#8217;t get too attached to the name because it&#8217;s just a codename until I think of a real name.  (<strong>Fun fact</strong>: Mitch Digger comes from the game Dokapon Kingdom, an obscure but great wii/ps2 game, check it out if you&#8217;ve never heard of it.)</p>
<p style="text-align: left;">Mitch digger is a side scrolling platformer,</p>
<p style="text-align: left;">Picture Dig-Dug.</p>
<p style="text-align: left;">Got it?</p>
<p style="text-align: left;">Ok now forget about Dig-Dug because other than the view it&#8217;s nothing like that. There&#8217;s a couple ideas I want to explore through this game, mainly the idea that not every platformer needs to be about combat. The main goal is to explore levels by drilling through the earth and finding valuables.  Sure there will be enemies but Mitch isn&#8217;t a fighter, they can be dealt with in other ways like making a little ditch for them to fall into. There will be lots of things to buy and upgrade with all the money you get from the ore you find, in fact you&#8217;ll have to. As you dig further down the earth gets tougher, you use more oxygen, and it gets darker.</p>
<p style="text-align: left;">The other interesting aspect of the game is that inspired by our beloved @MysteryCoconut I&#8217;m planning on making the game using only UIKit and CoreAnimation. I might break down halfway through and use openGL but so far it&#8217;s looking possible. There really will only be a few animated sprites on the screen at any given time and by using good MVC practices it should be pretty doable. Below is the first &#8220;screenshot&#8221; from the game with some placeholder graphics. I&#8217;m guessing a lot of my blogging will be related to the development of this game.</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Screenshot.png"><img class="size-full wp-image-188 aligncenter" title="Screenshot" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Screenshot.png" alt="" width="480" height="320" /></a></p>
<p style="text-align: left;">Ok so now that we&#8217;re best friends lets get to the meat of this post.</p>
<p style="text-align: left;">
<p><span id="more-213"></span></p>
<h2 style="text-align: left;">Recoloring Artwork in Illustrator</h2>
<p style="text-align: left;">When making art for iDevices of all kinds I really prefer to use Illustrator, or just vector graphics in general, due to all the different sizes you can need. In Tripolar we have four different themes: spring, summer, fall and winter. There&#8217;s many ways one could handle creating the different gems for these themes but I did it using a tool that was actually new to me and I&#8217;m really glad I did.</p>
<p style="text-align: left;">Here&#8217;s a picture of the original versions of the gems:</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Gems1.png"><img class="aligncenter size-full wp-image-225" title="Gems" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Gems1.png" alt="Gems" width="600" height="167" /></a></p>
<p style="text-align: left;">The first thing you might notice is that the colors look super saturated on your computer, I used a special color profile to simulate the iPhone&#8217;s screen because red&#8217;s tend to be a little dull on it. They are fairly simple shapes but I wanted them to have a feeling of translucency like real gems so instead of being filled with solid colors they have several gradients.</p>
<p style="text-align: left;">Now in my opinion, and don&#8217;t think I&#8217;m alone, Illustrator isn&#8217;t the best tool when it comes to gradients. The UI for it just doesn&#8217;t feel mature, it&#8217;s really easy click the wrong thing and you have to drag swatches onto the gradient&#8217;s color bar instead of clicking a color tag then clicking the swatch. But the real problem is that there isn&#8217;t an easy way I&#8217;ve found to have gradients work in a &#8220;pass by reference&#8221; type way, they work in a &#8220;pass by value&#8221; kind of way.  When you&#8217;re trying to adjust things and get the color balance right this can be really difficult. Once I decided I wanted to do different themes I made these into the Summer theme gems but I needed to make 3 new colorings for the different gems.</p>
<p style="text-align: left;">Enter the Recolor Artwork window:</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Toolbar.png"><img class="aligncenter size-full wp-image-239" title="Toolbar" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Toolbar.png" alt="" width="600" height="31" /></a></p>
<p style="text-align: left;">It&#8217;s that little guy hiding right there.</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Recolor-Start.png"><img class="aligncenter size-full wp-image-234" title="Recolor Start" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Recolor-Start.png" alt="" width="578" height="387" /></a></p>
<p style="text-align: left;">As you can see here for the original &#8220;blue&#8221; gem there&#8217;s 10 different colors in the 4 gradients that make it up. Changing this by hand would be a nightmare when you want to keep tweaking colors slightly and see how it looks. But with this tool you can see all the colors that make up the object individually and change them however you want. You can even reduce the number of individual colors to simply things by mapping multiple colors to a single new color.</p>
<p style="text-align: left;">That little box the arrow is pointing to brings up a window with several options for dealing with the original set of colors. You can sort by either hue or value, which I find helpful for lining up the new colors. You can also have Illustrator reduce the number of colors for you and change how it does the recoloring. If you look on the right you can see a list of the color groups I set up for each gem and yes, I refer to the gems as &#8220;Red, Green, Blue&#8221; instead of &#8220;Hexagon, Square, Octagon&#8221; and no, I offer no explanation to my madness. If you don&#8217;t know the exact colors you want to map to you can use the edit tab to play around:</p>
<p style="text-align: center;"><a rel="attachment wp-att-235" href="http://www.AngryFishStudios.com/?attachment_id=235"></a><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Recolor-Changed.png"><img class="aligncenter size-full wp-image-237" title="Recolor Changed" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Recolor-Changed.png" alt="" width="582" height="390" /></a></p>
<p style="text-align: left;">Yeah… uh… that looks good… well, no it doesn&#8217;t but it gets the point across.</p>
<p style="text-align: left;">Here you can drag the individual colors around to remap them however you want and get a live preview on your artwork. This is going to be the most time intensive part of recoloring but it gives you so much control. Because you&#8217;re changing the key colors in the gradients they keep their size and shape and adjust to the new colors, this is the &#8220;pass by reference&#8221; type effect we were looking for.</p>
<p style="text-align: center;"><a href="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Recolor-Finished.png"><img class="aligncenter size-full wp-image-238" title="Recolor Finished" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/03/Recolor-Finished.png" alt="" width="581" height="376" /></a></p>
<p style="text-align: left;">Here you can see the recoloring from the summer gem to the fall gem completed. Looking good!</p>
<p style="text-align: left;">One last tip when dealing with gradients in Illustrator that&#8217;s not immediately obvious. If you want a gradient to span more than one shape without having to individually adjust the size and position you can make a compound path by going to Object->Compound Path->Make.  Now when you give it a gradient it will span across all the shapes, this is great for text as well.  Just remember to keep gradients subtle, this isn&#8217;t Word Art!</p>
<p style="text-align: left;">Please let me know if there&#8217;s any formatting problems with the blog. Still kinda new with wordpress and it can be pretty wonky at times. And don&#8217;t forget to add me on twitter! @AlexEvangelou</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/03/a-buffet-of-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plans for the New Year!</title>
		<link>http://www.AngryFishStudios.com/2011/01/plans-for-the-new-year/</link>
		<comments>http://www.AngryFishStudios.com/2011/01/plans-for-the-new-year/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 18:19:56 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Tripolar]]></category>
		<category><![CDATA[Website]]></category>

		<guid isPermaLink="false">http://www.AngryFishStudios.com/?p=171</guid>
		<description><![CDATA[It&#8217;s been a while since this blog has been updated! It seems I start most blog entries with that&#8230; but this time there&#8217;s an excuse. I&#8217;ve been trying to save any ideas for blog updates for when my turn on iDevBlogADay comes around. If you have any interest in iPhone development be sure to check [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since this blog has been updated! It seems I start most blog entries with that&#8230; but this time there&#8217;s an excuse. I&#8217;ve been trying to save any ideas for blog updates for when my turn on <a href="http://www.idevblogaday.com">iDevBlogADay</a> comes around.  If you have any interest in iPhone development be sure to check it out!</p>
<p>Joe and I are both very busy right now but we&#8217;re working on a major update for Tripolar.  Nothing is final but the update will contain: New blocks, new shooters, a new game mode, achievements, online leaderboards and best of all a whole slew of new puzzle levels!</p>
<p>In the meantime here&#8217;s a sneak peak:<br />
<img class="size-full wp-image-177 alignleft" title="PlusBlock3" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/01/PlusBlock3.gif" alt="" width="40" height="40" /><img class="size-full wp-image-172 alignleft" title="MinusBlock1" src="http://www.AngryFishStudios.com/wp-content/uploads/2011/01/MinusBlock1.gif" alt="" width="40" height="40" /></p>
<p>-Alex</p>
]]></content:encoded>
			<wfw:commentRss>http://www.AngryFishStudios.com/2011/01/plans-for-the-new-year/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

