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

Einen Kommentar schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.