Don’t abuse NSLog in your iPhone game

April 8th, 2010 by Andrea Franz

I’m working on a simple game for iPhone based on cocos2d. Yesterday I installed it on my old iPhone3G and it was veeeeeeeery slow. After a lot of refactoring I found a NSLog call inside my game loop. It basically logged all the collision detection of the player with all the tiles in the map. After removing that it’s even faster then before. So, if you want to log something, do it, but remember to remove all these logging calls later.


Cocos2d: how to make a label to fit the Iphone screen width

July 15th, 2009 by Andrea Franz

In the iPhone game I’m working on I need to display a different label every time I start a new game level. Each one of these labels has a random string taken from an array of words, and each one of these strings has different size. So every time I create a new label I set the maximum font size and then I decrement it until the string size measures less than the iPhone screen. I do that using the sizeWithFont method of the NSString class:

- (int) calculateFontSizeForString:(NSString*)string fontName:(NSString*)usedFontName {
  int fontSize = 120; // it seems to be the biggest font we can use
  while (--fontSize > 0) {			
    CGSize size = [string sizeWithFont:[UIFont fontWithName:usedFontName size:fontSize]];
    if (size.width <= 480 && size.height <= 360)
      break;
  }				
 
  return fontSize;
}

And here a custom scene that you can use to test it:

MyScene.h

#import "cocos2d.h"
 
@interface MyScene : Scene {
  Label    *label;
  NSArray  *strings;
  NSString *fontName;
  int      stringIndex;
}
 
- (void) nextLabel;
- (int)  calculateFontSizeForString:(NSString*)string fontName:(NSString*)usedFontName;
- (void) removeCurrentLabel;
- (void) createNextLabel;
- (void) animateLabel;
 
@property (nonatomic, retain) NSArray  *strings;
@property (nonatomic, retain) NSString *fontName;
@end

MyScene.m

#import "MyScene.h"
 
@implementation MyScene
 
@synthesize strings;
@synthesize fontName;
 
- (id) init {
  if (self = [super init]) {
    [self setFontName:@"Marker Felt"];
    [self setStrings:[NSArray arrayWithObjects:
                      @"Lorem ipsum", 
                      @"Lorem ipsum dolor",
                      @"Lorem ipsum dolor sit amet",
                      @"Lorem ipsum dolor sit amet, consectetur adipisicing elit",
                      @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                      nil]];		
    stringIndex = 0;
  }
 
  return self;
}
 
- (void) onEnter {
  [super onEnter];
  [self nextLabel];
}
 
- (void) nextLabel {	
  [self removeCurrentLabel];
  [self createNextLabel];	
  stringIndex++;	
}
 
- (void) removeCurrentLabel {
  if (label) [self removeChild:label cleanup:YES];
  label = nil;
}
 
- (void) createNextLabel {
  NSString *labelString = [strings objectAtIndex:(stringIndex % [strings count])];
  int fontSize = [self calculateFontSizeForString:labelString fontName:fontName];	
  label = [Label labelWithString:labelString dimensions: CGSizeMake(0, 0) alignment: UITextAlignmentCenter fontName:fontName fontSize:fontSize];
  [label setPosition:ccp(240, 160)];	
  [label setScale:0.5];
  [self addChild:label];
  [self animateLabel];	
}
 
- (void) animateLabel {
  IntervalAction *scale = [ScaleTo actionWithDuration:0.5 scale:1];
  id delay  = [DelayTime actionWithDuration:1]; 
  id notify = [CallFunc actionWithTarget:self selector:@selector(nextLabel)];	
  Sequence *sequence = [Sequence actions:scale, delay, notify, nil];	
  [label runAction:sequence];		
}
 
- (int) calculateFontSizeForString:(NSString*)string fontName:(NSString*)usedFontName {
  int fontSize = 120; // it seems to be the biggest font we can use
  while (--fontSize > 0) {			
    CGSize size = [string sizeWithFont:[UIFont fontWithName:usedFontName size:fontSize]];
    if (size.width <= 480 && size.height <= 360)
      break;
  }				
 
  return fontSize;
}
 
- (void) dealloc {
  [strings retain];
  [fontName retain];
  [super dealloc];
}
 
@end

FitFontTestAppDelegate.m

#import "FitFontTestAppDelegate.h"
 
@implementation FitFontTestAppDelegate
 
- (void)applicationDidFinishLaunching:(UIApplication *)application {
  window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  [window setUserInteractionEnabled:YES];
  [window setMultipleTouchEnabled:YES];
 
  [[Director sharedDirector] setDeviceOrientation:CCDeviceOrientationLandscapeLeft];
  [[Director sharedDirector] attachInWindow:window];		
  [window makeKeyAndVisible];	
 
  MyScene *scene = [MyScene node];
  [[Director sharedDirector] runWithScene:scene];
 
}
 
 
- (void)dealloc {
  [window release];
  [super dealloc];
}
 
@end