From 339f8e2cb2fce18f6d32b3881a5cd390c0be488e Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sun, 4 Sep 2011 11:17:44 -0400 Subject: Implemented Jump mode (BETA) Dear god this is beta. I think I'll release a build for the testers soon so I can see what people think and then hammer out the bugs. Refs #204 --- Classes/Cart.h | 5 + Classes/Cart.m | 23 +++- Classes/CartDelegate.h | 19 +++ Classes/ClassicGameMode.m | 2 +- Classes/GameMode.h | 2 +- Classes/GameMode.m | 1 + Classes/GameOverScene.h | 5 +- Classes/GameOverScene.m | 9 +- Classes/JumpGameMode.h | 11 ++ Classes/JumpGameMode.m | 344 ++++++++++++++++++++++++++++++++++++++++++++-- 10 files changed, 404 insertions(+), 17 deletions(-) create mode 100644 Classes/CartDelegate.h (limited to 'Classes') diff --git a/Classes/Cart.h b/Classes/Cart.h index 0ef1abf..302e5ec 100644 --- a/Classes/Cart.h +++ b/Classes/Cart.h @@ -8,15 +8,20 @@ #import #import "cocos2d.h" +#import "CartDelegate.h" @interface Cart : NSObject { CCSprite* sprite; float accelX; BOOL immobile; + id delegate; + BOOL falling; } @property (readonly) CCSprite* sprite; @property (assign) BOOL immobile; +@property (nonatomic,retain) id delegate; +@property (assign) BOOL falling; - (id)initWithSprite:(CCSprite*)sprite; - (void)tick; - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration; diff --git a/Classes/Cart.m b/Classes/Cart.m index 45c370c..cfe7ee7 100644 --- a/Classes/Cart.m +++ b/Classes/Cart.m @@ -10,7 +10,7 @@ @implementation Cart -@synthesize sprite, immobile; +@synthesize sprite, immobile, delegate, falling; - (id)initWithSprite:(CCSprite*)m_sprite { @@ -20,6 +20,7 @@ { sprite = m_sprite; immobile = NO; + falling = NO; } return self; @@ -30,7 +31,27 @@ if (!immobile) { // Move the cart based on acceleration gathered from accelerometer + CGPoint prevLoc = sprite.position; sprite.position = ccp(MIN(MAX(sprite.position.x+accelX, 16),464), sprite.position.y); + + if ((delegate != nil) && ([delegate respondsToSelector:@selector(cartIsObstructed:)])) + { + if ([delegate cartIsObstructed:self]) + { + sprite.position = prevLoc; + } + } + + if (falling) + { + if ((delegate != nil) && ([delegate respondsToSelector:@selector(cartShouldFall:)])) + { + int bottom = [delegate cartShouldFall:self]; + sprite.position = ccp(sprite.position.x, MAX(bottom, sprite.position.y-6)); + } else { + NSLog(@"Falling is set on a cart without a compatible game mode."); + } + } } } diff --git a/Classes/CartDelegate.h b/Classes/CartDelegate.h new file mode 100644 index 0000000..8c37019 --- /dev/null +++ b/Classes/CartDelegate.h @@ -0,0 +1,19 @@ +// +// CartDelegate.h +// Cartographic +// +// Created by Starla Insigna on 8/27/11. +// Copyright 2011 Four Island. All rights reserved. +// + +#import + +@class Cart; + +@protocol CartDelegate + +@optional +- (int)cartShouldFall:(Cart*)cart; +- (BOOL)cartIsObstructed:(Cart*)cart; + +@end diff --git a/Classes/ClassicGameMode.m b/Classes/ClassicGameMode.m index c1d3be7..b8fe636 100755 --- a/Classes/ClassicGameMode.m +++ b/Classes/ClassicGameMode.m @@ -28,7 +28,7 @@ { [self unscheduleAllSelectors]; - [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInT transitionWithDuration:1.5f scene:[GameOverScene sceneWithScore:score]]]; + [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInT transitionWithDuration:1.5f scene:[GameOverScene sceneWithScore:score gameMode:@"Collect"]]]; } else if (score > lastScore) { if ((lastScore < 6500) && (score >= 6500)) diff --git a/Classes/GameMode.h b/Classes/GameMode.h index 53ed9fc..0659a57 100644 --- a/Classes/GameMode.h +++ b/Classes/GameMode.h @@ -12,7 +12,7 @@ #define GAME_SCENE 436 #define GAME_LAYER 437 -@interface GameMode : CCLayer { +@interface GameMode : CCLayer { NSMutableSet* objects; int score; int lives; diff --git a/Classes/GameMode.m b/Classes/GameMode.m index af9b3bd..f0eb02f 100644 --- a/Classes/GameMode.m +++ b/Classes/GameMode.m @@ -40,6 +40,7 @@ cart = [[Cart alloc] initWithSprite:[CCSprite spriteWithFile:@"cart.png"]]; cart.sprite.position = ccp(240, 22); cart.sprite.scale = 2; + cart.delegate = self; [self addChild:cart.sprite]; scoreLabel = [CCLabelBMFont labelWithString:@"Score: 0" fntFile:@"helvetica2.fnt"]; diff --git a/Classes/GameOverScene.h b/Classes/GameOverScene.h index ef63aa7..a91286e 100755 --- a/Classes/GameOverScene.h +++ b/Classes/GameOverScene.h @@ -18,10 +18,11 @@ UIActivityIndicatorView* activityIndicator; UIButton* backButton; int score; + NSString* gameMode; } -+ (GameOverScene*)sceneWithScore:(int)score; -- (id)initWithScore:(int)score; ++ (GameOverScene*)sceneWithScore:(int)score gameMode:(NSString*)gameMode; +- (id)initWithScore:(int)score gameMode:(NSString*)gameMode; - (void)newgame; - (void)submitScore; - (void)exit; diff --git a/Classes/GameOverScene.m b/Classes/GameOverScene.m index 94236ff..f2dca0b 100755 --- a/Classes/GameOverScene.m +++ b/Classes/GameOverScene.m @@ -14,12 +14,12 @@ @implementation GameOverScene -+ (GameOverScene*)sceneWithScore:(int)score ++ (GameOverScene*)sceneWithScore:(int)score gameMode:(NSString*)gameMode { - return [[[GameOverScene alloc] initWithScore:score] autorelease]; + return [[[GameOverScene alloc] initWithScore:score gameMode:gameMode] autorelease]; } -- (id)initWithScore:(int)score2 +- (id)initWithScore:(int)score2 gameMode:(NSString*)gameMode2 { self = [super init]; @@ -36,6 +36,7 @@ [theLayer addChild:backgroundImage z:0]; score = score2; + gameMode = gameMode2; movingLayer = [[UIView alloc] initWithFrame:CGRectMake(0, -320, 480, 320)]; movingLayer.backgroundColor = [UIColor clearColor]; @@ -88,7 +89,7 @@ textField.enabled = NO; submitSwitch.enabled = NO; - const char* sqlQuery = [[NSString stringWithFormat:@"INSERT INTO highscores (name, score, gameMode) VALUES (\"%@\",%d,\"Collect\")", [textField text], score] UTF8String]; + const char* sqlQuery = [[NSString stringWithFormat:@"INSERT INTO highscores (name, score, gameMode) VALUES (\"%@\",%d,\"%@\")", [textField text], score, gameMode] UTF8String]; sqlite3_stmt* compiled_statement; if (sqlite3_prepare_v2([Cart_CollectAppDelegate database], sqlQuery, -1, &compiled_statement, NULL) == SQLITE_OK) diff --git a/Classes/JumpGameMode.h b/Classes/JumpGameMode.h index 9753720..f6a31f8 100644 --- a/Classes/JumpGameMode.h +++ b/Classes/JumpGameMode.h @@ -8,6 +8,8 @@ #import "GameMode.h" +@class LedgeFactory; + @interface JumpGameMode : GameMode { CCSprite* water; int waterTick; @@ -16,6 +18,15 @@ int jumpTick; BOOL jump; float expectedAngle; + NSMutableSet* ledges; + LedgeFactory* factory; + int ledgeScrollSpeed; + float ledgeAccelerationRate; + float addSpeed; } +- (void)accelerateLedgeScrolling; +- (void)randomlyAddObject:(ccTime)dt; +- (void)incrementScore; + @end diff --git a/Classes/JumpGameMode.m b/Classes/JumpGameMode.m index e30be6a..bac3fa5 100644 --- a/Classes/JumpGameMode.m +++ b/Classes/JumpGameMode.m @@ -7,8 +7,27 @@ // #import "JumpGameMode.h" +#import "SimpleAudioEngine.h" +#import "FallingObject.h" +#import "Cherry.h" +#import "Bottle.h" +#import "OneUp.h" +#import "Rock.h" +#import "GameOverScene.h" -#define kMinimumGestureLength 50 +#define kMinimumGestureLength 25 + +@interface LedgeFactory : NSObject { + UIImage* leftSprite; + UIImage* midSprite; + UIImage* rightSprite; + UIImage* singleSprite; +} + +- (id)init; +- (UIImage*)createLedgeWithWidth:(int)width height:(int)height; + +@end @implementation JumpGameMode @@ -18,14 +37,33 @@ if (nil != self) { + CCSprite* backgroundImage = [CCSprite spriteWithFile:@"SeaBeach.png"]; + backgroundImage.position = ccp(240, 160); + [self addChild:backgroundImage z:-1]; + water = [CCSprite spriteWithFile:@"water.png"]; - water.position = ccp(240, -80); + water.position = ccp(240, -60); [self addChild:water]; + cart.sprite.position = ccp(120, 22+64); //86 + cart.falling = YES; + cart.delegate = self; + self.isTouchEnabled = YES; waterTick = 0; wave = NO; + + factory = [[LedgeFactory alloc] init]; + ledges = [[NSMutableSet alloc] init]; + CCSprite* ledge = [CCSprite spriteWithTexture:[[CCTexture2D alloc] initWithImage:[factory createLedgeWithWidth:6 height:2]]]; + ledge.position = ccp(80, 32); + [self addChild:ledge]; + [ledges addObject:ledge]; + + ledgeScrollSpeed = 0; + ledgeAccelerationRate = 20.0f; + addSpeed = 2.5f; } return self; @@ -34,21 +72,122 @@ - (void)onEnterTransitionDidFinish { [super onEnterTransitionDidFinish]; + + [self schedule:@selector(accelerateLedgeScrolling) interval:ledgeAccelerationRate]; + [self schedule:@selector(randomlyAddObject:) interval:addSpeed]; + [self schedule:@selector(incrementScore) interval:1.0f]; [self scheduleDelayedAction:^{ wave = YES; - } delay:3.0f]; + } delay:60.0f]; } - (void)tick:(ccTime)dt { + NSMutableSet* discardedSet = [NSMutableSet set]; + int rightmost = 0; + int rightwidth = 0; + + for (CCSprite* sprite in ledges) + { + sprite.position = ccp(sprite.position.x - ledgeScrollSpeed, sprite.position.y); + + if ((sprite.position.x + sprite.boundingBox.size.width/2) < 0) + { + [discardedSet addObject:sprite]; + [self removeChild:sprite cleanup:YES]; + } + + if (sprite.position.x > rightmost) + { + rightmost = sprite.position.x; + rightwidth = sprite.boundingBox.size.width/2; + } + } + + for (FallingObject* object in objects) + { + if (waterTick > 0) + { + object.sprite.position = ccp(object.sprite.position.x, MAX(object.sprite.position.y, water.position.y+80+11)); + } else { + object.sprite.position = ccp(object.sprite.position.x-ledgeScrollSpeed, object.sprite.position.y); + } + } + + [ledges minusSet:discardedSet]; + + if (rightmost <= 480) + { + CCSprite* ledge = [CCSprite spriteWithTexture:[[CCTexture2D alloc] initWithImage:[factory createLedgeWithWidth:(arc4random() % 10) height:2]]]; + ledge.position = ccp(rightmost + rightwidth + ledge.boundingBox.size.width/2+64, 32); + [self addChild:ledge]; + [ledges addObject:ledge]; + } + + if ([self cartIsObstructed:cart]) + { + cart.sprite.position = ccp(cart.sprite.position.x-ledgeScrollSpeed, cart.sprite.position.y); + } + + int lastScore = score; + [super tick:dt]; + if (cart.sprite.position.y == (0-cart.sprite.boundingBox.size.height/2)) + { + [self setLives:self.lives-1]; + + [[SimpleAudioEngine sharedEngine] playEffect:[[NSBundle mainBundle] pathForResource:@"Damage1" ofType:@"wav"]]; + + cart.sprite.position = ccp(cart.sprite.position.x, 320 + cart.sprite.boundingBox.size.height/2); + } + + if (lives == 0) + { + [self unscheduleAllSelectors]; + + [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInT transitionWithDuration:1.5f scene:[GameOverScene sceneWithScore:score gameMode:@"Jump"]]]; + } else if (score > lastScore) + { + if ((lastScore < 240) && (score >= 240)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.6f]; + addSpeed = 0.6f; + } else if ((lastScore < 180) && (score >= 180)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.7f]; + addSpeed = 0.7f; + } else if ((lastScore < 120) && (score >= 120)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.8f]; + addSpeed = 0.8f; + } else if ((lastScore < 90) && (score >= 90)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:0.9f]; + addSpeed = 0.9f; + } else if ((lastScore < 60) && (score >= 60)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:1.0f]; + addSpeed = 1.0f; + } else if ((lastScore < 30) && (score >= 30)) + { + [self unschedule:@selector(randomlyAddObject:)]; + [self schedule:@selector(randomlyAddObject:) interval:2.0f]; + addSpeed = 2.0f; + } + } + if (wave) { waterTick++; - water.position = ccp(240, 160 * sin(waterTick / (36 * M_PI)) - 80); + water.position = ccp(240, 140 * sin(waterTick / (36 * M_PI)) - 60); if (waterTick == 180) { @@ -61,6 +200,10 @@ { wave = NO; waterTick = 0; + + [self scheduleDelayedAction:^{ + wave = YES; + } delay:60.0f]; } } @@ -68,15 +211,14 @@ { jumpTick++; - cart.sprite.position = ccp(cart.sprite.position.x, MAX(100 * sin(jumpTick / (2 * M_PI)) + 22, water.position.y+80+11)); + cart.sprite.position = ccp(cart.sprite.position.x, MAX(100 * sin(jumpTick / (2 * M_PI)) + 86, water.position.y+80+11)); if (jumpTick == 20) { jump = NO; jumpTick = 0; + cart.falling = YES; } - } else { - cart.sprite.position = ccp(cart.sprite.position.x, MAX(22, water.position.y+80+11)); } } @@ -93,9 +235,10 @@ CGFloat angle = atan2f(gestureCurrentPosition.y - gestureStartPoint.y, gestureCurrentPosition.x - gestureStartPoint.x); CGFloat distance = sqrt(powf((gestureCurrentPosition.x - gestureStartPoint.x),2) + powf((gestureCurrentPosition.y - gestureStartPoint.y),2)); - if ((distance >= kMinimumGestureLength) && (angle >= expectedAngle - M_PI_4) && (angle <= expectedAngle + M_PI_4) && (cart.sprite.position.y == 22)) + if ((distance >= kMinimumGestureLength) && (angle >= expectedAngle - M_PI_4) && (angle <= expectedAngle + M_PI_4) && ((cart.sprite.position.y >= 80) && (cart.sprite.position.y <= 90))) { jump = YES; + cart.falling = NO; } } @@ -106,4 +249,189 @@ expectedAngle = acceleration.y*M_PI_2; } +- (int)cartShouldFall:(Cart *)m_cart +{ + int bottom = 0-m_cart.sprite.boundingBox.size.height/2; + + for (CCSprite* sprite in ledges) + { + CGSize first = [m_cart.sprite boundingBox].size; + CGSize second = [sprite boundingBox].size; + + if (m_cart.sprite.position.x > (sprite.position.x - second.width/2 - first.width/2)) + { + if (m_cart.sprite.position.x < (sprite.position.x + second.width/2 + first.width/2)) + { + bottom = sprite.position.y + second.height/2 + first.height/2; + break; + } + } + } + + if (waterTick > 0) + { + bottom = MAX(water.position.y+80+11, bottom); + } + + return bottom; +} + +- (BOOL)cartIsObstructed:(Cart *)m_cart +{ + for (CCSprite* sprite in ledges) + { + CGSize first = [m_cart.sprite boundingBox].size; + CGSize second = [sprite boundingBox].size; + + if (m_cart.sprite.position.x > (sprite.position.x - second.width/2 - first.width/2)) + { + if (m_cart.sprite.position.x < (sprite.position.x + second.width/2 + first.width/2)) + { + if (m_cart.sprite.position.y > (sprite.position.y - second.height/2 - first.height/2)) + { + if (m_cart.sprite.position.y < (sprite.position.y + second.height/2 + first.height/2)) + { + return YES; + } + } + } + } + } + + return NO; +} + +- (void)accelerateLedgeScrolling +{ + [self unschedule:@selector(accelerateLedgeScrolling)]; + + ledgeScrollSpeed += 2; + ledgeAccelerationRate *= 2; + + [self schedule:@selector(accelerateLedgeScrolling) interval:ledgeAccelerationRate]; +} + +- (void)randomlyAddObject:(ccTime)dt +{ + FallingObject* object; + + if (score < 120) + { + int randomval = arc4random()%100; + + if (randomval < 80) + { + object = [[Rock alloc] init]; + } else { + object = [[OneUp alloc] init]; + } + } else { + int randomval = arc4random()%100; + + if (randomval < 70) + { + object = [[Rock 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 >= 120) + { + 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 >= 240) + { + 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]; + } + } +} + +- (void)incrementScore +{ + [self setScore:self.score+1]; +} + @end + +@implementation LedgeFactory + +- (id)init +{ + self = [super init]; + + CGImageRef framestuff = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ledge" ofType:@"png"]] CGImage]; + CGImageRef leftRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(0, 0, 32, 32)); + CGImageRef midRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(32, 0, 32, 32)); + CGImageRef rightRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(64, 0, 32, 32)); + CGImageRef singleRef = CGImageCreateWithImageInRect(framestuff, CGRectMake(96, 0, 32, 32)); + leftSprite = [[UIImage alloc] initWithCGImage:leftRef]; + midSprite = [[UIImage alloc] initWithCGImage:midRef]; + rightSprite = [[UIImage alloc] initWithCGImage:rightRef]; + singleSprite = [[UIImage alloc] initWithCGImage:singleRef]; + CGImageRelease(leftRef); + CGImageRelease(midRef); + CGImageRelease(rightRef); + CGImageRelease(singleRef); + + return self; +} + +- (UIImage*)createLedgeWithWidth:(int)width height:(int)height +{ + UIGraphicsBeginImageContext(CGSizeMake(width*32, height*32)); + + for (int y=0; y