Hier finden Sie die Quellcodes und benötigten Grafiken zum Jump’n’Run „The Little Jungle Sisters“ aus dem Buch (Kapitel 4), damit Sie den langen Code nicht von Hand abtippen müssen.
Video des Gameplays:
Verwendete Grafiken: Download
Hilfsklassen:
#import <UIKit/UIKit.h> @interface Sprite : UIView { UIImageView *pic; NSMutableArray *mask; int spriteTyp; int movingDirection; int sId; int shieldPower; } @property (nonatomic, strong) UIImageView *pic; @property (nonatomic, strong) NSMutableArray *mask; - (id) initWithImage: (UIImage *) img spriteTyp: (double) sTyp parentView: (UIView*) parentView; - (void) addMask: (double) x y:(double) y width:(double)width height:(double)height; - (void) setSpriteTyp: (UIImage *) img typ: (int) sTyp; - (void) setAnimationTyp: (NSArray *) img spriteTyp: (int) sTyp duration: (double) duration repeat: (int) repeat; - (void) moveBy: (double) x y: (double) y; - (void) setCenter: (double) x y: (double) y; - (bool) detectCollisionWith: (Sprite *) sprite; - (bool) detectCollisionWithMask: (Sprite *) sprite; - (CGRect) frame; - (CGPoint) center; - (int) spriteTyp; - (int) movingDirection; - (void) setMovingDirection: (int) x; - (void) setAlpha: (float) a; - (void) mirrorSprite: (int) a; - (void) setId: (int) a; - (int) sId; - (void) setShieldPower: (int) a; - (int) shieldPower; @end
#import "Sprite.h" #import "constants.h" @implementation Sprite @synthesize pic, mask; - (id) initWithImage: (UIImage *) img spriteTyp: (double) sTyp parentView: (UIView *) parentView { if (self == [super init]) { pic = [[UIImageView alloc] initWithImage:img]; pic.hidden = YES; [self addSubview:pic]; [parentView addSubview:self]; spriteTyp = sTyp; movingDirection = right; mask = [[NSMutableArray alloc] init]; [mask addObject:[NSValue valueWithCGRect:CGRectMake(0, 0, 1,1)]]; } return self; } - (void) addMask: (double) x y:(double) y width:(double)width height:(double)height { [mask addObject:[NSValue valueWithCGRect:CGRectMake(x, y, width, height)]]; } - (void) setSpriteTyp: (UIImage *) img typ: (int) sTyp { pic.frame = CGRectMake(pic.frame.origin.x, pic.frame.origin.y, img.size.width, img.size.height); pic.image = img; spriteTyp = sTyp; } - (void) setAnimationTyp: (NSArray *) img spriteTyp: (int) sTyp duration: (double) duration repeat: (int) repeat { pic.animationImages = img; pic.animationDuration = duration; pic.animationRepeatCount = repeat; [pic startAnimating]; spriteTyp = sTyp; } - (void) moveBy: (double) x y: (double) y { pic.center = CGPointMake(pic.center.x+x, pic.center.y+y); } - (void) setCenter: (double) x y: (double) y { pic.center = CGPointMake(x, y); pic.hidden = NO; } - (bool) detectCollisionWith: (Sprite *) sprite { if (CGRectIntersectsRect(self.frame, sprite.frame)) { return YES; } return NO; } - (bool) detectCollisionWithMask: (Sprite *) sprite { bool collision = NO; // Alle Masken des Sprites durchtesten for (int p=0;p<[mask count]; p++) { //CGRect aus Array holen CGRect rect = [[mask objectAtIndex:p] CGRectValue]; // Koordinatenaddition CGRect sMask = CGRectMake(pic.frame.origin.x + rect.origin.x, pic.frame.origin.y + rect.origin.y, rect.size.width, rect.size.height); // eigentliche Kollisionsabfrage if (CGRectIntersectsRect(sprite.frame, sMask)){ collision = YES; } } return collision; } - (void) mirrorSprite:(int) direction { pic.transform = CGAffineTransformMakeScale(direction,1); } - (CGRect) frame {return pic.frame;} - (CGPoint) center {return pic.center;} - (int) spriteTyp { return spriteTyp; } - (int) movingDirection { return movingDirection; } - (void) setMovingDirection: (int) x { movingDirection = x;} - (void) setAlpha: (float) a {pic.alpha = a;}; - (void) setId: (int) a {sId=a;} - (int) sId {return sId;} - (void) setShieldPower: (int) a {shieldPower=a;} - (int) shieldPower {return shieldPower;} @end
// Raster der Plattformen #define rasterX 20 #define rasterY 20 // Animationen #define stand 0 #define walk 1 #define jump 2 #define springjump 3 #define bogeyewalk 4 // Gems / Items #define spring 5 #define extralife 6 #define flag 7 // Monsters #define bogeye 8 #define bogeyeSpeed 2 // Bewegungsrichtungen #define left -1 #define right 1 #define up -1 #define down 1
Level:
------------------------- -----------------------X- ------0--------------1111 ------------------------- ------------------------- ------------------------- -------------@----------- -----------2------------- ------------------------- ----#-------------------- ------------------------- --3---------------------- ------------------------- ------------3------------ ------------------------- -------------------------
----------------------------------X----0--------0-------*------------- --------------------0----0------111---------------------1------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- ------3--------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------@---------------------111------------------------ -----------------4--------------0------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- 2------------------------------------------------------@-------------- ---------------------------------------------------3-----------------4 --------#-------------------------@----------------------------------- ----3------------@-----------2---------------------------------------- -----------2--------------------------------3----------------^-------- --------------------3----------------------------------------1----3---
--------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------^---------- --------------------111-----------------------------------------------------------------1---------- ----------------------------3-------------X-------------------------------------------------------- ----------------------------------------111--------------------------------------------------1----2 4-------------@------------------------------------------------------------------------------------ ------------2-------------------------------------------------------#--------------------------*--- -----------------------------------------------------------------------------------------------0--- ----------------------------------------------------3---------------------------------------------- ------------------------2---------------------@--@------------------1------------------------------ ---------------------------------------------2------------------3---------------------------------3 --------------------------------------------------------------------------------------------------- ------------3-------------------------3------------------------------------------------------------ --------------------------3------------------------------------------------------------------------ --------------------------------------------------------------------------^--------------------00-- ---3--------------------0-----000------------------------------------000001------------1111--------
--------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------^----------------0-----0--------------------4--- --------------------------0------------------------------------------1-------1--------------------2------------------ -------------------------------------------------------@------------------------------------------------------------- ---------@---------------------1------------------4------------------------------------------------------------------ ------4--------------------------------2----------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------2----------------- --------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------- --------------------------------------------3-----------------------------------------------------------3--------------@-----^ ----------------------------------------------------------#---------------------------------------------------------4 ---------X------------------------------------------------------3------------------@-^------------------------------- ----3-----------------------------0---------------------2------------------------2--------------0-------------------------------------4
Hauptklasse:
#import <UIKit/UIKit.h> #import <CoreGraphics/CoreGraphics.h> #import <QuartzCore/QuartzCore.h> #import "Sprite.h" @interface ViewController : UIViewController { // Das duerfte bekannt sein: UIImageView *canvas; Sprite *player; int zaehler; bool normalAction; int level; double screenWidth; double screenHeight; // Steuerung UIImageView *joypad; UIImageView *jumpButton; double playerSpeedX; double playerSpeedY; bool playerHasContactToFloor; // Bodenkontakt fuer Spruenge bool playerAddJumpEnergy; // Sprungkraft int playerLooksLike; // fuer Animation // Plattformen NSMutableArray *levelSource; NSMutableArray *platforms; int maxPlatformWidth; // Preloader fuer die Grafiken NSMutableArray *imageSource; NSMutableArray *platformGraphicSource; NSMutableArray *animationSource; // Parallax-Scrolling Sprite *layer0; Sprite *layer1; Sprite *fogLayer; double fogMove; } @property (nonatomic,strong) UIImageView *canvas; @property (nonatomic,strong) UIImageView *joypad; @property (nonatomic,strong) UIImageView *jumpButton; @property (nonatomic,strong) Sprite *player; @property (nonatomic, strong) NSMutableArray *imageSource; @property (nonatomic, strong) NSMutableArray *animationSource; @property (nonatomic, strong) NSMutableArray *platformGraphicSource; @property (nonatomic, strong) NSMutableArray *levelSource; @property (nonatomic, strong) NSMutableArray *platforms; @property (nonatomic,strong) Sprite *layer0; @property (nonatomic,strong) Sprite *layer1; @property (nonatomic,strong) Sprite *fogLayer; @end
#import "ViewController.h" #import "Sprite.h" #include "constants.h" @implementation ViewController @synthesize canvas, joypad, jumpButton, player, imageSource; @synthesize animationSource, platforms, levelSource; @synthesize platformGraphicSource, layer0, layer1, fogLayer; - (bool)loadLevel: (int)currentLevel { // Leveldatei oeffnen NSString* pathOfLevelFile = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"level%d", currentLevel] ofType:@"lvl"]; // Wenn Leveldatei nicht existiert, FALSE zurueckgeben if (![[NSFileManager defaultManager] fileExistsAtPath: pathOfLevelFile ]==YES) return NO; NSString *levelDesign=[[NSString alloc] initWithContentsOfFile:pathOfLevelFile encoding:NSUTF8StringEncoding error:NULL]; // Dateiinhalt auslesen NSArray *lines = [levelDesign componentsSeparatedByString:@"\n"]; int row = -1; for (id levelRow in lines) { row++; for (int col=0;col<[levelRow length];col++) { NSString *part = [levelRow substringWithRange:NSMakeRange(col, 1)]; // Wenn ASCII-Zeichen nicht leer (= Minuszeichen) ist if(![part isEqualToString:@"-"]) { // dann Symbol auslesen und nachher zu levelSource hinzufuegen int spriteTyp = [part intValue]; if ([part isEqualToString:@"^"]) spriteTyp=spring; // Sprungfeder if ([part isEqualToString:@"X"]) spriteTyp=flag; // Zielflagge if ([part isEqualToString:@"*"]) spriteTyp=extralife; // Extraleben if ([part isEqualToString:@"@"]) spriteTyp=bogeye; // Sumpfmonster if ([part isEqualToString:@"#"]) { // Startposition player zaehler=col*rasterX-screenWidth/2-rasterX/2; [player setCenter:screenWidth/2 y:row*rasterY]; } else { // wenn nicht Startposition: // Item oder Plattform setzen UIImage *img = [platformGraphicSource objectAtIndex:spriteTyp]; double imgWidth = img.size.width; double imgHeight = img.size.height; double posX = col*rasterX + imgWidth/2; double posY = row*rasterY + imgHeight/2; // zu levelSource hinzufuegen [levelSource addObject:[NSArray arrayWithObjects: [NSNumber numberWithInteger:spriteTyp], // spriteTyp [NSNumber numberWithDouble:posX], // x-Pos [NSNumber numberWithDouble:posY], // y-Pos [NSNumber numberWithBool:NO], // Sichtbarkeit nil]]; } } } } // Level wurde geladen, TRUE zurueckgeben return YES; } - (void)restartLevel { normalAction=NO; // alten Level loeschen for (int p=0;p<[platforms count];p++) { [[platforms objectAtIndex:p] removeFromSuperview]; } [platforms removeAllObjects]; [levelSource removeAllObjects]; bool nextLevelLoaded = [self loadLevel:level+1]; if (nextLevelLoaded) { playerHasContactToFloor=NO; playerSpeedX=0; playerSpeedY=0; normalAction=YES; } else { level=0; [self restartLevel]; } } - (void)loadView { // Display: Vollbild und Dauerbeleuchtung [[UIApplication sharedApplication] setStatusBarHidden:YES]; [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; // Hintergrund vorbereiten canvas = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; [canvas setImage:[UIImage imageNamed:@"bg.png"]]; canvas.userInteractionEnabled = YES; canvas.multipleTouchEnabled = YES; self.view = canvas; // Breite und Hoehe speichern (vorsicht: landscape!) screenWidth = self.view.bounds.size.height; screenHeight = self.view.bounds.size.width; // Parallax-Ebenen // erst hinterste Ebene layer1 = [[Sprite alloc] initWithImage: [UIImage imageNamed:@"layer1.png"] spriteTyp:0 parentView:canvas]; // dann vordere Ebene layer0 = [[Sprite alloc] initWithImage: [UIImage imageNamed:@"layer0.png"] spriteTyp:0 parentView:canvas]; // zuletzt die Nebel-Ebene fogLayer = [[Sprite alloc] initWithImage: [UIImage imageNamed:@"fairyfog.png"] spriteTyp:0 parentView:canvas]; platforms = [[NSMutableArray alloc] init]; levelSource = [[NSMutableArray alloc] init]; platformGraphicSource = [[NSMutableArray alloc] init]; [platformGraphicSource addObject:[UIImage imageNamed:@"plattform0.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"plattform1.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"plattform2.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"plattform3.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"plattform4.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"spring2.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"heart.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"flag.png"]]; [platformGraphicSource addObject:[UIImage imageNamed:@"bogeye0.png"]]; level=3; // Preloader fuer Animationen animationSource = [[NSMutableArray alloc] init]; // stehen: [animationSource addObject:[NSArray arrayWithObjects: [UIImage imageNamed:@"liana1.png"], nil]]; // laufen: [animationSource addObject:[NSArray arrayWithObjects: [UIImage imageNamed:@"liana1.png"], [UIImage imageNamed:@"liana2.png"], [UIImage imageNamed:@"liana3.png"], [UIImage imageNamed:@"liana4.png"], [UIImage imageNamed:@"liana5.png"], [UIImage imageNamed:@"liana6.png"], [UIImage imageNamed:@"liana7.png"], [UIImage imageNamed:@"liana8.png"], [UIImage imageNamed:@"liana9.png"], [UIImage imageNamed:@"liana10.png"], [UIImage imageNamed:@"liana11.png"], [UIImage imageNamed:@"liana12.png"], [UIImage imageNamed:@"liana13.png"], [UIImage imageNamed:@"liana14.png"], [UIImage imageNamed:@"liana15.png"], nil]]; // springen: [animationSource addObject:[NSArray arrayWithObjects: [UIImage imageNamed:@"liana4.png"], nil]]; // Sprungfeder: [animationSource addObject:[NSArray arrayWithObjects: [UIImage imageNamed:@"spring2.png"], [UIImage imageNamed:@"spring1.png"], [UIImage imageNamed:@"spring0.png"], [UIImage imageNamed:@"spring1.png"], [UIImage imageNamed:@"spring2.png"], nil]]; // Sumpfmonster [animationSource addObject:[NSArray arrayWithObjects: [UIImage imageNamed:@"bogeye0.png"], [UIImage imageNamed:@"bogeye1.png"], [UIImage imageNamed:@"bogeye2.png"], [UIImage imageNamed:@"bogeye3.png"], [UIImage imageNamed:@"bogeye4.png"], [UIImage imageNamed:@"bogeye5.png"], nil]]; // Spielersprite vorbereiten player = [[Sprite alloc] initWithImage: [UIImage imageNamed:@"liana1.png"] spriteTyp:0 parentView:canvas]; // Joypad joypad = [[UIImageView alloc] initWithFrame:CGRectMake(0, screenHeight-82, 142, 82)]; joypad.image = [UIImage imageNamed:@"joypad.png"]; [canvas addSubview:joypad]; jumpButton = [[UIImageView alloc] initWithFrame:CGRectMake(screenWidth-47, screenHeight-47, 47, 48)]; jumpButton.image = [UIImage imageNamed:@"jump.png"]; [canvas addSubview:jumpButton]; // breiteste Plattform herausfinden maxPlatformWidth=0; for (int i=0;i<[platformGraphicSource count];i++) { UIImage* tmpPic = [platformGraphicSource objectAtIndex:i]; if (maxPlatformWidth<tmpPic.size.width) maxPlatformWidth=tmpPic.size.width; } maxPlatformWidth/=2; [self restartLevel]; // Timer fuer Game Engine starten (30fps) CADisplayLink *callGameEngine = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameEngine)]; [callGameEngine setFrameInterval:2]; [callGameEngine addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } - (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];} #pragma mark - View lifecycle - (void)playerEngine { bool playerIsInTheAir = YES; playerHasContactToFloor=NO; // Kontakt mit Plattform? for (int p=0; p<[platforms count]; p++) { // Boden-Tile holen Sprite *tmpBottom = [platforms objectAtIndex:p]; // Player mit Boden-Teil auf Kollisions pruefen if ([player detectCollisionWith: tmpBottom]) { bool specialItem = NO; // auf besondere Plattformen checken int sTyp = [[[levelSource objectAtIndex:[tmpBottom sId]] objectAtIndex:0] intValue]; // Sprungfeder if ((sTyp==spring)&&(playerSpeedY>0)) { specialItem=YES; playerSpeedY=up*18; playerLooksLike=jump; [tmpBottom setAnimationTyp:[animationSource objectAtIndex:springjump] spriteTyp:0 duration:0.25 repeat:1]; }; // Zielflagge if ((sTyp==flag)&&(player.center.y<tmpBottom.center.y)) { specialItem=YES; level++; [self restartLevel]; } // +1 Leben if (sTyp==extralife) { specialItem=YES; [tmpBottom removeFromSuperview]; [platforms removeObject:tmpBottom]; p--; } if (!specialItem) if (player.center.y<tmpBottom.frame.origin.y) { // Bei Bodenkontakt: bouncen if (playerSpeedY > 1) { playerSpeedY = -playerSpeedY * 0.3; playerHasContactToFloor = YES; } // oder wenn Schwung zu gering: // auf Boden absetzen else if (playerSpeedY >= 0) { playerSpeedY = 0; playerIsInTheAir = NO; playerHasContactToFloor = YES;} // aber auf jeden Fall: // an Plattform ausrichten! [player setCenter: player.center.x y:tmpBottom.frame.origin.y - player.frame.size.height/2+4]; } } } // Animation an Verhalten anpassen // springen und fallen if (playerSpeedY!=0) [player setSpriteTyp: [[animationSource objectAtIndex:walk] objectAtIndex:3] typ:0]; // rechts else if (playerSpeedX>0) [player setSpriteTyp: [[animationSource objectAtIndex:walk] objectAtIndex:(zaehler/5+100000)%15] typ:0]; // links else if (playerSpeedX<0) [player setSpriteTyp: [[animationSource objectAtIndex:walk] objectAtIndex:14-(zaehler/5+100000)%15] typ:0]; // stehen else if (playerSpeedX==0) [player setSpriteTyp: [[animationSource objectAtIndex:walk] objectAtIndex:0] typ:0]; // Gravitation einwirken lassen if (playerIsInTheAir) playerSpeedY+=down*0.75; // Sprungkraft nur bis zu bestimmter Hoehe verstaerken if (playerAddJumpEnergy) { if (playerSpeedY>up*7) playerSpeedY+=up*1.2; else playerAddJumpEnergy=NO; } // Faellt in Loch if (player.center.y>screenHeight) [self restartLevel]; } - (void)platformEngine { // Handler: Alle Plattformdaten auf Sichtbarkeit pruefen // und bei Bedarf sichtbar schalten for (int currentPlatformInLoop = 0; currentPlatformInLoop < [levelSource count]; currentPlatformInLoop++) { // Daten holen int sTyp = [[[levelSource objectAtIndex:currentPlatformInLoop] objectAtIndex:0] intValue]; int posX = [[[levelSource objectAtIndex:currentPlatformInLoop] objectAtIndex:1] intValue]; int posY = [[[levelSource objectAtIndex:currentPlatformInLoop] objectAtIndex:2] intValue]; bool platformIsVisible = [[[levelSource objectAtIndex:currentPlatformInLoop] objectAtIndex:3] boolValue]; // Sprite sichtbar schalten, falls in Viewport if ((posX>zaehler-maxPlatformWidth) && (posX<zaehler+screenWidth+maxPlatformWidth)) { if (platformIsVisible==NO) { // Plattform als Sprite in Array platforms einfuegen Sprite *showPlatform = [[Sprite alloc] initWithImage:[platformGraphicSource objectAtIndex:sTyp] spriteTyp: 0 parentView: canvas]; if (sTyp==bogeye) [showPlatform setAnimationTyp:[animationSource objectAtIndex:bogeyewalk] spriteTyp:bogeye duration:0.5 repeat:0]; // Auf Display Setzen [showPlatform setCenter:posX-zaehler y:posY]; [showPlatform setId:currentPlatformInLoop]; [platforms addObject:showPlatform]; [levelSource replaceObjectAtIndex:currentPlatformInLoop withObject:[NSArray arrayWithObjects: [NSNumber numberWithInteger:sTyp], // spriteTyp [NSNumber numberWithDouble:posX], // x-Pos [NSNumber numberWithDouble:posY], // y-Pos [NSNumber numberWithBool:YES], // Sichtbarkeit nil]]; // z-Index sortieren von oben nach unten // damit Staemme von hoeheren Plattformen // die Plattformen darunter nicht verdecken! for (int zIndex = 0; zIndex < screenHeight; zIndex +=rasterY) { for (int sortCurrentVisiblePlatform = 0; sortCurrentVisiblePlatform < [platforms count]; sortCurrentVisiblePlatform++) { Sprite *existingPlatform = [platforms objectAtIndex:sortCurrentVisiblePlatform]; int platformTyp= [[[levelSource objectAtIndex:currentPlatformInLoop] objectAtIndex:0] intValue]; if ((platformTyp==bogeye) || ((existingPlatform.frame.origin.y <= zIndex) && (existingPlatform.frame.origin.y > zIndex-rasterY))) { [self.view bringSubviewToFront:existingPlatform]; } } } // z-Index sortieren Ende } } } // Handler: alle sichtbaren Plattformen for (int currentVisiblePlatformInLoop=0; currentVisiblePlatformInLoop < [platforms count]; currentVisiblePlatformInLoop++) { Sprite *showPlatform=[platforms objectAtIndex:currentVisiblePlatformInLoop]; int spriteId = [showPlatform sId]; // Daten holen int sTyp = [[[levelSource objectAtIndex:spriteId] objectAtIndex:0] intValue]; double posX = [[[levelSource objectAtIndex:spriteId] objectAtIndex:1] doubleValue]; double posY = [[[levelSource objectAtIndex:spriteId] objectAtIndex:2] doubleValue]; // Sprite sichtbar schalten, falls in Viewport if ((posX > zaehler - maxPlatformWidth) && (posX < zaehler + screenWidth + maxPlatformWidth)) { if (sTyp!=bogeye) [showPlatform setCenter:posX-zaehler y:posY]; } else { // Plattform wieder loeschen [levelSource replaceObjectAtIndex:spriteId withObject: [NSArray arrayWithObjects: [NSNumber numberWithInteger:sTyp],// spriteTyp [NSNumber numberWithDouble:posX], // x-Pos [NSNumber numberWithDouble:posY], // y-Pos [NSNumber numberWithBool:NO], // Sichtbarkeit nil]]; [showPlatform removeFromSuperview]; [platforms removeObject:showPlatform]; currentVisiblePlatformInLoop--; } } } - (void)parallaxScrolling { fogMove+=0.5; [layer0 setCenter:-((960 + zaehler)/2) % 960 + layer0.frame.size.width/2 y:screenHeight/2]; [layer1 setCenter:-((960 + zaehler)/3) % 960 + layer1.frame.size.width/2 y:screenHeight/2]; [fogLayer setCenter:-fmod((480 + zaehler + fogMove)/2,480) + fogLayer.frame.size.width/2 y:screenHeight/2]; } - (void)enemyEngine { // Plattformcheck START for (int currentEnemy=0;currentEnemy<[platforms count];currentEnemy++) { Sprite *enemySprite = [platforms objectAtIndex:currentEnemy]; int spriteId = [enemySprite sId]; int sTyp= [[[levelSource objectAtIndex:spriteId] objectAtIndex:0] intValue]; // Monster bewegen if (sTyp==bogeye) { // Monster nach vorne setzen [self.view bringSubviewToFront:enemySprite]; // auf Kollision mit allen anderen Plattformen pruefen for (int otherVisiblePlatforms=0; otherVisiblePlatforms<[platforms count]; otherVisiblePlatforms++) { if (otherVisiblePlatforms!=currentEnemy) { Sprite *otherPlatform=[platforms objectAtIndex:otherVisiblePlatforms]; // Beruehrung mit Plattform? if ([enemySprite detectCollisionWith:otherPlatform]) { // Monster AUF Plattform? if (enemySprite.center.y < otherPlatform.frame.origin.y) { if (enemySprite.center.x < otherPlatform.frame.origin.x) { if ([enemySprite movingDirection]==right) { [enemySprite setMovingDirection: -[enemySprite movingDirection]]; [enemySprite mirrorSprite:left]; } } else if (enemySprite.center.x > otherPlatform.frame.origin.x + otherPlatform.frame.size.width) { if ([enemySprite movingDirection] == left) { [enemySprite setMovingDirection: -[enemySprite movingDirection]]; [enemySprite mirrorSprite:right]; } } else { [enemySprite setCenter:enemySprite.center.x y:otherPlatform.frame.origin.y - enemySprite.frame.size.height/3]; } } } // Beruehrung mit Plattform ENDE } } // Sprite bewegen [enemySprite moveBy:-bogeyeSpeed*[enemySprite movingDirection] - playerSpeedX y:0]; } } // Plattformcheck ENDE // Kollision mit Sally START for (int currentEnemy=0;currentEnemy<[platforms count];currentEnemy++) { Sprite *enemySprite = [platforms objectAtIndex:currentEnemy]; int spriteId = [enemySprite sId]; int sTyp= [[[levelSource objectAtIndex:spriteId] objectAtIndex:0] intValue]; // Monster? if (sTyp==bogeye) { if ([enemySprite detectCollisionWith:player]) { // Player kollidiert mit Sumpfmonster? if ([player detectCollisionWith:enemySprite]) { // wenn in Fallbewegung: Sumpfmonster entfernen if (playerSpeedY>0) { // kleiner Sprung playerSpeedY=-6; [platforms removeObject:enemySprite]; [UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionCurveEaseIn animations:^{ [enemySprite moveBy:0 y:100]; [enemySprite setAlpha:0.0]; } completion:^(BOOL finished) { [enemySprite removeFromSuperview]; }]; } else [self restartLevel]; } } } } // Kollision mit Sally ENDE } // ------------------- // --- Game Loop ----- // ------------------- - (void)gameEngine { if (normalAction) { // Zaehler fuer Animationen zaehler+=playerSpeedX; [self enemyEngine]; [self platformEngine]; [self parallaxScrolling]; [self playerEngine]; [player moveBy:0 y: playerSpeedY]; // z-Indizes sortieren [self.view bringSubviewToFront:player]; [self.view bringSubviewToFront:joypad]; [self.view bringSubviewToFront:jumpButton]; } } - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *allTouches = [touches allObjects]; CGPoint coord = [[allTouches objectAtIndex:[touches count]-1] locationInView:self.view]; // Springen if (!((coord.x<=100) && (coord.y>screenHeight/2)) && (playerHasContactToFloor)) { playerAddJumpEnergy = YES; playerSpeedY = up*5; playerHasContactToFloor=NO; } // oder Laufen, wenn Joypad beruehrt else { [self touchesMoved:touches withEvent:event]; } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *allTouches = [touches allObjects]; CGPoint coord = [[allTouches objectAtIndex:[touches count]-1] locationInView:self.view]; if ((coord.x<=100) && (coord.y>screenHeight/2)) { playerSpeedX = (coord.x-50)/5; if (playerSpeedX < -5) playerSpeedX=-5; if (playerSpeedX > 5) playerSpeedX=5; if (playerSpeedX < 0) [player mirrorSprite:left]; else [player mirrorSprite:right]; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *allTouches = [touches allObjects]; CGPoint coord = [[allTouches objectAtIndex:[allTouches count]-1] locationInView:self.view]; if ((coord.x<=200) && (coord.y>screenHeight/2)) { playerSpeedX = 0; } else playerAddJumpEnergy = NO; } - (void)viewDidUnload {[super viewDidUnload];} - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); } @end