Code Snippets

Groovy quicksort

0

Very short post.. even my blogging style is aligning itself to the way groovy allows me to write code – i.e. quickly.

Shamelessly copied from Dierk Konig’s excellent book “Groovy in Action’, I bring you the groovy implementation of the quick sort algorithm…

def quicksort(list)
{
    if ( list.size() < 2 ) 
        return list
    
    def pivot    = list[list.size().intdiv(2)]
    def left     = list.findAll {item -> item < pivot}
    def middle   = list.findAll {item -> item == pivot}
    def right    = list.findAll {item -> item > pivot}
    
    return (quicksort(left) + middle + quicksort(right))
}

(For those not familiar with Groovy, findAll, closures¬†and ranges¬†are standard language features and this algorithm ties these concepts up so nicely…)
I’m quickly falling in love with Groovy… I can’t wait to see whats waiting for me in the Grails framework… (more on this when I have time to post)

Go go SFML!!

Picking a library…

2

Progress is being made on MindHunters (the Trading Card Game I’m working on). In fact, progress has been really good.

Effects are working on the server, and the game is much more playable (and enjoyable) via the testbed client. Its time to move onto developing the actual game client. This is where I am, and where I’ve been since last week Friday. Well, actually, last Friday I was wondering which framework I should use (if any) for developing the client. My choices were:

  • SDL
  • SFML
  • Cinder
  • Qt
  • Write my own OpenGL framework (not really an option)

(more…)

cocos2d-iphone: A Binary Clock

0

Here is a CCScene based Binary Clock implementation in cocos2d-iphone. I used 0.99.5 for this, but it should compile flawlessly on 0.99.4 as well…

ClockScene.h

//
//  ClockScene.h
//  BinaryClock
//
//  Created by Peter Mares on 23/02/2011.
//  Copyright 2011. All rights reserved.
//


// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorld Layer
@interface ClockScene : CCScene
{
	CCLabelTTF *_arrLabels[6];
}

+(id) scene;

@end

ClockScene.m

//
//  ClockScene.m
//  BinaryClock
//
//  Created by Peter Mares on 23/02/2011.
//  Copyright 2011. All rights reserved.
//

// Import the interfaces
#import "ClockScene.h"

////////////////////////////////////////////////////////////////////////////////////////////////

@interface ClockScene ()
- (void) onTick:(ccTime)dt;
- (void) updateClockDisplay;
@end

////////////////////////////////////////////////////////////////////////////////////////////////

// HelloWorld implementation
@implementation ClockScene

+(id) scene
{
	ClockScene *scene = [ClockScene node];
	return scene;
}

////////////////////////////////////////////////////////////////////////////////////////////////

-(id) init
{
	if( (self=[super init] )) 
	{
		CGSize winSize = [[CCDirector sharedDirector] winSize];
		CCLabelTTF *label = nil;
		float yOffset = 0;
		
		for ( int i = 0; i < 6; i++ )
		{
			yOffset = (i % 2) * 25;
			label = [CCLabelTTF labelWithString:@"0000" fontName:@"Helvetica-Bold" fontSize:16];
			// some arbitrary magic numbers to make it work - you can make this more dynamic...
			label.position = ccp( winSize.width / 2 - ( (1-(i/2)) * 100 ), winSize.height / 2 - yOffset);
			[label setColor:ccc3(255, 255, 255)];
			_arrLabels[i] = label;
			
			[self addChild:label];
		}
		
		[self updateClockDisplay];
		[self schedule:@selector(onTick:) interval:1];
	}
	return self;
}

////////////////////////////////////////////////////////////////////////////////////////////////

- (void) dealloc
{
	[super dealloc];
}

////////////////////////////////////////////////////////////////////////////////////////////////

- (void) onTick:(ccTime)dt
{
	[self updateClockDisplay];
}

////////////////////////////////////////////////////////////////////////////////////////////////

- (void) updateClockDisplay
{
	NSDate *now = [NSDate date];
	NSCalendar *calendar = [NSCalendar currentCalendar];
	NSDateComponents *components = [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:now];
	int timeComponents[6];

	// now transform the hours, minutes and seconds into binary nibbles
	timeComponents[0] = [components hour] / 10;
	timeComponents[1] = [components hour] % 10;
	timeComponents[2] = [components minute] / 10;
	timeComponents[3] = [components minute] % 10;
	timeComponents[4] = [components second] / 10;
	timeComponents[5] = [components second] % 10;
	
	// translate each component into a binary nibble string
	for (int i = 0; i < 6; i++ )
	{
		NSMutableString* str = [NSMutableString string];
		
		for ( int bit = 8; bit > 0; bit >>= 1 )
			timeComponents[i] & bit ? [str appendString:@"1"] : [str appendString:@"0"];
			
		[_arrLabels[i] setString:str];
	}
}

@end

cocos2d-iphone: Sliding menu (from Lumi)

15

When Lumi was being designed, I wanted to make the navigation through the level packs and levels as slick as possible. I had played enough iOS games to know that navigation makes a huge difference to a games impact on a player. We were aiming for a simple, almost obvious paradigm to allow players to navigate through the level packs and levels.
I realised that during the discussions, the word ‘pages’ was constantly mentioned, as in ‘when the player goes from this page to this page’ or ‘maybe we should let the player flip through pages of levels’… this was so obvious – we were even using it while discussing WHAT the navigation would be. So, pages it was. With that out of the way, I decided to go with a UI mechanism similar to what Angry Birds had done for their level selection mechanics, which was to allow the user to slide left/right to flip ‘pages’.

Initially I had the code doing the same thing (sliding left and right), and that worked really well, but after I saw the graphic assets and we discussed how the level pack graphics would look, I realised I had to move to an up/down sliding mechanism. Not a problem, a quick refactor, a new enumeration and voila!

So now that Lumi has been released, and is doing well, I thought I’d share the code behind Lumi’s sliding menu system.

WARNING! LOTS OF CODE COMING NOW…

(more…)

cocos2d_logo

cocos2d-iphone: A basic button class

7

cocos2d-iphone is an amazing 2D OpenGL development framework, and comes bundled with a ton of really great and useful classes that make game development a pleasure. However, one of the things that it is currently missing is a basic button object that can be used freely in your projects.

I’ve created a class called BasicButton class that uses delegates and selectors to quickly create buttons and react to them in a seperate ‘handler’ object.
(more…)

cocos2d_logo

cocos2d-iphone: Filled polygons

2

While testing my upcoming game on an iPhone 3G, I discovered that drawing line segments was error prone in terms of accurately connecting multiple line segments seamlessly. The problem seems to arise from the fact that OpenGL cannot guarantee exact pixelation for lines (using glDrawArrays(GL_LINES…) ).

This is mentioned in the Rasterization FAQ on the OpenGL site here : Link
(more…)

Objective C class: Simple Image Cache singleton

2

While working on an iPhone application which makes use of remote data and remote image assets, I realised I needed an object that could quickly and easily cache remote images in the app’s local sandboxed “Documents” folder. To be honest, I kind of feel like I reinvented someone’s wheel here, but I got exactly what I wanted – a small class (singleton) that provides full remote image (not limited to images though) caching within the sandboxed environment on an iPhone.
(more…)

Snippet: Endian swap template

0

Template to swap endian-ness of a primitive datatype:

template <typename T>
T swapEndianness(const T& t)
{
  unsigned char byteCount = sizeof(T);
  T byteMask = 0xFF;
  T newVal = 0;

  for ( unsigned char i = 0; i < byteCount; i++ )
  {
    T mask = (byteMask << (i*8));
    T val = ((t&mask)>>i*8);
    unsigned char offset = (byteCount-i-1)*8;
    T destMask = byteMask << offset;

    newVal |= ((( val ) << offset) & destMask);
  }

  return newVal;
}

//
// sample usage:
//
long long llVal = 0x12345600ABCDEF;
long long llVal2 = swapEndianness<long long>(llVal);

Go to Top