From d8f00310e486aed1ab289a0f816acec571193c32 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Wed, 24 Aug 2011 11:53:40 -0400 Subject: Added support for multiple local highscore lists This revision increments the database version to 2. Also fixed a small problem with GameModeSelection that aligned the highscore text incorrectly. --- Classes/Cart_CollectAppDelegate.m | 40 ++++++++++++++++++++++++---- Classes/GameModeSelection.h | 2 -- Classes/GameModeSelection.m | 53 ++++++++++++++++---------------------- Classes/GameModeSelectionLayer.m | 14 +--------- Classes/GameOverScene.m | 6 ++--- Classes/Highscore.h | 2 ++ Classes/Highscore.m | 53 ++++++++++++++++++++++++++++++++++++++ Classes/HighscoreListController.m | 37 +------------------------- Resources/cartdata.sqlite3 | Bin 16384 -> 16384 bytes 9 files changed, 117 insertions(+), 90 deletions(-) diff --git a/Classes/Cart_CollectAppDelegate.m b/Classes/Cart_CollectAppDelegate.m index 0af3ac0..ba9d60b 100755 --- a/Classes/Cart_CollectAppDelegate.m +++ b/Classes/Cart_CollectAppDelegate.m @@ -142,6 +142,8 @@ -(void) applicationDidEnterBackground:(UIApplication*)application { [[CCDirector sharedDirector] stopAnimation]; + + [[NSUserDefaults standardUserDefaults] synchronize]; if ([[CCDirector sharedDirector] runningScene].tag == GAME_SCENE) { @@ -194,20 +196,48 @@ { NSString* databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName]; [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil]; - //[fileManager release]; - [userDefaults setInteger:1 forKey:@"databaseVersion"]; + [userDefaults setInteger:2 forKey:@"databaseVersion"]; + } + + if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) + { + NSLog(@"Failed to open database"); } + // Database migrations! if ([userDefaults integerForKey:@"databaseVersion"] < 1) { // Upgrade the database to version 1, which is completely unnecessary as no prior version exists } - - if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) + + if ([userDefaults integerForKey:@"databaseVersion"] < 2) { - NSLog(@"Failed to open database"); + // Database version 2 adds a "gameMode" column to highscores to allow for multiple highscore lists + const char* sqlQuery = "ALTER TABLE highscores ADD gameMode varchar(255)"; + sqlite3_stmt* compiled_statement; + + if (sqlite3_prepare_v2(database, sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) + { + sqlite3_step(compiled_statement); + + sqlQuery = "UPDATE highscores SET gameMode = \"Collect\""; + if (sqlite3_prepare_v2(database, sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) + { + sqlite3_step(compiled_statement); + + NSLog(@"Updated database to version 2."); + [userDefaults setInteger:2 forKey:@"databaseVersion"]; + } else { + NSLog(@"Error while updating database to version 2. '%s'", sqlite3_errmsg(database)); + } + } else { + NSLog(@"Error while updating database to version 2. '%s'", sqlite3_errmsg(database)); + } } + + // It's rather important that the database version gets saved + [userDefaults synchronize]; } return database; diff --git a/Classes/GameModeSelection.h b/Classes/GameModeSelection.h index f69ea37..bdb38fb 100644 --- a/Classes/GameModeSelection.h +++ b/Classes/GameModeSelection.h @@ -22,10 +22,8 @@ @property (readonly) BOOL unlocked; @property (nonatomic,retain) id delegate; + (id)selectionWithName:(NSString*)name location:(NSString*)location filename:(NSString*)filename unlocked:(BOOL)unlocked; -+ (id)selectionWithName:(NSString *)name location:(NSString *)location filename:(NSString *)filename highscore:(int)highscore; + (id)selectionWithName:(NSString *)name location:(NSString *)location filename:(NSString *)filename unlockCondition:(NSString*)unlockCondition; - (id)initWithName:(NSString*)name location:(NSString*)location filename:(NSString*)filename unlocked:(BOOL)unlocked; -- (id)initWithName:(NSString *)name location:(NSString *)location filename:(NSString *)filename highscore:(int)highscore; - (id)initWithName:(NSString *)name location:(NSString *)location filename:(NSString *)filename unlockCondition:(NSString*)unlockCondition; - (void)buttonTapped; diff --git a/Classes/GameModeSelection.m b/Classes/GameModeSelection.m index 582c9dd..69f1ddb 100644 --- a/Classes/GameModeSelection.m +++ b/Classes/GameModeSelection.m @@ -9,6 +9,7 @@ #import "GameModeSelection.h" #import "UIImage+ColorMasking.h" #import "NMPanelMenu.h" +#import "Highscore.h" @implementation GameModeSelection @@ -19,11 +20,6 @@ return [[[GameModeSelection alloc] initWithName:name location:location filename:filename unlocked:unlocked] autorelease]; } -+ (id)selectionWithName:(NSString *)name location:(NSString *)location filename:(NSString *)filename highscore:(int)highscore -{ - return [[[GameModeSelection alloc] initWithName:name location:location filename:filename highscore:highscore] autorelease]; -} - + (id)selectionWithName:(NSString *)name location:(NSString *)location filename:(NSString *)filename unlockCondition:(NSString*)unlockCondition { return [[[GameModeSelection alloc] initWithName:name location:location filename:filename unlockCondition:unlockCondition] autorelease]; @@ -162,34 +158,29 @@ CCSprite* titleSprite = [CCSprite spriteWithCGImage:titleImage key:[NSString stringWithFormat:@"gms-%@-title", filenameMod]]; titleSprite.position = ccp(-10, (boxSize.height)/2+(combinedTitleSize.height)/2); [self addChild:titleSprite]; - } - - return self; -} - -- (id)initWithName:(NSString *)m_name location:(NSString *)m_location filename:(NSString *)m_filename highscore:(int)m_highscore -{ - self = [self initWithName:m_name location:m_location filename:m_filename unlocked:YES]; - - if (nil != self) - { - if (m_highscore != 0) + + if (unlocked) { - // Render the highscore label - NSString* highscoreString = [NSString stringWithFormat:@"Highscore: %d", m_highscore]; - UIFont* highscoreFont = [UIFont fontWithName:@"AmericanTypewriter" size:16.0f]; - CGSize highscoreSize = [highscoreString sizeWithFont:highscoreFont]; - - UIGraphicsBeginImageContext(CGSizeMake(highscoreSize.width+10, highscoreSize.height+10)); - CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetShadow(context, CGSizeMake(-6, 6), 4.0f); - [highscoreString drawInRect:CGRectMake(10, 0, highscoreSize.width, highscoreSize.height) withFont:highscoreFont]; + Highscore* localHighscore = [Highscore localHighscoreForGameMode:name]; - CGImageRef highscoreImage = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; - UIGraphicsEndImageContext(); - CCSprite* highscoreSprite = [CCSprite spriteWithCGImage:highscoreImage key:[NSString stringWithFormat:@"gms-%@-highscore", m_filename]]; - highscoreSprite.position = ccp((128-highscoreSize.width)/2, 0-64-(highscoreSize.height)/2-10); - [self addChild:highscoreSprite]; + if (localHighscore != nil) + { + // Render the highscore label + NSString* highscoreString = [NSString stringWithFormat:@"Highscore: %d", localHighscore.score]; + UIFont* highscoreFont = [UIFont fontWithName:@"AmericanTypewriter" size:16.0f]; + CGSize highscoreSize = [highscoreString sizeWithFont:highscoreFont]; + + UIGraphicsBeginImageContext(CGSizeMake(highscoreSize.width+10, highscoreSize.height+10)); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetShadow(context, CGSizeMake(-6, 6), 4.0f); + [highscoreString drawInRect:CGRectMake(10, 0, highscoreSize.width, highscoreSize.height) withFont:highscoreFont]; + + CGImageRef highscoreImage = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; + UIGraphicsEndImageContext(); + CCSprite* highscoreSprite = [CCSprite spriteWithCGImage:highscoreImage key:[NSString stringWithFormat:@"gms-%@-highscore", filename]]; + highscoreSprite.position = ccp(-5, 0-64-(highscoreSize.height)/2-10); + [self addChild:highscoreSprite]; + } } } diff --git a/Classes/GameModeSelectionLayer.m b/Classes/GameModeSelectionLayer.m index 4c4845d..db08146 100644 --- a/Classes/GameModeSelectionLayer.m +++ b/Classes/GameModeSelectionLayer.m @@ -49,19 +49,7 @@ if ([defaults boolForKey:@"hasDoneTutorial"]) { - const char* sqlQuery = "SELECT * FROM highscores ORDER BY score DESC LIMIT 1"; - sqlite3_stmt* compiled_statement; - int score = 0; - - if (sqlite3_prepare_v2([Cart_CollectAppDelegate database], sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) - { - if (sqlite3_step(compiled_statement) == SQLITE_ROW) - { - score = sqlite3_column_int(compiled_statement, 2); - } - } - - collectSelection = [GameModeSelection selectionWithName:@"Collect" location:@"Paris" filename:@"paris" highscore:score]; + collectSelection = [GameModeSelection selectionWithName:@"Collect" location:@"Paris" filename:@"paris" unlocked:YES]; } else { collectSelection = [GameModeSelection selectionWithName:@"Collect" location:@"Paris" filename:@"paris" unlockCondition:@"Beat the tutorial!"]; } diff --git a/Classes/GameOverScene.m b/Classes/GameOverScene.m index bc081ff..94236ff 100755 --- a/Classes/GameOverScene.m +++ b/Classes/GameOverScene.m @@ -88,15 +88,15 @@ textField.enabled = NO; submitSwitch.enabled = NO; - const char* sqlQuery = [[NSString stringWithFormat:@"INSERT INTO highscores (name, score) VALUES (\"%@\",%d)", [textField text], score] UTF8String]; + const char* sqlQuery = [[NSString stringWithFormat:@"INSERT INTO highscores (name, score, gameMode) VALUES (\"%@\",%d,\"Collect\")", [textField text], score] UTF8String]; sqlite3_stmt* compiled_statement; if (sqlite3_prepare_v2([Cart_CollectAppDelegate database], sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) { sqlite3_step(compiled_statement); - NSLog(@"awesome, %@", [textField text]); + NSLog(@"awesome, %@, %d", [textField text], score); } else { - NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg([Cart_CollectAppDelegate database])); + NSLog(@"Error while adding highscore to local highscore list. '%s'", sqlite3_errmsg([Cart_CollectAppDelegate database])); } if (submitSwitch.on) diff --git a/Classes/Highscore.h b/Classes/Highscore.h index bc6a8fb..fa2ea71 100755 --- a/Classes/Highscore.h +++ b/Classes/Highscore.h @@ -17,6 +17,8 @@ @property (readonly) NSString* name; @property (readonly) int score; @property (readonly) NSDate* date; ++ (NSArray*)localHighscoreListForGameMode:(NSString*)gameMode; ++ (Highscore*)localHighscoreForGameMode:(NSString*)gameMode; - (id)initWithName:(NSString*)name score:(int)score date:(NSDate*)date; @end diff --git a/Classes/Highscore.m b/Classes/Highscore.m index 20ce56f..546cbfe 100755 --- a/Classes/Highscore.m +++ b/Classes/Highscore.m @@ -7,11 +7,64 @@ // #import "Highscore.h" +#import +#import "Cart_CollectAppDelegate.h" @implementation Highscore @synthesize name, score, date; ++ (NSArray*)localHighscoreListForGameMode:(NSString*)gameMode +{ + NSMutableArray* highscores = [NSMutableArray arrayWithCapacity:15]; + const char* sqlQuery = [[NSString stringWithFormat:@"SELECT * FROM highscores WHERE gameMode = \"%@\" ORDER BY score DESC LIMIT 15", gameMode] UTF8String]; + sqlite3_stmt* compiled_statement; + + if (sqlite3_prepare_v2([Cart_CollectAppDelegate database], sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) + { + while (sqlite3_step(compiled_statement) == SQLITE_ROW) + { + NSString* name = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiled_statement, 1)]; + int score = sqlite3_column_int(compiled_statement, 2); + + NSDate* date = nil; + char* dateStr = (char*)sqlite3_column_text(compiled_statement, 3); + if (dateStr != NULL) + { + NSString* theDate = [NSString stringWithUTF8String:dateStr]; + NSDateComponents* comps = [[NSDateComponents alloc] init]; + [comps setYear:[[theDate substringToIndex:4] intValue]]; + [comps setMonth:[[theDate substringWithRange:NSMakeRange(5, 2)] intValue]]; + [comps setDay:[[theDate substringWithRange:NSMakeRange(8, 2)] intValue]]; + [comps setHour:[[theDate substringWithRange:NSMakeRange(11, 2)] intValue]]; + [comps setMinute:[[theDate substringWithRange:NSMakeRange(14, 2)] intValue]]; + [comps setSecond:[[theDate substringWithRange:NSMakeRange(17, 2)] intValue]]; + date = [[NSCalendar currentCalendar] dateFromComponents:comps]; + date = [date dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]]; + [comps release]; + } + + Highscore* highscore = [[Highscore alloc] initWithName:name score:score date:date]; + [highscores addObject:highscore]; + [highscore release]; + } + } + + return [highscores copy]; +} + ++ (Highscore*)localHighscoreForGameMode:(NSString*)gameMode +{ + NSArray* localHighscores = [Highscore localHighscoreListForGameMode:gameMode]; + + if ([localHighscores count] > 0) + { + return [localHighscores objectAtIndex:0]; + } else { + return nil; + } +} + - (id)initWithName:(NSString*)m_name score:(int)m_score date:(NSDate*)m_date { self = [super init]; diff --git a/Classes/HighscoreListController.m b/Classes/HighscoreListController.m index 932b147..d7bffcb 100755 --- a/Classes/HighscoreListController.m +++ b/Classes/HighscoreListController.m @@ -10,7 +10,6 @@ #import "Highscore.h" #import "RootViewController.h" #import "cocoslive.h" -#import #import "Cart_CollectAppDelegate.h" @implementation HighscoreListController @@ -23,41 +22,7 @@ // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. self = [super initWithStyle:style]; if (self) { - NSMutableArray* highscores = [NSMutableArray arrayWithCapacity:15]; - const char* sqlQuery = "SELECT * FROM highscores ORDER BY score DESC LIMIT 15"; - sqlite3_stmt* compiled_statement; - - if (sqlite3_prepare_v2([Cart_CollectAppDelegate database], sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) - { - while (sqlite3_step(compiled_statement) == SQLITE_ROW) - { - NSString* name = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiled_statement, 1)]; - int score = sqlite3_column_int(compiled_statement, 2); - - NSDate* date = nil; - char* dateStr = (char*)sqlite3_column_text(compiled_statement, 3); - if (dateStr != NULL) - { - NSString* theDate = [NSString stringWithUTF8String:dateStr]; - NSDateComponents* comps = [[NSDateComponents alloc] init]; - [comps setYear:[[theDate substringToIndex:4] intValue]]; - [comps setMonth:[[theDate substringWithRange:NSMakeRange(5, 2)] intValue]]; - [comps setDay:[[theDate substringWithRange:NSMakeRange(8, 2)] intValue]]; - [comps setHour:[[theDate substringWithRange:NSMakeRange(11, 2)] intValue]]; - [comps setMinute:[[theDate substringWithRange:NSMakeRange(14, 2)] intValue]]; - [comps setSecond:[[theDate substringWithRange:NSMakeRange(17, 2)] intValue]]; - date = [[NSCalendar currentCalendar] dateFromComponents:comps]; - date = [date dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]]; - [comps release]; - } - - Highscore* highscore = [[Highscore alloc] initWithName:name score:score date:date]; - [highscores addObject:highscore]; - [highscore release]; - } - } - - localHighscores = [highscores copy]; + localHighscores = [Highscore localHighscoreListForGameMode:@"Collect"]; navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; myNavigationItem = [[UINavigationItem alloc] initWithTitle:@"Highscores"]; diff --git a/Resources/cartdata.sqlite3 b/Resources/cartdata.sqlite3 index 6b7b656..5afd6aa 100755 Binary files a/Resources/cartdata.sqlite3 and b/Resources/cartdata.sqlite3 differ -- cgit 1.4.1