From d19677f9f73d8fe7436982bdf8d40f69d69d1b43 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Fri, 12 Aug 2011 09:51:50 -0400 Subject: Added tutorial mode GameLayer was also renamed to ClassicGameMode and its pause functionality and score/lives counters were moved out to GameMode. FallingObjectDelegate was created to allow for custom code to be run when items were caught/missed, something that is used extensively by tutorial mode. Important: Cart Collect's bundle identifier was changed in this revision from com.fourisland.Cart-Collect to com.apatheticink.Cart-Collect, so ensure that before attempting to compile/run this build, you clear your build directory and remove the old version of Cart Collect from your device. Closes #193 --- Cart Collect.xcodeproj/project.pbxproj | 40 ++-- Classes/Cart.h | 2 + Classes/Cart.m | 10 +- Classes/Cart_CollectAppDelegate.m | 4 +- Classes/ClassicGameMode.h | 20 ++ Classes/ClassicGameMode.m | 166 ++++++++++++++++ Classes/FallingObject.h | 3 + Classes/FallingObject.m | 25 ++- Classes/FallingObjectDelegate.h | 20 ++ Classes/GameLayer.h | 31 --- Classes/GameLayer.m | 284 --------------------------- Classes/GameMode.h | 19 +- Classes/GameMode.m | 112 ++++++++++- Classes/MainMenuLayer.m | 12 +- Classes/TutorialBubble.m | 13 +- Classes/TutorialMode.h | 26 +++ Classes/TutorialMode.m | 349 +++++++++++++++++++++++++++++++++ Resources/Info.plist | 4 +- Resources/skiptutorial.png | Bin 0 -> 2871 bytes Resources/skiptutorial2.png | Bin 0 -> 3193 bytes 20 files changed, 792 insertions(+), 348 deletions(-) create mode 100755 Classes/ClassicGameMode.h create mode 100755 Classes/ClassicGameMode.m create mode 100644 Classes/FallingObjectDelegate.h delete mode 100755 Classes/GameLayer.h delete mode 100755 Classes/GameLayer.m create mode 100644 Classes/TutorialMode.h create mode 100644 Classes/TutorialMode.m create mode 100644 Resources/skiptutorial.png create mode 100644 Resources/skiptutorial2.png diff --git a/Cart Collect.xcodeproj/project.pbxproj b/Cart Collect.xcodeproj/project.pbxproj index a7baa89..ebc6afe 100755 --- a/Cart Collect.xcodeproj/project.pbxproj +++ b/Cart Collect.xcodeproj/project.pbxproj @@ -43,7 +43,7 @@ 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 */; }; - 3FE79CD413D4DE37001A6B93 /* GameLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FE79CD313D4DE37001A6B93 /* GameLayer.m */; }; + 3FE79CD413D4DE37001A6B93 /* ClassicGameMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FE79CD313D4DE37001A6B93 /* ClassicGameMode.m */; }; 504DFC4810AF1557006D82FE /* CLScoreServerPost.h in Headers */ = {isa = PBXBuildFile; fileRef = 504DFC4210AF1557006D82FE /* CLScoreServerPost.h */; }; 504DFC4910AF1557006D82FE /* CLScoreServerPost.m in Sources */ = {isa = PBXBuildFile; fileRef = 504DFC4310AF1557006D82FE /* CLScoreServerPost.m */; }; 504DFC4A10AF1557006D82FE /* CLScoreServerRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 504DFC4410AF1557006D82FE /* CLScoreServerRequest.h */; }; @@ -91,6 +91,9 @@ 6C29041213EAEC8A0032DA0F /* framestuff.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C29041113EAEC8A0032DA0F /* framestuff.png */; }; 6C5179C613DF3839006F1F38 /* Morning1.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C5179C513DF3839006F1F38 /* Morning1.png */; }; 6CC89DD913F2F4E6003704F7 /* Entitlements.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6CC89DD813F2F4E6003704F7 /* Entitlements.plist */; }; + 6CC89DDF13F31413003704F7 /* TutorialMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC89DDE13F31413003704F7 /* TutorialMode.m */; }; + 6CF29FF013F5580400C83428 /* skiptutorial.png in Resources */ = {isa = PBXBuildFile; fileRef = 6CF29FEE13F5580400C83428 /* skiptutorial.png */; }; + 6CF29FF113F5580400C83428 /* skiptutorial2.png in Resources */ = {isa = PBXBuildFile; fileRef = 6CF29FEF13F5580400C83428 /* skiptutorial2.png */; }; DC6640030F83B3EA000B3E49 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640020F83B3EA000B3E49 /* AudioToolbox.framework */; }; DC6640050F83B3EA000B3E49 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6640040F83B3EA000B3E49 /* OpenAL.framework */; }; DCCBF1B70F6022AE0040855A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCBF1B60F6022AE0040855A /* CoreGraphics.framework */; }; @@ -338,8 +341,8 @@ 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 = ""; }; 3F8395D013D746200059AEE8 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; }; - 3FE79CD213D4DE37001A6B93 /* GameLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameLayer.h; sourceTree = ""; }; - 3FE79CD313D4DE37001A6B93 /* GameLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GameLayer.m; sourceTree = ""; }; + 3FE79CD213D4DE37001A6B93 /* ClassicGameMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassicGameMode.h; sourceTree = ""; }; + 3FE79CD313D4DE37001A6B93 /* ClassicGameMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ClassicGameMode.m; sourceTree = ""; }; 504DFC4210AF1557006D82FE /* CLScoreServerPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLScoreServerPost.h; sourceTree = ""; }; 504DFC4310AF1557006D82FE /* CLScoreServerPost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLScoreServerPost.m; sourceTree = ""; }; 504DFC4410AF1557006D82FE /* CLScoreServerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLScoreServerRequest.h; sourceTree = ""; }; @@ -387,6 +390,11 @@ 6C29041113EAEC8A0032DA0F /* framestuff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = framestuff.png; sourceTree = ""; }; 6C5179C513DF3839006F1F38 /* Morning1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Morning1.png; sourceTree = ""; }; 6CC89DD813F2F4E6003704F7 /* Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Entitlements.plist; sourceTree = ""; }; + 6CC89DDD13F31413003704F7 /* TutorialMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TutorialMode.h; sourceTree = ""; }; + 6CC89DDE13F31413003704F7 /* TutorialMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TutorialMode.m; sourceTree = ""; }; + 6CC89DE013F3197F003704F7 /* FallingObjectDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FallingObjectDelegate.h; sourceTree = ""; }; + 6CF29FEE13F5580400C83428 /* skiptutorial.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = skiptutorial.png; sourceTree = ""; }; + 6CF29FEF13F5580400C83428 /* skiptutorial2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = skiptutorial2.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; }; DCCBF1B60F6022AE0040855A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -736,6 +744,8 @@ 3F7D0EC713D8E6B000B6CE14 /* Buttons */ = { isa = PBXGroup; children = ( + 6CF29FEE13F5580400C83428 /* skiptutorial.png */, + 6CF29FEF13F5580400C83428 /* skiptutorial2.png */, 3F7D0F4813D8F17C00B6CE14 /* highscores.png */, 3F7D0F4913D8F17C00B6CE14 /* highscores2.png */, 3F7D0F4A13D8F17C00B6CE14 /* newgame.png */, @@ -836,8 +846,10 @@ children = ( 6C0C141213F20E98003A31B2 /* GameMode.h */, 6C0C141313F20E98003A31B2 /* GameMode.m */, - 3FE79CD213D4DE37001A6B93 /* GameLayer.h */, - 3FE79CD313D4DE37001A6B93 /* GameLayer.m */, + 3FE79CD213D4DE37001A6B93 /* ClassicGameMode.h */, + 3FE79CD313D4DE37001A6B93 /* ClassicGameMode.m */, + 6CC89DDD13F31413003704F7 /* TutorialMode.h */, + 6CC89DDE13F31413003704F7 /* TutorialMode.m */, ); name = "Game Modes"; sourceTree = ""; @@ -859,6 +871,7 @@ 6C0C140D13F1C3EC003A31B2 /* ValuableObject.m */, 6C0C140F13F2099B003A31B2 /* Cart.h */, 6C0C141013F2099B003A31B2 /* Cart.m */, + 6CC89DE013F3197F003704F7 /* FallingObjectDelegate.h */, ); name = Items; sourceTree = ""; @@ -1325,6 +1338,8 @@ 6C5179C613DF3839006F1F38 /* Morning1.png in Resources */, 6C29041213EAEC8A0032DA0F /* framestuff.png in Resources */, 6CC89DD913F2F4E6003704F7 /* Entitlements.plist in Resources */, + 6CF29FF013F5580400C83428 /* skiptutorial.png in Resources */, + 6CF29FF113F5580400C83428 /* skiptutorial2.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1338,7 +1353,7 @@ 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 507022A4107672FA00393637 /* Cart_CollectAppDelegate.m in Sources */, E0F81038120A173C005866B8 /* RootViewController.m in Sources */, - 3FE79CD413D4DE37001A6B93 /* GameLayer.m in Sources */, + 3FE79CD413D4DE37001A6B93 /* ClassicGameMode.m in Sources */, 3F6C7C4F13D5E1B600C038FE /* FallingObject.m in Sources */, 3F6C7C6D13D5E51800C038FE /* Cherry.m in Sources */, 3F6C7C7013D5E54E00C038FE /* Bottle.m in Sources */, @@ -1352,6 +1367,7 @@ 6C0C140E13F1C3EC003A31B2 /* ValuableObject.m in Sources */, 6C0C141113F2099B003A31B2 /* Cart.m in Sources */, 6C0C141413F20E98003A31B2 /* GameMode.m in Sources */, + 6CC89DDF13F31413003704F7 /* TutorialMode.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1487,8 +1503,8 @@ "-ObjC", ); PRODUCT_NAME = "Cart Collect"; - PROVISIONING_PROFILE = "D4BA5E2C-C75B-4F36-A5F6-AF4A3C6072A5"; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = "D4BA5E2C-C75B-4F36-A5F6-AF4A3C6072A5"; + PROVISIONING_PROFILE = "42DE7CBA-2166-4560-9EE8-5D227F4278B1"; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "42DE7CBA-2166-4560-9EE8-5D227F4278B1"; TARGETED_DEVICE_FAMILY = 1; WARNING_CFLAGS = "-Wall"; }; @@ -1513,8 +1529,8 @@ "-ObjC", ); PRODUCT_NAME = "Cart Collect"; - PROVISIONING_PROFILE = "D4BA5E2C-C75B-4F36-A5F6-AF4A3C6072A5"; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = "D4BA5E2C-C75B-4F36-A5F6-AF4A3C6072A5"; + PROVISIONING_PROFILE = "42DE7CBA-2166-4560-9EE8-5D227F4278B1"; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "42DE7CBA-2166-4560-9EE8-5D227F4278B1"; TARGETED_DEVICE_FAMILY = 1; WARNING_CFLAGS = "-Wall"; }; @@ -1597,8 +1613,8 @@ "-ObjC", ); PRODUCT_NAME = "Cart Collect"; - PROVISIONING_PROFILE = "D4BA5E2C-C75B-4F36-A5F6-AF4A3C6072A5"; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = "D4BA5E2C-C75B-4F36-A5F6-AF4A3C6072A5"; + PROVISIONING_PROFILE = "42DE7CBA-2166-4560-9EE8-5D227F4278B1"; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "42DE7CBA-2166-4560-9EE8-5D227F4278B1"; TARGETED_DEVICE_FAMILY = 1; WARNING_CFLAGS = "-Wall"; }; diff --git a/Classes/Cart.h b/Classes/Cart.h index d708d73..0ef1abf 100644 --- a/Classes/Cart.h +++ b/Classes/Cart.h @@ -12,9 +12,11 @@ @interface Cart : NSObject { CCSprite* sprite; float accelX; + BOOL immobile; } @property (readonly) CCSprite* sprite; +@property (assign) BOOL immobile; - (id)initWithSprite:(CCSprite*)sprite; - (void)tick; - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration; diff --git a/Classes/Cart.m b/Classes/Cart.m index 3046be3..45c370c 100644 --- a/Classes/Cart.m +++ b/Classes/Cart.m @@ -10,7 +10,7 @@ @implementation Cart -@synthesize sprite; +@synthesize sprite, immobile; - (id)initWithSprite:(CCSprite*)m_sprite { @@ -19,6 +19,7 @@ if (nil != self) { sprite = m_sprite; + immobile = NO; } return self; @@ -26,8 +27,11 @@ - (void)tick { - // Move the cart based on acceleration gathered from accelerometer - sprite.position = ccp(MIN(MAX(sprite.position.x+accelX, 16),464), sprite.position.y); + if (!immobile) + { + // Move the cart based on acceleration gathered from accelerometer + sprite.position = ccp(MIN(MAX(sprite.position.x+accelX, 16),464), sprite.position.y); + } } - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration diff --git a/Classes/Cart_CollectAppDelegate.m b/Classes/Cart_CollectAppDelegate.m index 7547601..158f660 100755 --- a/Classes/Cart_CollectAppDelegate.m +++ b/Classes/Cart_CollectAppDelegate.m @@ -10,7 +10,7 @@ #import "Cart_CollectAppDelegate.h" #import "GameConfig.h" -#import "GameLayer.h" +#import "GameMode.h" #import "RootViewController.h" #import "MainMenuLayer.h" @@ -141,7 +141,7 @@ if ([[CCDirector sharedDirector] runningScene].tag == GAME_SCENE) { - [((GameLayer*)[[[CCDirector sharedDirector] runningScene] getChildByTag:GAME_LAYER]) pause]; + [((GameMode*)[[[CCDirector sharedDirector] runningScene] getChildByTag:GAME_LAYER]) pause]; } } diff --git a/Classes/ClassicGameMode.h b/Classes/ClassicGameMode.h new file mode 100755 index 0000000..bbce029 --- /dev/null +++ b/Classes/ClassicGameMode.h @@ -0,0 +1,20 @@ +// +// GameLayer.h +// Cart Collect +// +// Created by iD Student Account on 7/18/11. +// Copyright 2011 __MyCompanyName__. All rights reserved. +// + +#import +#import "cocos2d.h" +#import "GameMode.h" + +@interface ClassicGameMode : GameMode { + float addSpeed; +} + +- (id)init; +- (void)randomlyAddObject:(ccTime)dt; + +@end diff --git a/Classes/ClassicGameMode.m b/Classes/ClassicGameMode.m new file mode 100755 index 0000000..eb766a1 --- /dev/null +++ b/Classes/ClassicGameMode.m @@ -0,0 +1,166 @@ +// +// GameLayer.m +// Cart Collect +// +// Created by iD Student Account on 7/18/11. +// Copyright 2011 __MyCompanyName__. All rights reserved. +// + +#import "ClassicGameMode.h" +#import "FallingObject.h" +#import "Cherry.h" +#import "Bottle.h" +#import "OneUp.h" +#import "Rock.h" +#import "GameOverLayer.h" +#import "SimpleAudioEngine.h" + +@implementation ClassicGameMode + +- (void)tick:(ccTime)dt +{ + int lastScore = score; + + [super tick:dt]; + + if (lives == 0) + { + [self unscheduleAllSelectors]; + + [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInT transitionWithDuration:1.5f scene:[GameOverLayer sceneWithScore:score]]]; + } else if (score > lastScore) + { + if ((lastScore < 6500) && (score >= 6500)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.6f]; + addSpeed = 0.6f; + } else if ((lastScore < 4500) && (score >= 4500)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.7f]; + addSpeed = 0.7f; + } else if ((lastScore < 2500) && (score >= 2500)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.8f]; + addSpeed = 0.8f; + } else if ((lastScore < 1500) && (score >= 1500)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.9f]; + addSpeed = 0.9f; + } else if ((lastScore < 500) && (score >= 500)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:1.0f]; + addSpeed = 1.0f; + } else if ((lastScore < 150) && (score >= 150)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:2.0f]; + addSpeed = 2.0f; + } + } +} + +- (void)randomlyAddObject:(ccTime)dt +{ + FallingObject* object; + int oneuppercent = 98 - (lives == 1 ? 1 : 0); + + if (score < 1000) + { + int randomval = arc4random()%100; + + if (randomval < 65) + { + object = [[Cherry alloc] init]; + } else if (randomval < oneuppercent) + { + object = [[Bottle alloc] init]; + } else { + object = [[OneUp alloc] init]; + } + } else { + int randomval = arc4random()%100; + + if (randomval < 40) + { + object = [[Cherry alloc] init]; + } else if (randomval < 70) + { + object = [[Rock alloc] init]; + } else if (randomval < oneuppercent) + { + object = [[Bottle alloc] init]; + } else { + object = [[OneUp alloc] init]; + } + } + + int objectX = arc4random()%448+16; + object.sprite.position = ccp(objectX, 360); + object.sprite.scale = 1; + [self addChild:object.sprite]; + + [objects addObject:object]; + [object release]; + + if (score >= 2000) + { + if (arc4random() % 100 > 80) + { + object = [[Rock alloc] init]; + + objectX = arc4random()%448+16; + object.sprite.position = ccp(objectX, 360); + object.sprite.scale = 1; + [self addChild:object.sprite]; + + [objects addObject:object]; + [object release]; + } + } + + if (score >= 4000) + { + if (arc4random() % 100 > 80) + { + object = [[Rock alloc] init]; + + objectX = arc4random()%448+16; + object.sprite.position = ccp(objectX, 360); + object.sprite.scale = 1; + [self addChild:object.sprite]; + + [objects addObject:object]; + [object release]; + } + } +} + +- (id)init +{ + self = [super init]; + + if (nil != self) + { + CCSprite* backgroundImage = [CCSprite spriteWithFile:@"SeaBeach.png"]; + backgroundImage.position = ccp(240, 160); + [self addChild:backgroundImage z:-1]; + + addSpeed = 2.5f; + } + + return self; +} + +- (void)onEnterTransitionDidFinish +{ + [super onEnterTransitionDidFinish]; + + [self schedule:@selector(randomlyAddObject:) interval:addSpeed]; +} + +@end diff --git a/Classes/FallingObject.h b/Classes/FallingObject.h index 0bda787..3e28903 100755 --- a/Classes/FallingObject.h +++ b/Classes/FallingObject.h @@ -8,14 +8,17 @@ #import #import "cocos2d.h" +#import "FallingObjectDelegate.h" @interface FallingObject : NSObject { CCSprite* sprite; int weight; + id delegate; } @property (readonly) CCSprite* sprite; @property (readonly) int weight; +@property (nonatomic,retain) id delegate; - (id)init; - (BOOL)tick; - (void)collideWithCart; diff --git a/Classes/FallingObject.m b/Classes/FallingObject.m index 515948e..85ea902 100755 --- a/Classes/FallingObject.m +++ b/Classes/FallingObject.m @@ -11,7 +11,7 @@ @implementation FallingObject -@synthesize sprite, weight; +@synthesize sprite, weight, delegate; - (id)init { @@ -46,6 +46,16 @@ { [self collideWithCart]; + if ((delegate != nil) && ([delegate respondsToSelector:@selector(didCatchItem:)])) + { + [delegate didCatchItem:self]; + } + + if ((delegate != nil) && ([delegate respondsToSelector:@selector(didDestroyItem:)])) + { + [delegate didDestroyItem:self]; + } + return YES; } } @@ -57,6 +67,16 @@ { [self collideWithFloor]; + if ((delegate != nil) && ([delegate respondsToSelector:@selector(didMissItem:)])) + { + [delegate didMissItem:self]; + } + + if ((delegate != nil) && ([delegate respondsToSelector:@selector(didDestroyItem:)])) + { + [delegate didDestroyItem:self]; + } + return YES; } @@ -75,7 +95,8 @@ - (void)dealloc { - [sprite release]; + [sprite.parent removeChild:sprite cleanup:YES]; + [delegate release]; [super dealloc]; } diff --git a/Classes/FallingObjectDelegate.h b/Classes/FallingObjectDelegate.h new file mode 100644 index 0000000..b5c03fb --- /dev/null +++ b/Classes/FallingObjectDelegate.h @@ -0,0 +1,20 @@ +// +// FallingObjectDelegate.h +// Cart Collect +// +// Created by Starla Insigna on 8/10/11. +// Copyright 2011 Four Island. All rights reserved. +// + +#import + +@class FallingObject; + +@protocol FallingObjectDelegate + +@optional +- (void)didCatchItem:(FallingObject*)item; +- (void)didMissItem:(FallingObject*)item; +- (void)didDestroyItem:(FallingObject*)item; + +@end diff --git a/Classes/GameLayer.h b/Classes/GameLayer.h deleted file mode 100755 index 128cbf2..0000000 --- a/Classes/GameLayer.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// GameLayer.h -// Cart Collect -// -// Created by iD Student Account on 7/18/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import -#import "cocos2d.h" -#import "TutorialBubble.h" -#import "GameMode.h" - -@interface GameLayer : GameMode { - CCLabelBMFont* scoreLabel; - CCLabelBMFont* livesLabel; - float addSpeed; - TutorialBubble* currentTutorial; - - CCLayerColor* shadedLayer; - CCLayer* pauseLayer; -} - -@property (nonatomic,retain) TutorialBubble* currentTutorial; -- (id)init; -- (void)pause; -- (void)unpause; -- (void)mainmenu; -- (void)endTutorial; - -@end diff --git a/Classes/GameLayer.m b/Classes/GameLayer.m deleted file mode 100755 index 95bc83b..0000000 --- a/Classes/GameLayer.m +++ /dev/null @@ -1,284 +0,0 @@ -// -// GameLayer.m -// Cart Collect -// -// Created by iD Student Account on 7/18/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import "GameLayer.h" -#import "FallingObject.h" -#import "Cherry.h" -#import "Bottle.h" -#import "OneUp.h" -#import "Rock.h" -#import "GameOverLayer.h" -#import "SimpleAudioEngine.h" -#import "MainMenuLayer.h" - -@implementation GameLayer - -@synthesize currentTutorial; - -- (void)tick:(ccTime)dt -{ - int lastScore = score; - - [super tick:dt]; - - if (lives == 0) - { - [self unscheduleAllSelectors]; - - [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInT transitionWithDuration:1.5f scene:[GameOverLayer sceneWithScore:score]]]; - } else if (score > lastScore) - { - if ((lastScore < 6500) && (score >= 6500)) - { - [self unschedule:@selector(randomlyAddObject:)]; - [self schedule:@selector(randomlyAddObject:) interval:0.6f]; - addSpeed = 0.6f; - } else if ((lastScore < 4500) && (score >= 4500)) - { - [self unschedule:@selector(randomlyAddObject:)]; - [self schedule:@selector(randomlyAddObject:) interval:0.7f]; - addSpeed = 0.7f; - } else if ((lastScore < 2500) && (score >= 2500)) - { - [self unschedule:@selector(randomlyAddObject:)]; - [self schedule:@selector(randomlyAddObject:) interval:0.8f]; - addSpeed = 0.8f; - } else if ((lastScore < 1500) && (score >= 1500)) - { - [self unschedule:@selector(randomlyAddObject:)]; - [self schedule:@selector(randomlyAddObject:) interval:0.9f]; - addSpeed = 0.9f; - } else if ((lastScore < 500) && (score >= 500)) - { - [self unschedule:@selector(randomlyAddObject:)]; - [self schedule:@selector(randomlyAddObject:) interval:1.0f]; - addSpeed = 1.0f; - } else if ((lastScore < 150) && (score >= 150)) - { - [self unschedule:@selector(randomlyAddObject:)]; - [self schedule:@selector(randomlyAddObject:) interval:2.0f]; - addSpeed = 2.0f; - } - } -} - -- (void)randomlyAddObject:(ccTime)dt -{ - FallingObject* object; - int oneuppercent = 98 - (lives == 1 ? 1 : 0); - - if (score < 1000) - { - int randomval = arc4random()%100; - - if (randomval < 65) - { - object = [[Cherry alloc] init]; - } else if (randomval < oneuppercent) - { - object = [[Bottle alloc] init]; - } else { - object = [[OneUp alloc] init]; - } - } else { - int randomval = arc4random()%100; - - if (randomval < 40) - { - object = [[Cherry alloc] init]; - } else if (randomval < 70) - { - object = [[Rock alloc] init]; - } else if (randomval < oneuppercent) - { - object = [[Bottle alloc] init]; - } else { - object = [[OneUp alloc] init]; - } - } - - int objectX = arc4random()%448+16; - object.sprite.position = ccp(objectX, 360); - object.sprite.scale = 1; - [self addChild:object.sprite]; - - [objects addObject:object]; - [object release]; - - if (score >= 2000) - { - if (arc4random() % 100 > 80) - { - object = [[Rock alloc] init]; - - objectX = arc4random()%448+16; - object.sprite.position = ccp(objectX, 360); - object.sprite.scale = 1; - [self addChild:object.sprite]; - - [objects addObject:object]; - [object release]; - } - } - - if (score >= 4000) - { - if (arc4random() % 100 > 80) - { - object = [[Rock alloc] init]; - - objectX = arc4random()%448+16; - object.sprite.position = ccp(objectX, 360); - object.sprite.scale = 1; - [self addChild:object.sprite]; - - [objects addObject:object]; - [object release]; - } - } -} - -- (id)init -{ - self = [super init]; - - int winWidth = [CCDirector sharedDirector].winSize.width; - //int winHeight = [CCDirector sharedDirector].winSize.height; - int cartScale = 2; - - if (self != nil) - { - CCSprite* backgroundImage = [CCSprite spriteWithFile:@"SeaBeach.png"]; - backgroundImage.position = ccp(240, 160); - [self addChild:backgroundImage z:0]; - - cart = [[Cart alloc] initWithSprite:[CCSprite spriteWithFile:@"cart.png"]]; - cart.sprite.position = ccp(winWidth/2, 22); - cart.sprite.scale = cartScale; - [self addChild:cart.sprite]; - - scoreLabel = [CCLabelBMFont labelWithString:@"Score: 0" fntFile:@"helvetica2.fnt"]; - scoreLabel.position = ccp(50, 300); - [self addChild:scoreLabel]; - - livesLabel = [CCLabelBMFont labelWithString:@"Lives: 3" fntFile:@"helvetica2.fnt"]; - livesLabel.position = ccp(50, 280); - [self addChild:livesLabel]; - - score = 0; - lives = 3; - - CCMenuItemImage* pauseButton = [CCMenuItemImage itemFromNormalImage:@"pause2.png" selectedImage:@"pause.png" target:self selector:@selector(pause)]; - CCMenu* pauseMenu = [CCMenu menuWithItems:pauseButton, nil]; - [pauseMenu setPosition:ccp(480-8-16, 320-8-16)]; - [self addChild:pauseMenu]; - - addSpeed = 2.5f; - } - - return self; -} - -- (void)onEnter -{ - [super onEnter]; - - [self schedule:@selector(randomlyAddObject:) interval:addSpeed]; -} - -- (void)setScore:(int)m_score -{ - score = m_score; - - [scoreLabel setString:[NSString stringWithFormat:@"Score: %d", score]]; -} - -- (void)setLives:(int)m_lives -{ - lives = m_lives; - - [livesLabel setString:[NSString stringWithFormat:@"Lives: %d", lives]]; -} - -- (void)pause -{ - 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/GameMode.h b/Classes/GameMode.h index bd47c90..370550c 100644 --- a/Classes/GameMode.h +++ b/Classes/GameMode.h @@ -17,11 +17,26 @@ int score; int lives; Cart* cart; + + CCLayerColor* shadedLayer; + CCLayer* pauseLayer; + + CCLabelBMFont* scoreLabel; + CCLabelBMFont* livesLabel; + + void (^delayedAction)(void); } @property (readonly) Cart* cart; -@property (assign) int score; -@property (assign) int lives; +@property (nonatomic,assign) int score; +@property (nonatomic,assign) int lives; ++ (CCScene*)scene; - (void)tick:(ccTime)dt; +- (BOOL)canPause; +- (void)pause; +- (void)unpause; +- (void)mainmenu; +- (void)scheduleDelayedAction:(void(^)(void))delayedAction delay:(float)delay; +- (void)runDelayedAction; @end diff --git a/Classes/GameMode.m b/Classes/GameMode.m index 6fa31e5..7afbf20 100644 --- a/Classes/GameMode.m +++ b/Classes/GameMode.m @@ -8,6 +8,7 @@ #import "GameMode.h" #import "FallingObject.h" +#import "MainMenuLayer.h" @implementation GameMode @@ -16,7 +17,7 @@ + (CCScene*)scene { CCScene* scene = [CCScene node]; - + GameMode* layer = [self node]; layer.tag = GAME_LAYER; [scene addChild:layer]; @@ -35,6 +36,30 @@ isAccelerometerEnabled_ = YES; objects = [[NSMutableSet alloc] init]; + + cart = [[Cart alloc] initWithSprite:[CCSprite spriteWithFile:@"cart.png"]]; + cart.sprite.position = ccp(240, 22); + cart.sprite.scale = 2; + [self addChild:cart.sprite]; + + scoreLabel = [CCLabelBMFont labelWithString:@"Score: 0" fntFile:@"helvetica2.fnt"]; + scoreLabel.position = ccp(50, 300); + [self addChild:scoreLabel]; + + livesLabel = [CCLabelBMFont labelWithString:@"Lives: 3" fntFile:@"helvetica2.fnt"]; + livesLabel.position = ccp(50, 280); + [self addChild:livesLabel]; + + score = 0; + lives = 3; + + if ([self canPause]) + { + CCMenuItemImage* pauseButton = [CCMenuItemImage itemFromNormalImage:@"pause2.png" selectedImage:@"pause.png" target:self selector:@selector(pause)]; + CCMenu* pauseMenu = [CCMenu menuWithItems:pauseButton, nil]; + [pauseMenu setPosition:ccp(480-8-16, 320-8-16)]; + [self addChild:pauseMenu]; + } } return self; @@ -45,9 +70,9 @@ [cart accelerometer:accelerometer didAccelerate:acceleration]; } -- (void)onEnter +- (void)onEnterTransitionDidFinish { - [super onEnter]; + [super onEnterTransitionDidFinish]; [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 60)]; [self schedule:@selector(tick:) interval:1.0f/60.0f]; @@ -61,13 +86,90 @@ { if ([object tick]) { - [object retain]; - [self removeChild:object.sprite cleanup:YES]; [objects removeObject:object]; } } } +- (BOOL)canPause +{ + return YES; +} + +- (void)pause +{ + if ([self canPause]) + { + [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; + + [self resumeSchedulerAndActions]; +} + +- (void)mainmenu +{ + [[CCDirector sharedDirector] replaceScene:[MainMenuLayer scene]]; +} + +- (void)setScore:(int)m_score +{ + score = m_score; + + [scoreLabel setString:[NSString stringWithFormat:@"Score: %d", score]]; +} + +- (void)setLives:(int)m_lives +{ + lives = m_lives; + + [livesLabel setString:[NSString stringWithFormat:@"Lives: %d", lives]]; +} + +- (void)scheduleDelayedAction:(void(^)(void))m_delayedAction delay:(float)delay +{ + delayedAction = Block_copy([m_delayedAction retain]); + + [self schedule:@selector(runDelayedAction) interval:delay]; +} + +- (void)runDelayedAction +{ + [self unschedule:@selector(runDelayedAction)]; + + delayedAction(); + [delayedAction release]; + delayedAction = nil; +} + - (void)dealloc { [objects release]; diff --git a/Classes/MainMenuLayer.m b/Classes/MainMenuLayer.m index 11cffd7..50c595f 100755 --- a/Classes/MainMenuLayer.m +++ b/Classes/MainMenuLayer.m @@ -8,7 +8,8 @@ #import "MainMenuLayer.h" #import "HighscoreListController.h" -#import "GameLayer.h" +#import "ClassicGameMode.h" +#import "TutorialMode.h" #import "Cart_CollectAppDelegate.h" @implementation MainMenuLayer @@ -57,7 +58,14 @@ - (void)newgame { - [[CCDirector sharedDirector] replaceScene:[GameLayer scene]]; + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + + if ([defaults boolForKey:@"hasDoneTutorial"]) + { + [[CCDirector sharedDirector] replaceScene:[ClassicGameMode scene]]; + } else { + [[CCDirector sharedDirector] replaceScene:[TutorialMode scene]]; + } } - (void)highscores diff --git a/Classes/TutorialBubble.m b/Classes/TutorialBubble.m index b85aa31..74f667f 100644 --- a/Classes/TutorialBubble.m +++ b/Classes/TutorialBubble.m @@ -134,6 +134,17 @@ boxLoc = CGPointMake(CGRectGetMaxX(spriteBounds), CGRectGetMaxY(spriteBounds) - self.frame.size.height); arrowLoc = CGPointMake(0, button.frame.size.height - spriteBounds.size.height/2 + 4); } + } else { + arrowRotation = 180; + + if (CGRectGetMidX(spriteBounds) < button.frame.size.width) + { + boxLoc = CGPointMake(0, CGRectGetMaxY(spriteBounds)-4); + arrowLoc = CGPointMake(spriteBounds.origin.x+4, 0); + } else { + boxLoc = CGPointMake(CGRectGetMaxX(spriteBounds) - self.frame.size.width, CGRectGetMaxY(spriteBounds)-4); + arrowLoc = CGPointMake(button.frame.size.width - spriteBounds.size.width/2 + 4, 0); + } } CGImageRef framestuff = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"framestuff" ofType:@"png"]] CGImage]; @@ -153,8 +164,6 @@ - (void)buttonPressed:(id)sender { - [self removeFromSuperview]; - if (target != nil) { [target performSelector:action]; diff --git a/Classes/TutorialMode.h b/Classes/TutorialMode.h new file mode 100644 index 0000000..17b0c7f --- /dev/null +++ b/Classes/TutorialMode.h @@ -0,0 +1,26 @@ +// +// TutorialMode.h +// Cart Collect +// +// Created by Starla Insigna on 8/10/11. +// Copyright 2011 Four Island. All rights reserved. +// + +#import "GameMode.h" +#import "TutorialBubble.h" +#import "FallingObjectDelegate.h" + +@interface TutorialMode : GameMode { + TutorialBubble* currentTutorial; + BOOL showedDeathBubble; + int randomItemsDropped; +} + +@property (nonatomic,retain) TutorialBubble* currentTutorial; +- (void)endTutorial; +- (FallingObject*)dropSpecificItem:(FallingObject*)item; +- (FallingObject*)dropRandomItem; +- (void)randomlyAddObject:(ccTime)dt; +- (void)skipTutorial; + +@end diff --git a/Classes/TutorialMode.m b/Classes/TutorialMode.m new file mode 100644 index 0000000..37e8bd0 --- /dev/null +++ b/Classes/TutorialMode.m @@ -0,0 +1,349 @@ +// +// TutorialMode.m +// Cart Collect +// +// Created by Starla Insigna on 8/10/11. +// Copyright 2011 Four Island. All rights reserved. +// + +#import "TutorialMode.h" +#import "FallingObject.h" +#import "Cherry.h" +#import "Bottle.h" +#import "OneUp.h" +#import "Rock.h" +#import "ClassicGameMode.h" + +// Item tags: +// 2000 - first dropped item +// 2001 - item that is dropped after you catch first dropped item to demonstrate what happens when you miss +// 2002 - items that are dropped after you miss first dropped item to demonstrate what happens when you catch +// 2003 - 1-Up +// 2009 - rock + +@implementation TutorialMode + +@synthesize currentTutorial; + +- (id)init +{ + self = [super init]; + + if (nil != self) + { + CCSprite* backgroundImage = [CCSprite spriteWithFile:@"SeaBeach.png"]; + backgroundImage.position = ccp(240, 160); + [self addChild:backgroundImage z:-1]; + + CCMenuItemImage* menuItem1 = [CCMenuItemImage itemFromNormalImage:@"skiptutorial.png" selectedImage:@"skiptutorial2.png" target:self selector:@selector(skipTutorial)]; + CCMenu* theMenu = [CCMenu menuWithItems:menuItem1, nil]; + theMenu.position = ccp(480-16-16-62, 320-8-16); + [self addChild:theMenu]; + + showedDeathBubble = NO; + randomItemsDropped = 0; + } + + return self; +} + +- (void)onEnterTransitionDidFinish +{ + [super onEnterTransitionDidFinish]; + + [self scheduleDelayedAction:^{ + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"Welcome to Cart Collect. This is a tutorial designed to help you get started playing the game. Below this bubble is a cart. Tilt your device to move it." name:@"cart" spriteReference:cart.sprite]; + self.currentTutorial = bubble; + [bubble release]; + } delay:2.0f]; +} + +- (void)tick:(ccTime)dt +{ + [super tick:dt]; + + FallingObject* object = [objects anyObject]; + if ((object.sprite.tag == 2000) && (object.sprite.position.y == 360-object.weight*14)) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"This is an item. Try to catch it with your cart." name:@"item" spriteReference:object.sprite]; + self.currentTutorial = bubble; + [bubble release]; + } else if ((object.sprite.tag == 2003) && (object.sprite.position.y == 360-object.weight*8)) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"This is a 1-Up. Catch it to gain an extra life. There's no penalty for not catching it, though." name:@"oneup" spriteReference:object.sprite]; + self.currentTutorial = bubble; + [bubble release]; + } else if ((object.sprite.tag == 2009) && (object.sprite.position.y == 360-object.weight*14)) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"This is a rock. It would be better for your health if you did not catch this item." name:@"rock" spriteReference:object.sprite]; + self.currentTutorial = bubble; + [bubble release]; + } +} + +- (void)didCatchItem:(FallingObject *)item +{ + if (item.sprite.tag == 2000) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"Congratulations! If you look at your score, you'll see it increased. Catching items is good. Now, let's see what happens when you don't catch an item." name:@"caught-first"]; + self.currentTutorial = bubble; + [bubble release]; + } else if (item.sprite.tag == 2002) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"There you go! If you look at your score, you'll see it increased. Catching items is good." name:@"caught-second"]; + self.currentTutorial = bubble; + [bubble release]; + } +} + +- (void)didMissItem:(FallingObject *)item +{ + if (item.sprite.tag == 2000) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"Whoops, you missed it! Look at your lives counter--you lost one! If you lose all of your lives, you lose the game. Try catching the item again." name:@"missed-first"]; + self.currentTutorial = bubble; + [bubble release]; + } else if (item.sprite.tag == 2001) + { + [cart setImmobile:NO]; + + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"You lost a life! You only have three lives, so try not to miss any items! However..." name:@"missed-second"]; + self.currentTutorial = bubble; + [bubble release]; + } else if (item.sprite.tag == 2002) + { + [self scheduleDelayedAction:^{ + FallingObject* object = [self dropRandomItem]; + object.sprite.tag = 2002; + [object release]; + } delay:1.0f]; + } +} + +- (void)didDestroyItem:(FallingObject *)item +{ + if (item.sprite.tag == 2003) + { + [self schedule:@selector(randomlyAddObject:) interval:2.5f]; + } else if (item.sprite.tag == 2009) + { + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"As you play, Cart Collect gets progressively more intense. Watch what happens when rocks are added to the mix and the speed is turned up." name:@"intense"]; + self.currentTutorial = bubble; + [bubble release]; + } +} + +- (void)setCurrentTutorial:(TutorialBubble *)m_currentTutorial +{ + @synchronized(self) + { + if (currentTutorial != m_currentTutorial) + { + [currentTutorial removeFromSuperview]; + [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 resumeSchedulerAndActions]; + + if ([currentTutorial.name isEqual:@"cart"]) + { + [self scheduleDelayedAction:^{ + FallingObject* object = [self dropRandomItem]; + object.sprite.tag = 2000; + [object release]; + } delay:3.0f]; + } else if ([currentTutorial.name isEqual:@"caught-first"]) + { + [cart setImmobile:YES]; + + [self scheduleDelayedAction:^{ + FallingObject* object = [self dropRandomItem]; + + if (cart.sprite.position.x > 240) + { + object.sprite.position = ccp(20, 360); + } else { + object.sprite.position = ccp(460, 360); + } + + object.sprite.tag = 2001; + + [object release]; + } delay:1.0f]; + } else if ([currentTutorial.name isEqual:@"missed-first"]) + { + [self scheduleDelayedAction:^{ + FallingObject* object = [self dropRandomItem]; + object.sprite.tag = 2002; + [object release]; + } delay:1.0f]; + } else if (([currentTutorial.name isEqual:@"caught-second"]) || ([currentTutorial.name isEqual:@"missed-second"])) + { + [self scheduleDelayedAction:^{ + FallingObject* object = [self dropSpecificItem:[[OneUp alloc] init]]; + object.sprite.tag = 2003; + [object release]; + } delay:2.0f]; + } else if ([currentTutorial.name isEqual:@"intense"]) + { + [self schedule:@selector(randomlyAddObject:) interval:1.0f]; + } else if ([currentTutorial.name isEqual:@"end"]) + { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + [defaults setBool:YES forKey:@"hasDoneTutorial"]; + + [[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:3.0f scene:[ClassicGameMode scene] withColor:ccc3(0,0,0)]]; + } + + self.currentTutorial = nil; +} + +- (void)pause +{ + if (self.currentTutorial != nil) + { + [self.currentTutorial removeFromSuperview]; + } + + [super pause]; +} + +- (void)unpause +{ + [super unpause]; + + if (self.currentTutorial != nil) + { + [self pauseSchedulerAndActions]; + [[[CCDirector sharedDirector] openGLView] addSubview:self.currentTutorial]; + } +} + +- (FallingObject*)dropSpecificItem:(FallingObject*)object +{ + int objectX = arc4random()%448+16; + object.sprite.position = ccp(objectX, 360); + object.sprite.scale = 1; + [self addChild:object.sprite]; + + object.delegate = self; + + [objects addObject:object]; + + return object; +} + +- (FallingObject*)dropRandomItem +{ + FallingObject* object; + int randomval = arc4random()%100; + + if (randomval < 65) + { + object = [[Cherry alloc] init]; + } else { + object = [[Bottle alloc] init]; + } + + return [self dropSpecificItem:object]; +} + +- (void)setLives:(int)m_lives +{ + [super setLives:m_lives]; + + if ((lives < 1) && (!showedDeathBubble)) + { + showedDeathBubble = YES; + + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"You lost all your lives! Normally, you'd be taken to a game over screen where you could submit your score to the highscore list, but we're a bit more forgiving in tutorial mode." name:@"gameover"]; + self.currentTutorial = bubble; + [bubble release]; + } +} + +- (void)randomlyAddObject:(ccTime)dt +{ + FallingObject* object; + + if (randomItemsDropped < 5) + { + int randomval = arc4random()%100; + + if (randomval < 65) + { + object = [[Cherry alloc] init]; + } else if (randomval < 98) + { + object = [[Bottle alloc] init]; + } else { + object = [[OneUp alloc] init]; + } + } else if (randomItemsDropped == 5) + { + object = [[Rock alloc] init]; + object.sprite.tag = 2009; + + [self unschedule:@selector(randomlyAddObject:)]; + } else if (randomItemsDropped < 15) { + int randomval = arc4random()%100; + + if (randomval < 40) + { + object = [[Cherry alloc] init]; + } else if (randomval < 70) + { + object = [[Rock alloc] init]; + } else if (randomval < 98) + { + object = [[Bottle alloc] init]; + } else { + object = [[OneUp alloc] init]; + } + } else if (randomItemsDropped == 15) + { + [self scheduleDelayedAction:^{ + TutorialBubble* bubble = [[TutorialBubble alloc] initWithText:@"That's pretty much it! You've completed the tutorial, so now it's time to play an actual game of Cart Collect!" name:@"end"]; + self.currentTutorial = bubble; + [bubble release]; + } delay:2.0f]; + + [self unschedule:@selector(randomlyAddObject:)]; + + return; + } else { + NSLog(@"randomItemsDropped in TutorialMode is greater than 15--this should never happen."); + + return; + } + + [self dropSpecificItem:object]; + [object release]; + + randomItemsDropped++; +} + +- (void)skipTutorial +{ + [self unscheduleAllSelectors]; + self.currentTutorial = nil; + + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + [defaults setBool:YES forKey:@"hasDoneTutorial"]; + + [[CCDirector sharedDirector] replaceScene:[CCTransitionFlipY transitionWithDuration:1.0f scene:[ClassicGameMode scene]]]; +} + +@end diff --git a/Resources/Info.plist b/Resources/Info.plist index 9b64e3d..ed33cda 100755 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -19,7 +19,7 @@ Icon-72.png CFBundleIdentifier - com.fourisland.${PRODUCT_NAME:rfc1034identifier} + com.apatheticink.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -32,8 +32,6 @@ ???? CFBundleURLTypes - CFBundleVersion - 1.0 LSRequiresIPhoneOS UIPrerenderedIcon diff --git a/Resources/skiptutorial.png b/Resources/skiptutorial.png new file mode 100644 index 0000000..5c95cc9 Binary files /dev/null and b/Resources/skiptutorial.png differ diff --git a/Resources/skiptutorial2.png b/Resources/skiptutorial2.png new file mode 100644 index 0000000..95bbbbd Binary files /dev/null and b/Resources/skiptutorial2.png differ -- cgit 1.4.1