From 2ac50443ddbf69b7594808ba4e6de49eecbc0b84 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Mon, 22 Aug 2011 19:52:08 -0400 Subject: Added borders to level selection images The image for each level selection now has a tutorial bubble-esque border around it, which was achieved using image masking. The border is included in the graying-out effect when the image is being tapped, and it is also included in the grayscaling when the level is not yet unlocked. Also rewrote most of the selection drawing code. The titles are now drawn above the image, with Quartz instead of Cocos2D. The highscore label is also drawn with Quartz, though it is still below the image. The unlock condition label no longer appears, and instead, locked levels are now tappable and tapping them shows an alert view containing the unlock condition. Will probably be changed to be more elegant later. Really, the biggest thing left before the selection screen is done is the ability to scroll through levels. The background also needs changing, but that will come later once I recruit a graphics designer. :P Refs #207 --- Classes/GameModeSelection.m | 195 ++++++++++++++++++++++++++++++++------------ 1 file changed, 145 insertions(+), 50 deletions(-) (limited to 'Classes/GameModeSelection.m') diff --git a/Classes/GameModeSelection.m b/Classes/GameModeSelection.m index 0816828..fc6797a 100644 --- a/Classes/GameModeSelection.m +++ b/Classes/GameModeSelection.m @@ -9,10 +9,11 @@ #import "GameModeSelection.h" #import "TutorialMode.h" #import "ClassicGameMode.h" +#import "UIImage+ColorMasking.h" @implementation GameModeSelection -@synthesize name, location, unlocked, highscore, unlockCondition; +@synthesize name, location, unlocked; - (id)initWithName:(NSString*)m_name location:(NSString*)m_location filename:(NSString*)filename unlocked:(BOOL)m_unlocked; { @@ -26,92 +27,186 @@ location = m_location; unlocked = m_unlocked; - if (!unlocked) + NSString* filenameMod; + + if (unlocked) { + filenameMod = [NSString stringWithFormat:@"%@-unlocked", filename]; + } else { + filenameMod = [NSString stringWithFormat:@"%@-locked", filename]; name = [@"" stringByPaddingToLength:name.length withString:@"?" startingAtIndex:0]; location = [@"" stringByPaddingToLength:location.length withString:@"?" startingAtIndex:0]; } - nameLabel = [CCLabelBMFont labelWithString:[NSString stringWithFormat:@"%@ (%@)", location, name] fntFile:@"levelnames.fnt"]; + // First, create the frame that we will put the level picture inside + CGImageRef framestuff = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"framestuff" ofType:@"png"]] CGImage]; + CGImageRef topLeftRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(0, 0, 8, 8)); + CGImageRef topRightRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(8, 0, 8, 8)); + CGImageRef bottomLeftRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(0, 8, 8, 8)); + CGImageRef bottomRightRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(8, 8, 8, 8)); + CGImageRef topBorderRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(0, 16, 8, 8)); + CGImageRef leftBorderRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(8, 16, 8, 8)); + CGImageRef rightBorderRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(0, 24, 8, 8)); + CGImageRef bottomBorderRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(8, 24, 8, 8)); + UIImage* topLeft = [UIImage imageWithCGImage:topLeftRef]; + UIImage* topRight = [UIImage imageWithCGImage:topRightRef]; + UIImage* bottomLeft = [UIImage imageWithCGImage:bottomLeftRef]; + UIImage* bottomRight = [UIImage imageWithCGImage:bottomRightRef]; + UIImage* topBorder = [UIImage imageWithCGImage:topBorderRef]; + UIImage* leftBorder = [UIImage imageWithCGImage:leftBorderRef]; + UIImage* rightBorder = [UIImage imageWithCGImage:rightBorderRef]; + UIImage* bottomBorder = [UIImage imageWithCGImage:bottomBorderRef]; + CGImageRelease(topLeftRef); + CGImageRelease(topRightRef); + CGImageRelease(bottomLeftRef); + CGImageRelease(bottomRightRef); + CGImageRelease(topBorderRef); + CGImageRelease(leftBorderRef); + CGImageRelease(rightBorderRef); + CGImageRelease(bottomBorderRef); - [self addChild:nameLabel]; - nameLabel.position = ccp(0, -32-nameLabel.contentSize.height); + CGSize boxSize = CGSizeMake(128+12, 128+12); + UIGraphicsBeginImageContext(boxSize); + CGContextRef context = UIGraphicsGetCurrentContext(); + [topLeft drawInRect:CGRectMake(0, 0, 8, 8)]; + [topBorder drawInRect:CGRectMake(8, 0, boxSize.width-16, 8)]; + [topRight drawInRect:CGRectMake(8+boxSize.width-16, 0, 8, 8)]; + [rightBorder drawInRect:CGRectMake(8+boxSize.width-16, 8, 8, boxSize.height-16)]; + [bottomRight drawInRect:CGRectMake(8+boxSize.width-16, 8+boxSize.height-16, 8, 8)]; + [bottomBorder drawInRect:CGRectMake(8, 8+boxSize.height-16, boxSize.width-16, 8)]; + [bottomLeft drawInRect:CGRectMake(0, 8+boxSize.height-16, 8, 8)]; + [leftBorder drawInRect:CGRectMake(0, 8, 8, boxSize.height-16)]; + CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); + CGContextFillRect(context, CGRectMake(8, 8, boxSize.width-16, boxSize.height-16)); + UIImage* selectionBackground = UIGraphicsGetImageFromCurrentImageContext(); + // Now we want to put the level image inside the frame without messing up the frame itself UIImage* innerPicture = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"png"]]; - UIGraphicsBeginImageContext(CGSizeMake(128, 128)); - CGContextRef context = UIGraphicsGetCurrentContext(); - UIGraphicsPushContext(context); + CGContextClipToMask(context, CGRectMake(0, 0, boxSize.width, boxSize.height), [[selectionBackground opaqueMaskFromWhiteImage] CGImage]); + [innerPicture drawInRect:CGRectMake(6, 6, 128, 128)]; + selectionBackground = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + // The frame needs a shadow, so let's redraw it in a new context + UIGraphicsBeginImageContext(CGSizeMake(boxSize.width+10, boxSize.height+10)); + context = UIGraphicsGetCurrentContext(); + CGContextSaveGState(context); if (unlocked) { - [innerPicture drawInRect:CGRectMake(0, 0, 128, 128)]; + CGContextSetShadow(context, CGSizeMake(-6, 6), 4.0f); + [selectionBackground drawInRect:CGRectMake(10, 0, boxSize.width, boxSize.height)]; } else { + // Draw the picture in grayscale if the level has not yet been unlocked + CGContextClipToMask(context, CGRectMake(10, 0, boxSize.width, boxSize.height), [selectionBackground CGImage]); CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); - CGContextFillRect(context, CGRectMake(0, 0, 128, 128)); - [innerPicture drawInRect:CGRectMake(0, 0, 128, 128) blendMode:kCGBlendModeLuminosity alpha:1.0]; + CGContextFillRect(context, CGRectMake(10, 0, boxSize.width, boxSize.height)); + CGContextRestoreGState(context); + + CGContextSaveGState(context); + CGContextSetShadow(context, CGSizeMake(-6, 6), 4.0f); + [selectionBackground drawInRect:CGRectMake(10, 0, boxSize.width, boxSize.height) blendMode:kCGBlendModeLuminosity alpha:1.0]; } - UIGraphicsPopContext(); - CGImageRef innerPictureRef = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; + CGContextRestoreGState(context); + CGImageRef pictureRef = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; - if (unlocked) - { - CCSprite* picture = [CCSprite spriteWithCGImage:innerPictureRef key:[NSString stringWithFormat:@"gms-%@", filename]]; - UIGraphicsPushContext(context); - CGContextSetFillColorWithColor(context, [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5] CGColor]); - CGContextFillRect(context, CGRectMake(0, 0, 128, 128)); - UIGraphicsPopContext(); - CGImageRef selectedButtonRef = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; - CCSprite* selectedButton = [CCSprite spriteWithCGImage:selectedButtonRef key:[NSString stringWithFormat:@"gms-%@-selected", filename]]; - - CCMenuItemSprite* pictureMenuItem = [CCMenuItemSprite itemFromNormalSprite:picture selectedSprite:selectedButton target:self selector:@selector(buttonTapped)]; - CCMenu* theMenu = [CCMenu menuWithItems:pictureMenuItem, nil]; - theMenu.position = ccp(0, 32); - [self addChild:theMenu]; - } else { - CCSprite* picture = [CCSprite spriteWithCGImage:innerPictureRef key:[NSString stringWithFormat:@"gms-%@-locked", filename]]; - picture.position = ccp(0, 32); - [self addChild:picture]; - } + CCSprite* picture = [CCSprite spriteWithCGImage:pictureRef key:[NSString stringWithFormat:@"gms-%@", filenameMod]]; + // We're also going to need a "selected" image state for the button + CGContextSaveGState(context); + CGContextClipToMask(context, CGRectMake(10, 0, boxSize.width, boxSize.height), [selectionBackground CGImage]); + CGContextSetFillColorWithColor(context, [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5] CGColor]); + CGContextFillRect(context, CGRectMake(10, 0, boxSize.width, boxSize.height)); + CGContextRestoreGState(context); + CGImageRef selectedButtonRef = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; UIGraphicsEndImageContext(); + CCSprite* selectedButton = [CCSprite spriteWithCGImage:selectedButtonRef key:[NSString stringWithFormat:@"gms-%@-selected", filenameMod]]; + + CCMenuItemSprite* pictureMenuItem = [CCMenuItemSprite itemFromNormalSprite:picture selectedSprite:selectedButton target:self selector:@selector(buttonTapped)]; + CCMenu* theMenu = [CCMenu menuWithItems:pictureMenuItem, nil]; + theMenu.position = ccp(-5, 0); + [self addChild:theMenu]; + + // Render the titles + UIFont* titleFont = [UIFont fontWithName:@"AmericanTypewriter-Bold" size:18.0f]; + CGSize titleSize = [location sizeWithFont:titleFont constrainedToSize:CGSizeMake(128, 0)]; + UIFont* subtitleFont = [UIFont fontWithName:@"AmericanTypewriter" size:18.0f]; + CGSize subtitleSize = [name sizeWithFont:subtitleFont constrainedToSize:CGSizeMake(128, 0)]; + CGSize combinedTitleSize = CGSizeMake(128, titleSize.height + 10 + subtitleSize.height + 10); + + UIGraphicsBeginImageContext(combinedTitleSize); + context = UIGraphicsGetCurrentContext(); + CGContextSetShadow(context, CGSizeMake(-6, 6), 4.0f); + [location drawInRect:CGRectMake(10, 0, 128, titleSize.height) withFont:titleFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter]; + [name drawInRect:CGRectMake(10, titleSize.height, 128, subtitleSize.height) withFont:subtitleFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter]; + + CGImageRef titleImage = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; + UIGraphicsEndImageContext(); + 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; } -- (void)setHighscore:(int)m_highscore +- (id)initWithName:(NSString *)m_name location:(NSString *)m_location filename:(NSString *)m_filename highscore:(int)m_highscore { - if (unlocked) + self = [self initWithName:m_name location:m_location filename:m_filename unlocked:YES]; + + if (nil != self) { - highscore = m_highscore; - - otherLabel = [CCLabelBMFont labelWithString:[NSString stringWithFormat:@"Highscore: %d", highscore] fntFile:@"leveldescriptions.fnt"]; - otherLabel.position = ccp(0, -32-nameLabel.contentSize.height-otherLabel.contentSize.height); - [self addChild:otherLabel]; + if (m_highscore != 0) + { + // 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]; + + 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]; + } } + + return self; } -- (void)setUnlockCondition:(NSString *)m_unlockCondition +- (id)initWithName:(NSString *)m_name location:(NSString *)m_location filename:(NSString *)m_filename unlockCondition:(NSString*)m_unlockCondition { - if (!unlocked) + self = [self initWithName:m_name location:m_location filename:m_filename unlocked:NO]; + + if (nil != self) { unlockCondition = m_unlockCondition; - - otherLabel = [CCLabelBMFont labelWithString:unlockCondition fntFile:@"leveldescriptions.fnt"]; - otherLabel.position = ccp(0, -32-nameLabel.contentSize.height-otherLabel.contentSize.height); - [self addChild:otherLabel]; } + + return self; } - (void)buttonTapped { - if ([name isEqual:@"Tutorial"]) - { - [[CCDirector sharedDirector] replaceScene:[TutorialMode scene]]; - } else if ([name isEqual:@"Collect"]) + if (unlocked) { - [[CCDirector sharedDirector] replaceScene:[ClassicGameMode scene]]; + if ([name isEqual:@"Tutorial"]) + { + [[CCDirector sharedDirector] replaceScene:[TutorialMode scene]]; + } else if ([name isEqual:@"Collect"]) + { + [[CCDirector sharedDirector] replaceScene:[ClassicGameMode scene]]; + } + } else { + UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"To unlock this game mode:" message:unlockCondition delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; + [alertView show]; + [alertView release]; } } -- cgit 1.4.1