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 --- Cart Collect.xcodeproj/project.pbxproj | 46 +++++---- 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 +++++++++++++++++++++++++++++++++ Resources/framestuff.png | Bin 0 -> 678 bytes 9 files changed, 329 insertions(+), 115 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 create mode 100755 Resources/framestuff.png diff --git a/Cart Collect.xcodeproj/project.pbxproj b/Cart Collect.xcodeproj/project.pbxproj index 2ca790c..b3c5dfa 100755 --- a/Cart Collect.xcodeproj/project.pbxproj +++ b/Cart Collect.xcodeproj/project.pbxproj @@ -40,7 +40,6 @@ 3F7D0F4F13D8F17C00B6CE14 /* newgame2.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F7D0F4B13D8F17C00B6CE14 /* newgame2.png */; }; 3F8394F313D732330059AEE8 /* pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F8394F213D732330059AEE8 /* pause.png */; }; 3F8394F513D7328E0059AEE8 /* pause2.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F8394F413D7328E0059AEE8 /* pause2.png */; }; - 3F8394F813D7336D0059AEE8 /* PauseLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F8394F713D7336D0059AEE8 /* PauseLayer.m */; }; 3F83955313D739B10059AEE8 /* MainMenuLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F83955213D739B10059AEE8 /* MainMenuLayer.m */; }; 3F8395B813D744420059AEE8 /* cartdata.sqlite3 in Resources */ = {isa = PBXBuildFile; fileRef = 3F8395B713D744420059AEE8 /* cartdata.sqlite3 */; }; 3F8395D113D746200059AEE8 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F8395D013D746200059AEE8 /* libsqlite3.0.dylib */; }; @@ -85,6 +84,8 @@ 50F4144910692EE7002A0D5E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 50F4144410692EE7002A0D5E /* Default.png */; }; 50F4144A10692EE7002A0D5E /* fps_images.png in Resources */ = {isa = PBXBuildFile; fileRef = 50F4144510692EE7002A0D5E /* fps_images.png */; }; 50F4144B10692EE7002A0D5E /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 50F4144610692EE7002A0D5E /* Icon.png */; }; + 6C29041013EAEB590032DA0F /* TutorialBubble.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C29040F13EAEB590032DA0F /* TutorialBubble.m */; }; + 6C29041213EAEC8A0032DA0F /* framestuff.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C29041113EAEC8A0032DA0F /* framestuff.png */; }; 6C5179C613DF3839006F1F38 /* Morning1.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C5179C513DF3839006F1F38 /* Morning1.png */; }; DC6640030F83B3EA000B3E49 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640020F83B3EA000B3E49 /* AudioToolbox.framework */; }; DC6640050F83B3EA000B3E49 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640040F83B3EA000B3E49 /* OpenAL.framework */; }; @@ -330,8 +331,6 @@ 3F8394AC13D72E2C0059AEE8 /* ValuableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValuableObject.h; sourceTree = ""; }; 3F8394F213D732330059AEE8 /* pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause.png; sourceTree = ""; }; 3F8394F413D7328E0059AEE8 /* pause2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause2.png; sourceTree = ""; }; - 3F8394F613D7336D0059AEE8 /* PauseLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PauseLayer.h; sourceTree = ""; }; - 3F8394F713D7336D0059AEE8 /* PauseLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PauseLayer.m; sourceTree = ""; }; 3F83955113D739B10059AEE8 /* MainMenuLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainMenuLayer.h; sourceTree = ""; }; 3F83955213D739B10059AEE8 /* MainMenuLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainMenuLayer.m; sourceTree = ""; }; 3F8395B713D744420059AEE8 /* cartdata.sqlite3 */ = {isa = PBXFileReference; lastKnownFileType = file; path = cartdata.sqlite3; sourceTree = ""; }; @@ -374,6 +373,9 @@ 50F4144510692EE7002A0D5E /* fps_images.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = fps_images.png; sourceTree = ""; }; 50F4144610692EE7002A0D5E /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 50F4144710692EE7002A0D5E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6C29040E13EAEB590032DA0F /* TutorialBubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TutorialBubble.h; sourceTree = ""; }; + 6C29040F13EAEB590032DA0F /* TutorialBubble.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TutorialBubble.m; sourceTree = ""; }; + 6C29041113EAEC8A0032DA0F /* framestuff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = framestuff.png; sourceTree = ""; }; 6C5179C513DF3839006F1F38 /* Morning1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Morning1.png; sourceTree = ""; }; DC6640020F83B3EA000B3E49 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; DC6640040F83B3EA000B3E49 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; @@ -654,6 +656,7 @@ 2D500B1D0D5A766B00DBA0E3 /* Classes */ = { isa = PBXGroup; children = ( + 6C5887E313EE3ED900B5A80A /* Items */, E0F81035120A173C005866B8 /* GameConfig.h */, E0F81036120A173C005866B8 /* RootViewController.h */, E0F81037120A173C005866B8 /* RootViewController.m */, @@ -661,27 +664,16 @@ 507022A2107672FA00393637 /* Cart_CollectAppDelegate.m */, 3FE79CD213D4DE37001A6B93 /* GameLayer.h */, 3FE79CD313D4DE37001A6B93 /* GameLayer.m */, - 3F6C7C4D13D5E1B600C038FE /* FallingObject.h */, - 3F6C7C4E13D5E1B600C038FE /* FallingObject.m */, - 3F6C7C6B13D5E51800C038FE /* Cherry.h */, - 3F6C7C6C13D5E51800C038FE /* Cherry.m */, - 3F6C7C6E13D5E54E00C038FE /* Bottle.h */, - 3F6C7C6F13D5E54E00C038FE /* Bottle.m */, - 3F6C7C7113D5E57100C038FE /* OneUp.h */, - 3F6C7C7213D5E57100C038FE /* OneUp.m */, - 3F6C7EE213D636CF00C038FE /* Rock.h */, - 3F6C7EE313D636CF00C038FE /* Rock.m */, 3F6C7EE713D6377D00C038FE /* GameOverLayer.h */, 3F6C7EE813D6377D00C038FE /* GameOverLayer.m */, - 3F8394AC13D72E2C0059AEE8 /* ValuableObject.h */, - 3F8394F613D7336D0059AEE8 /* PauseLayer.h */, - 3F8394F713D7336D0059AEE8 /* PauseLayer.m */, 3F83955213D739B10059AEE8 /* MainMenuLayer.m */, 3F83955113D739B10059AEE8 /* MainMenuLayer.h */, 3F03221413D78F8C00E6A708 /* HighscoreListController.h */, 3F03221513D78F8C00E6A708 /* HighscoreListController.m */, 3F03221713D7904E00E6A708 /* Highscore.h */, 3F03221813D7904E00E6A708 /* Highscore.m */, + 6C29040E13EAEB590032DA0F /* TutorialBubble.h */, + 6C29040F13EAEB590032DA0F /* TutorialBubble.m */, ); path = Classes; sourceTree = ""; @@ -699,6 +691,7 @@ 3F6C7F4D13D647B600C038FE /* Sprites */ = { isa = PBXGroup; children = ( + 6C29041113EAEC8A0032DA0F /* framestuff.png */, 3F6C7EE013D636BE00C038FE /* rock.png */, 3F63FA3E13D4EE53003B3D14 /* oneup.png */, 3F63FA3C13D4EE4D003B3D14 /* cherry.png */, @@ -828,6 +821,24 @@ path = Resources; sourceTree = ""; }; + 6C5887E313EE3ED900B5A80A /* Items */ = { + isa = PBXGroup; + children = ( + 3F6C7C4D13D5E1B600C038FE /* FallingObject.h */, + 3F6C7C4E13D5E1B600C038FE /* FallingObject.m */, + 3F6C7C6B13D5E51800C038FE /* Cherry.h */, + 3F6C7C6C13D5E51800C038FE /* Cherry.m */, + 3F6C7C6E13D5E54E00C038FE /* Bottle.h */, + 3F6C7C6F13D5E54E00C038FE /* Bottle.m */, + 3F6C7C7113D5E57100C038FE /* OneUp.h */, + 3F6C7C7213D5E57100C038FE /* OneUp.m */, + 3F6C7EE213D636CF00C038FE /* Rock.h */, + 3F6C7EE313D636CF00C038FE /* Rock.m */, + 3F8394AC13D72E2C0059AEE8 /* ValuableObject.h */, + ); + name = Items; + sourceTree = ""; + }; E02BBB19126CC2F5006E46A2 /* cocos2d */ = { isa = PBXGroup; children = ( @@ -1289,6 +1300,7 @@ 3F7D0F4E13D8F17C00B6CE14 /* newgame.png in Resources */, 3F7D0F4F13D8F17C00B6CE14 /* newgame2.png in Resources */, 6C5179C613DF3839006F1F38 /* Morning1.png in Resources */, + 6C29041213EAEC8A0032DA0F /* framestuff.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1325,10 +1337,10 @@ 3F6C7C7313D5E57100C038FE /* OneUp.m in Sources */, 3F6C7EE413D636CF00C038FE /* Rock.m in Sources */, 3F6C7EE913D6377D00C038FE /* GameOverLayer.m in Sources */, - 3F8394F813D7336D0059AEE8 /* PauseLayer.m in Sources */, 3F83955313D739B10059AEE8 /* MainMenuLayer.m in Sources */, 3F03221613D78F8C00E6A708 /* HighscoreListController.m in Sources */, 3F03221913D7904E00E6A708 /* Highscore.m in Sources */, + 6C29041013EAEB590032DA0F /* TutorialBubble.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 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 diff --git a/Resources/framestuff.png b/Resources/framestuff.png new file mode 100755 index 0000000..3a5c8d0 Binary files /dev/null and b/Resources/framestuff.png differ -- cgit 1.4.1