From 1d9ed882de4e2e3a53cdd5e90edc25e8ae10af1b Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sun, 7 Aug 2011 10:04:54 -0400 Subject: Implemented tutorial bubbles GameLayer now has support for pausing game flow and displaying a tutorial bubble that the user can tap to dismiss. No code has been written, however, to make use of this, because I think it may be simpler to abstract GameLayer out somewhat and create a separate game mode for the tutorial. Deliberation required. PauseLayer has also been removed and the behavior has been brought into GameLayer. Refs #193 --- Classes/Cart_CollectAppDelegate.m | 4 +- Classes/GameLayer.h | 14 ++- Classes/GameLayer.m | 84 ++++++++++++++++-- Classes/PauseLayer.h | 22 ----- Classes/PauseLayer.m | 68 --------------- Classes/TutorialBubble.h | 29 +++++++ Classes/TutorialBubble.m | 177 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 300 insertions(+), 98 deletions(-) delete mode 100755 Classes/PauseLayer.h delete mode 100755 Classes/PauseLayer.m create mode 100644 Classes/TutorialBubble.h create mode 100644 Classes/TutorialBubble.m (limited to 'Classes') diff --git a/Classes/Cart_CollectAppDelegate.m b/Classes/Cart_CollectAppDelegate.m index 201422f..7547601 100755 --- a/Classes/Cart_CollectAppDelegate.m +++ b/Classes/Cart_CollectAppDelegate.m @@ -139,9 +139,9 @@ -(void) applicationDidEnterBackground:(UIApplication*)application { [[CCDirector sharedDirector] stopAnimation]; - if ([[CCDirector sharedDirector] runningScene].tag == 436) + if ([[CCDirector sharedDirector] runningScene].tag == GAME_SCENE) { - [[CCDirector sharedDirector] replaceScene:[PauseLayer sceneWithScene:[[CCDirector sharedDirector] runningScene]]]; + [((GameLayer*)[[[CCDirector sharedDirector] runningScene] getChildByTag:GAME_LAYER]) pause]; } } diff --git a/Classes/GameLayer.h b/Classes/GameLayer.h index 88a1406..e72b551 100755 --- a/Classes/GameLayer.h +++ b/Classes/GameLayer.h @@ -15,9 +15,13 @@ #import "Rock.h" #import "GameOverLayer.h" #import "ValuableObject.h" -#import "PauseLayer.h" #import "CocosDenshion.h" #import "SimpleAudioEngine.h" +#import "TutorialBubble.h" +#import "MainMenuLayer.h" + +#define GAME_SCENE 436 +#define GAME_LAYER 437 @interface GameLayer : CCLayer { NSMutableSet* objects; @@ -28,11 +32,19 @@ int lives; float addSpeed; CCSprite* cartSprite; + TutorialBubble* currentTutorial; + + CCLayerColor* shadedLayer; + CCLayer* pauseLayer; } +@property (nonatomic,retain) TutorialBubble* currentTutorial; + (CCScene*)scene; - (id)init; - (void)updateLabels; - (void)pause; +- (void)unpause; +- (void)mainmenu; +- (void)endTutorial; @end diff --git a/Classes/GameLayer.m b/Classes/GameLayer.m index 32ca483..2ec8ef5 100755 --- a/Classes/GameLayer.m +++ b/Classes/GameLayer.m @@ -11,6 +11,8 @@ @implementation GameLayer +@synthesize currentTutorial; + + (CCScene*)scene { CCScene* scene = [CCScene node]; @@ -19,9 +21,10 @@ [scene addChild:backgroundLayer]; GameLayer* layer = [GameLayer node]; + layer.tag = GAME_LAYER; [scene addChild:layer]; - scene.tag = 436; + scene.tag = GAME_SCENE; return scene; } @@ -266,13 +269,13 @@ return self; } --(void) onEnter +- (void)onEnter { [super onEnter]; [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 60)]; - [self schedule:@selector(tick:) interval:1.0f/60.0f]; - [self schedule:@selector(randomlyAddObject:) interval:addSpeed]; + [self schedule:@selector(tick:) interval:1.0f/60.0f]; + [self schedule:@selector(randomlyAddObject:) interval:addSpeed]; } - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration @@ -295,7 +298,78 @@ - (void)pause { - [[CCDirector sharedDirector] replaceScene:[PauseLayer sceneWithScene:[[CCDirector sharedDirector] runningScene]]]; + if (self.currentTutorial != nil) + { + [self.currentTutorial removeFromSuperview]; + } + + [self pauseSchedulerAndActions]; + + shadedLayer = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 127)]; + [[[CCDirector sharedDirector] runningScene] addChild:shadedLayer]; + + pauseLayer = [CCLayer node]; + CCLabelBMFont* scoreLabel2 = [CCLabelBMFont labelWithString:@"PAUSE" fntFile:@"helvetica.fnt"]; + scoreLabel2.position = ccp(240,90); + [pauseLayer addChild:scoreLabel2]; + + CCMenuItemImage* pauseButton = [CCMenuItemImage itemFromNormalImage:@"pause2.png" selectedImage:@"pause.png" target:self selector:@selector(unpause)]; + CCMenu* pauseMenu = [CCMenu menuWithItems:pauseButton, nil]; + [pauseMenu setPosition:ccp(480-8-16, 320-8-16)]; + [pauseLayer addChild:pauseMenu]; + + CCMenuItemImage* newgameMenuItem = [CCMenuItemImage itemFromNormalImage:@"back.png" selectedImage:@"back2.png" target:self selector:@selector(mainmenu)]; + CCMenu* myMenu = [CCMenu menuWithItems:newgameMenuItem, nil]; + myMenu.position = ccp(240, 60); + [pauseLayer addChild:myMenu]; + + [[[CCDirector sharedDirector] runningScene] addChild:pauseLayer]; +} + +- (void)unpause +{ + [[[CCDirector sharedDirector] runningScene] removeChild:shadedLayer cleanup:YES]; + [[[CCDirector sharedDirector] runningScene] removeChild:pauseLayer cleanup:YES]; + + shadedLayer = nil; + pauseLayer = nil; + + if (self.currentTutorial != nil) + { + [[[CCDirector sharedDirector] openGLView] addSubview:self.currentTutorial]; + } else { + [self resumeSchedulerAndActions]; + } +} + +- (void)mainmenu +{ + [[CCDirector sharedDirector] replaceScene:[MainMenuLayer scene]]; +} + +- (void)setCurrentTutorial:(TutorialBubble *)m_currentTutorial +{ + @synchronized(self) + { + if (currentTutorial != m_currentTutorial) + { + [currentTutorial release]; + currentTutorial = [m_currentTutorial retain]; + } + } + + if (currentTutorial != nil) + { + [currentTutorial setTarget:self action:@selector(endTutorial)]; + [[[CCDirector sharedDirector] openGLView] addSubview:currentTutorial]; + [self pauseSchedulerAndActions]; + } +} + +- (void)endTutorial +{ + self.currentTutorial = nil; + [self resumeSchedulerAndActions]; } @end diff --git a/Classes/PauseLayer.h b/Classes/PauseLayer.h deleted file mode 100755 index aae5d6c..0000000 --- a/Classes/PauseLayer.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// PauseLayer.h -// Cart Collect -// -// Created by iD Student Account on 7/20/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import -#import "cocos2d.h" -#import "GameLayer.h" - -@interface PauseLayer : CCLayer { - CCScene* game; -} - -+ (CCScene*)sceneWithScene:(CCScene*)scene; -- (id)initWithScene:(CCScene*)scene; -- (void)unpause; -- (void)newgame; - -@end diff --git a/Classes/PauseLayer.m b/Classes/PauseLayer.m deleted file mode 100755 index 53574b2..0000000 --- a/Classes/PauseLayer.m +++ /dev/null @@ -1,68 +0,0 @@ -// -// PauseLayer.m -// Cart Collect -// -// Created by iD Student Account on 7/20/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import "PauseLayer.h" - -@implementation PauseLayer - -+ (CCScene*)sceneWithScene:(CCScene*)scene2 -{ - CCScene* scene = [CCScene node]; - - CCLayerColor* backgroundLayer = [CCLayerColor layerWithColor:ccc4(255, 255, 255, 255)]; - CCSprite* backgroundImage = [CCSprite spriteWithFile:@"SeaBeach.png"]; - backgroundImage.position = ccp(240,160); - [backgroundLayer addChild:backgroundImage]; - [scene addChild:backgroundLayer]; - - CCLayerColor* backgroundLayer2 = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 127)]; - [scene addChild:backgroundLayer2]; - - PauseLayer* layer = [[[PauseLayer alloc] initWithScene:scene2] autorelease]; - [scene addChild:layer]; - - return scene; -} - -- (id)initWithScene:(CCScene*)scene -{ - self = [super init]; - - if (nil != self) - { - game = [scene retain]; - - CCLabelBMFont* scoreLabel = [CCLabelBMFont labelWithString:@"PAUSE" fntFile:@"helvetica.fnt"]; - scoreLabel.position = ccp(240,90); - [self addChild:scoreLabel]; - - CCMenuItemImage* pauseButton = [CCMenuItemImage itemFromNormalImage:@"pause2.png" selectedImage:@"pause.png" target:self selector:@selector(unpause)]; - CCMenu* pauseMenu = [CCMenu menuWithItems:pauseButton, nil]; - [pauseMenu setPosition:ccp(480-8-16, 320-8-16)]; - [self addChild:pauseMenu]; - - CCMenuItemImage* newgameMenuItem = [CCMenuItemImage itemFromNormalImage:@"back.png" selectedImage:@"back2.png" target:self selector:@selector(newgame)]; - CCMenu* myMenu = [CCMenu menuWithItems:newgameMenuItem, nil]; - myMenu.position = ccp(240, 60); - [self addChild:myMenu]; - } - - return self; -} - -- (void)unpause -{ - [[CCDirector sharedDirector] replaceScene:game]; -} - -- (void)newgame -{ - [[CCDirector sharedDirector] replaceScene:[MainMenuLayer scene]]; -} - -@end diff --git a/Classes/TutorialBubble.h b/Classes/TutorialBubble.h new file mode 100644 index 0000000..4ce3352 --- /dev/null +++ b/Classes/TutorialBubble.h @@ -0,0 +1,29 @@ +// +// TutorialBubble.h +// Cart Collect +// +// Created by Starla Insigna on 8/4/11. +// Copyright 2011 Four Island. All rights reserved. +// + +#import +#import "cocos2d.h" + +@interface TutorialBubble : UIView { + UILabel* textView; + UIImage* background; + UIImageView* imageView; + UIImageView* arrowView; + UIButton* button; + id target; + SEL action; + NSString* name; +} + +@property (readonly) NSString* name; +- (id)initWithText:(NSString*)text name:(NSString*)name; +- (id)initWithText:(NSString*)text name:(NSString*)name spriteReference:(CCSprite*)spriteReference; +- (void)buttonPressed:(id)sender; +- (void)setTarget:(id)sender action:(SEL)action; + +@end diff --git a/Classes/TutorialBubble.m b/Classes/TutorialBubble.m new file mode 100644 index 0000000..b85aa31 --- /dev/null +++ b/Classes/TutorialBubble.m @@ -0,0 +1,177 @@ +// +// TutorialBubble.m +// Cart Collect +// +// Created by Starla Insigna on 8/4/11. +// Copyright 2011 Four Island. All rights reserved. +// + +#import "TutorialBubble.h" + +@implementation TutorialBubble + +@synthesize name; + +- (id)initWithText:(NSString*)text name:(NSString*)m_name +{ + self = [super init]; + + textView = [[UILabel alloc] init]; + textView.text = text; + textView.font = [UIFont systemFontOfSize:14.0f]; + CGSize size = [textView.text sizeWithFont:textView.font constrainedToSize:CGSizeMake(200, 300) lineBreakMode:UILineBreakModeWordWrap]; + textView.lineBreakMode = UILineBreakModeWordWrap; + textView.numberOfLines = 0; + textView.frame = CGRectMake(8, 8, size.width, size.height); + + button = [UIButton buttonWithType:UIButtonTypeCustom]; + [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; + + 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); + + CGSize boxSize = CGSizeMake(size.width, size.height); + + UIGraphicsBeginImageContext(CGSizeMake(boxSize.width+16, boxSize.height+16)); + CGContextRef context = UIGraphicsGetCurrentContext(); + UIGraphicsPushContext(context); + [topLeft drawInRect:CGRectMake(0, 0, 8, 8)]; + [topBorder drawInRect:CGRectMake(8, 0, boxSize.width, 8)]; + [topRight drawInRect:CGRectMake(8+boxSize.width, 0, 8, 8)]; + [rightBorder drawInRect:CGRectMake(8+boxSize.width, 8, 8, boxSize.height)]; + [bottomRight drawInRect:CGRectMake(8+boxSize.width, 8+boxSize.height, 8, 8)]; + [bottomBorder drawInRect:CGRectMake(8, 8+boxSize.height, boxSize.width, 8)]; + [bottomLeft drawInRect:CGRectMake(0, 8+boxSize.height, 8, 8)]; + [leftBorder drawInRect:CGRectMake(0, 8, 8, boxSize.height)]; + CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); + CGContextFillRect(context, CGRectMake(8, 8, boxSize.width, boxSize.height)); + UIGraphicsPopContext(); + background = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + imageView = [[UIImageView alloc] initWithImage:background]; + [imageView setFrame:CGRectMake(0, 0, boxSize.width+16, boxSize.height+16)]; + [button addSubview:imageView]; + [button addSubview:textView]; + + button.frame = CGRectMake(0, 0, boxSize.width+16, boxSize.height+16); + [self addSubview:button]; + self.frame = CGRectMake(240-(boxSize.width+16)/2, 160-(boxSize.height+16)/2, boxSize.width+16, boxSize.height+16); + + name = [m_name retain]; + + return self; +} + +- (id)initWithText:(NSString*)text name:(NSString*)m_name spriteReference:(CCSprite*)spriteReference +{ + self = [self initWithText:text name:m_name]; + + button.frame = CGRectMake(8, 8, button.frame.size.width, button.frame.size.height); + self.frame = CGRectMake(0, 0, button.frame.size.width+16, button.frame.size.height+16); + + CGRect spriteBounds = CGRectMake(spriteReference.position.x-spriteReference.contentSize.width/2, 320-spriteReference.position.y-spriteReference.contentSize.height/2, spriteReference.contentSize.width*spriteReference.scale, spriteReference.contentSize.height*spriteReference.scale); + CGPoint boxLoc; + CGPoint arrowLoc; + int arrowRotation; + + if (spriteBounds.origin.y > self.frame.size.height) + { + arrowRotation = 0; + + if (CGRectGetMidX(spriteBounds) < button.frame.size.width) + { + boxLoc = CGPointMake(0, spriteBounds.origin.y-self.frame.size.height - 8); + arrowLoc = CGPointMake(spriteBounds.origin.x + 4, 8+button.frame.size.height); + } else { + boxLoc = CGPointMake(CGRectGetMaxX(spriteBounds) - self.frame.size.width, spriteBounds.origin.y-self.frame.size.height - 8); + arrowLoc = CGPointMake(button.frame.size.width - spriteBounds.size.width/2 + 4, 8+button.frame.size.height); + } + } else if (spriteBounds.origin.x > self.frame.size.width) + { + arrowRotation = 270; + + if (CGRectGetMidY(spriteBounds) < button.frame.size.height) + { + boxLoc = CGPointMake(spriteBounds.origin.x-self.frame.size.width-8, 0); + arrowLoc = CGPointMake(8+button.frame.size.width, spriteBounds.origin.y+4); + } else { + boxLoc = CGPointMake(spriteBounds.origin.y-self.frame.size.width-8, CGRectGetMaxY(spriteBounds) - self.frame.size.height); + arrowLoc = CGPointMake(8+button.frame.size.width, button.frame.size.height - spriteBounds.size.height/2 + 4); + } + } else if ((480 - CGRectGetMaxX(spriteBounds)) > self.frame.size.width) + { + arrowRotation = 90; + + if (CGRectGetMidY(spriteBounds) < button.frame.size.height) + { + boxLoc = CGPointMake(CGRectGetMaxX(spriteBounds), 0); + arrowLoc = CGPointMake(0, spriteBounds.origin.y+4); + } else { + boxLoc = CGPointMake(CGRectGetMaxX(spriteBounds), CGRectGetMaxY(spriteBounds) - self.frame.size.height); + arrowLoc = CGPointMake(0, button.frame.size.height - spriteBounds.size.height/2 + 4); + } + } + + CGImageRef framestuff = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"framestuff" ofType:@"png"]] CGImage]; + CGImageRef arrowRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(0, 32, 8, 8)); + UIImage* arrow = [UIImage imageWithCGImage:arrowRef]; + CGImageRelease(arrowRef); + + arrowView = [[UIImageView alloc] initWithImage:arrow]; + arrowView.transform = CGAffineTransformMakeRotation(arrowRotation * (M_PI / 180)); + arrowView.frame = CGRectMake(arrowLoc.x, arrowLoc.y, 8, 8); + [self addSubview:arrowView]; + + self.frame = CGRectMake(boxLoc.x, boxLoc.y, self.frame.size.width, self.frame.size.height); + + return self; +} + +- (void)buttonPressed:(id)sender +{ + [self removeFromSuperview]; + + if (target != nil) + { + [target performSelector:action]; + } +} + +- (void)setTarget:(id)sender action:(SEL)m_action +{ + target = sender; + action = m_action; +} + +- (void)dealloc +{ + [name release]; + + [super dealloc]; +} + +@end -- cgit 1.4.1