Hier finden Sie die Quellcodes und benötigten Grafiken zum Geschicklichkeitsspiel „I-Type“ aus dem Buch (Kapitel 4.3), damit Sie den langen Code nicht von Hand abtippen müssen.

Video des Gameplays:


Verwendete Grafiken: Download

Quellcode:

#import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>
#import <QuartzCore/QuartzCore.h>
#import "Sprite.h"
#import "Particle.h"

@interface itypeViewController : UIViewController {
  // Das duerfte bekannt sein:
  UIView *canvas;
  Sprite *player;
  int zaehler;
  bool normalAction;
  int level;
  double screenWidth;
  double screenHeight;
  
  // Steuerung
  UIImageView *joypad;
  double playerSpeedX;
  double playerSpeedY;
  
  // Container fuer die Plattformen
  NSMutableArray *areaTop;
  NSMutableArray *areaBottom;
  int areaCurrentTile;
  int tilesTotal;
  
  // Preloader fuer die Grafiken
  NSMutableArray *imageSource;
  NSMutableArray *animationSource;
  
  // Aliens
  NSMutableArray *enemySource;
  NSMutableArray *enemy;
  float sinus[628];
  int maxSpriteWidth;
  
  // Schuss
  NSMutableArray *shots;
  
  // Schuesse der Aliens
  NSMutableArray *alienshots;
  
  // Sterne, Explosionen, etc
  NSMutableArray *backgroundParticles;
  
}

@property (nonatomic,strong) UIView *canvas;
@property (nonatomic,strong) UIImageView *joypad;
@property (nonatomic,strong) Sprite *player;
@property (nonatomic, strong) NSMutableArray *imageSource;
@property (nonatomic, strong) NSMutableArray *animationSource;
@property (nonatomic, strong) NSMutableArray *enemySource;
@property (nonatomic, strong) NSMutableArray *enemy;
@property (nonatomic, strong) NSMutableArray *areaTop;
@property (nonatomic, strong) NSMutableArray *areaBottom;
@property (nonatomic, strong) NSMutableArray *shots;
@property (nonatomic, strong) NSMutableArray *alienshots;
@property (nonatomic, strong) NSMutableArray *backgroundParticles;
@end
#import "itypeViewController.h"
#import "Sprite.h"
#import "Particle.h"
#include "leveldesign.h"

@implementation itypeViewController
@synthesize canvas, joypad, player, enemy, imageSource, animationSource, enemySource, areaTop, areaBottom, shots, alienshots, backgroundParticles;


// ----------------------------
// --- ausgemustertes Tile  ---
// --- neu gestylt nach vorne  ---
// ----------------------------

- (void) setTile: (int) tile currentPosition: (int) curPos {
  
  // Tile OBEN:
  Sprite *tmpTop = [areaTop objectAtIndex:tile];
  int spriteTopTyp = pattern[patternSequence[level][curPos/tilesProPattern]]
                                                [curPos%tilesProPattern][0][1];
  double spriteTopPosY = pattern[patternSequence[level][curPos/tilesProPattern]]
                                                [curPos%tilesProPattern][0][0] -
                                                tmpTop.frame.size.height/2;
  // Design anpassen
  [tmpTop setSpriteTyp:[imageSource objectAtIndex:spriteTopTyp] typ:0];
  
  // ans Ende der Tilesreihe springen
  [tmpTop moveBy: tilesTotal*tileSize y: spriteTopPosY- tmpTop.center.y];
  
  // Tile UNTEN:
  Sprite *tmpBottom = [areaBottom objectAtIndex:tile];
  int spriteBottomTyp = pattern[patternSequence[level][curPos/tilesProPattern]]
                                                [curPos%tilesProPattern][1][1];
  double spriteBottomPosY = screenHeight - pattern[patternSequence[level]
                                                [curPos/tilesProPattern]]
                                                [curPos%tilesProPattern][1][0] +
                                                tmpBottom.frame.size.height/2;
  // Design anpassen
  [tmpBottom setSpriteTyp:[imageSource objectAtIndex:spriteBottomTyp] typ:0];
  // ans Ende der Tilesreihe springen
  [tmpBottom moveBy:tilesTotal*tileSize y: spriteBottomPosY-tmpBottom.center.y];
}

// -------------------------
// --- Spiel vorbereiten ---
// -------------------------

- (void) restartLevel {
  // Reset Aliens
  for (int p=0;p<[enemy count];p++) {
    [[enemy objectAtIndex:p] removeFromSuperview];
    //[[enemy objectAtIndex:p] deleteSprite];
  }
  [enemy removeAllObjects];    
  
  // alle Schuesse entfernen
  for (int p=0;p<[shots count];p++) {
    [[shots objectAtIndex:p] die];
  }
  [shots removeAllObjects];
  for (int p=0;p<[alienshots count];p++) {
    [[alienshots objectAtIndex:p] die];
  }
  [alienshots removeAllObjects];
  
  // restliche Partikel entfernen
  for (int p=0;p<[backgroundParticles count];p++) {
    [[backgroundParticles objectAtIndex:p] die];
  }
  [backgroundParticles removeAllObjects];
  
  areaCurrentTile = -1;
  for (int i=0; i<tilesTotal; i++) {
    areaCurrentTile++;
    // Tiles chronologisch links ausserhalb des Displays setzen
    // damit sie dann ueber setTile korrekt platziert werden!
    [[areaTop objectAtIndex:i] setCenter: -(tilesTotal-i)*tileSize y:0];
    [[areaBottom objectAtIndex:i] setCenter: -(tilesTotal-i)*tileSize y:0];
    [self setTile:i currentPosition: i];
  }
  [player setCenter:screenWidth/2 y:screenHeight/2];
  [player setAnimationTyp:[animationSource objectAtIndex:spaceship]
                spriteTyp:0
                 duration:2.0
                   repeat:0];
  playerSpeedX=0;
  playerSpeedY=0;
  zaehler=0;
  normalAction = YES;
}


- (void) loadView {
  
  // Display: Vollbild und Dauerbeleuchtung
  [[UIApplication sharedApplication] setStatusBarHidden:YES];
  [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
  
  // Hintergrund vorbereiten
  canvas = [[UIView alloc] initWithFrame:[[UIScreen mainScreen]
                                                            applicationFrame]];
  canvas.backgroundColor=[UIColor blackColor];
  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;
  
  tilesTotal = screenWidth/tileSize + 1;
  
  // Preloader fuer Bilder (wg. Performance)
  imageSource = [[NSMutableArray alloc] init];
  for (int p=0; p<=4; p++) {
    [imageSource addObject:[UIImage imageNamed:
                            [NSString stringWithFormat:@"area%d.png",p]]];
  }
  
  // Preloader fuer Animationen
  animationSource = [[NSMutableArray alloc] init];
  [animationSource addObject:[NSArray arrayWithObjects:   
                              [UIImage imageNamed:@"itype0.png"],
                              [UIImage imageNamed:@"itype1.png"],
                              [UIImage imageNamed:@"itype2.png"],
                              [UIImage imageNamed:@"itype3.png"],
                              [UIImage imageNamed:@"itype4.png"],
                              [UIImage imageNamed:@"itype5.png"],
                              [UIImage imageNamed:@"itype6.png"],
                              [UIImage imageNamed:@"itype7.png"],
                              nil]];
  [animationSource addObject:[NSArray arrayWithObjects:   
                              [UIImage imageNamed:@"itype_explosion0.png"],
                              [UIImage imageNamed:@"itype_explosion1.png"],
                              [UIImage imageNamed:@"itype_explosion2.png"],
                              [UIImage imageNamed:@"itype_explosion3.png"],
                              [UIImage imageNamed:@"itype_explosion4.png"],
                              [UIImage imageNamed:@"itype_explosion5.png"],
                              [UIImage imageNamed:@"itype_explosion6.png"],
                              [UIImage imageNamed:@"itype_explosion7.png"],
                              [UIImage imageNamed:@"itype_explosion8.png"],
                              [UIImage imageNamed:@"itype_explosion9.png"],
                              [UIImage imageNamed:@"itype_explosion10.png"],
                              nil]];
  
  // Area vorbereiten
  areaTop = [[NSMutableArray alloc] init];
  areaBottom = [[NSMutableArray alloc] init];
  for (int p=0; p<tilesTotal; p++) {
    Sprite *tmpTop = [[Sprite alloc]
                       initWithImage:[imageSource objectAtIndex: 0]
                       spriteTyp:0
                       parentView:canvas];
    Sprite *tmpBottom = [[Sprite alloc]
                          initWithImage:[imageSource objectAtIndex: 0]
                          spriteTyp:0
                          parentView:canvas];
    [areaTop addObject:tmpTop];
    [areaBottom addObject:tmpBottom];
  }
  
  // Gegner vorbereiten

  // Alienanimationen in enemySource speichern
  enemySource = [[NSMutableArray alloc] init];
  [enemySource addObject:[NSArray arrayWithObjects:   
                          [UIImage imageNamed:@"alien0.png"],
                          nil]];
  [enemySource addObject:[NSArray arrayWithObjects:   
                          [UIImage imageNamed:@"alien1.png"],
                          [UIImage imageNamed:@"alien1b.png"],
                          nil]];
  [enemySource addObject:[NSArray arrayWithObjects:   
                          [UIImage imageNamed:@"alien2.png"],
                          [UIImage imageNamed:@"alien2a.png"],
                          [UIImage imageNamed:@"alien2b.png"],
                          [UIImage imageNamed:@"alien2c.png"],
                          [UIImage imageNamed:@"alien2d.png"],
                          nil]];
  [enemySource addObject:[NSArray arrayWithObjects:   
                          [UIImage imageNamed:@"alien3.png"],
                          nil]];
  [enemySource addObject:[NSArray arrayWithObjects:   
                          [UIImage imageNamed:@"alien3b.png"],
                          nil]];

  // Spritecontainer vorbereiten und noch nicht fuellen  
  enemy = [[NSMutableArray alloc] init];

  // Berechnet die maximale Breite, die ein Sprite einnehmen kann, um es
  // in ausreichendem Abstand neben dem Display erscheinen zu lassen
  maxSpriteWidth=0;
  for (int i=0;i<[enemySource count];i++) {
    NSArray *getAnimArray = [enemySource objectAtIndex:i];
    UIImage * tmpPic = [getAnimArray objectAtIndex:0];
    if (maxSpriteWidth<tmpPic.size.width) maxSpriteWidth=tmpPic.size.width;
  }
  // davon die Haelfte, um mit center besser arbeiten zu koennen
  maxSpriteWidth/=2;

  // Sinus-Array vorbereiten
  for (float i = 0; i < 628; i++) {
    sinus[(int)i]=sinf(i/100);
  }
  
  // Raumschiff vorbereiten
  player = [[Sprite alloc] initWithImage: [UIImage imageNamed:@"itype0.png"]
                            spriteTyp:0
                           parentView:canvas];
  [player setAnimationTyp:[animationSource objectAtIndex:spaceship]
                spriteTyp:0
                 duration:2.0
                   repeat:0];
  [player addMask:2 y:4 width:33 height:13];
  [player addMask:37 y:10 width:19 height:3];
  [player setCenter:100 y:screenHeight/2];
  
  // Joypad
  joypad = [[UIImageView alloc] initWithFrame:CGRectMake(20, screenHeight-120,
                                                         100, 100)];
  joypad.image = [UIImage imageNamed:@"joypad.png"];
  [canvas addSubview:joypad];
  
  
  level = 0;
  areaCurrentTile=tilesProPattern-1;
  
  shots = [[NSMutableArray alloc] init];
  [NSTimer scheduledTimerWithTimeInterval:0.5
                                   target: self
                                 selector:@selector(shoot)
                                 userInfo:nil
                                  repeats:YES];
  
  alienshots = [[NSMutableArray alloc] init];
  
  backgroundParticles = [[NSMutableArray alloc] init];
  [NSTimer scheduledTimerWithTimeInterval:0.5
                                   target: self
                                 selector:@selector(stars)
                                 userInfo:nil
                                  repeats:YES];
  
  
  // Level vorbereiten
  [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) shoot {
  if (normalAction) {
    Particle *shoot = [[Particle alloc]
                  initParticleAt:player.frame.origin.x + player.frame.size.width
                  y:player.center.y+2
                       width:20
                       height:1
                       alpha:1.0
                       lifetime:0
                       gravity:0.00
                       wind:0.0
                       rX:5.0
                       rY:0.0
                       col:[UIColor whiteColor] parentView:canvas];
    [shots addObject:shoot];
  }
}

-(void) stars {
  if (normalAction) {
    double starSize = arc4random()%3 + 1;
    Particle *star =
    [[Particle alloc] initParticleAt:screenWidth
                                   y:fmod(arc4random(),screenHeight) 
                               width:1 
                              height:1
                               alpha:starSize/4 
                            lifetime:0
                             gravity:0.00 
                                wind:0.0 
                                  rX:-starSize-0.2 
                                  rY:0.0 
                                 col:[UIColor grayColor]
                          parentView:canvas];
    [backgroundParticles addObject:star];
  }
}

// -------------------
// --- Tile Engine ---
// -------------------

-(void) tileEngine {
  for (int p=0; p<[areaTop count]; p++) {
    // Area um 1 Pixel nach links scrollen
    Sprite *tmpTop = [areaTop objectAtIndex:p];
    Sprite *tmpBottom = [areaBottom objectAtIndex:p];
    [tmpTop moveBy:-1 y:0];
    [tmpBottom moveBy:-1 y:0];
    if (
        [player detectCollisionWithMask: tmpTop] ||
        [player detectCollisionWithMask: tmpBottom]
        ) {
      normalAction=NO;
      [player setAnimationTyp:[animationSource objectAtIndex:explosion]
                    spriteTyp:0
                     duration:1.0
                       repeat:1];
      [self performSelector:@selector(restartLevel) withObject:nil afterDelay:1.0];
    }
    // wenn aus Display verschwunden, vorne anstellen
    if (tmpTop.center.x + tileSize/2 <= 0) {
      areaCurrentTile++;
      // wenn Level zu Ende: keine Aktion mehr!
      if (areaCurrentTile>=tilesProPattern*patternProLevel) normalAction = NO;
      [self setTile: p currentPosition: areaCurrentTile];
    }
  }
}

// --------------------
// --- Enemy Engine ---
// --------------------

-(void) enemyEngine {
  
  // Alle Aliens in Daten-Array
  for (int curEnemy=0; curEnemy<aliensProLevel; curEnemy++) {
    
    int startX=aliens[level][curEnemy][0];
    int startY=aliens[level][curEnemy][1];
    int spriteImage=aliens[level][curEnemy][2];
    int moveTyp=aliens[level][curEnemy][3];
    int needsShotsToDie=aliens[level][curEnemy][4];
    
    if (startX==zaehler) {
      NSArray *getAnimArray = [enemySource objectAtIndex:spriteImage];
      UIImage * tmpPic = [getAnimArray objectAtIndex:0];
      
      Sprite *newEnemy = [[Sprite alloc] initWithImage: tmpPic
                                             spriteTyp:spriteImage
                                            parentView:canvas];
      [newEnemy setAnimationTyp:getAnimArray
                      spriteTyp:moveTyp
                       duration:1.0
                         repeat:0];
      [newEnemy setCenter:screenWidth+maxSpriteWidth y:startY];
      [newEnemy setId:curEnemy];
      [newEnemy setShieldPower:needsShotsToDie];
      [enemy addObject:newEnemy];
    }
  }
  
  // Alle sichtbaren Alien in Sprite-Array
  for (int curVisibleEnemy=0; curVisibleEnemy<[enemy count]; curVisibleEnemy++){
    Sprite *visibleEnemy = [enemy objectAtIndex:curVisibleEnemy];
    
    int startX=aliens[level][[visibleEnemy sId]][0];
    int startY=aliens[level][[visibleEnemy sId]][1];
    
    int posX = visibleEnemy.center.x;
    int posY = visibleEnemy.center.y;
    
    switch ([visibleEnemy spriteTyp]) {
      case wobble:
        posX = posX-3;
        posY = startY+20*sinus[(posX*4)%628];
        
        // Streubomben
        if (posX%30 <= 2) {
          Particle *shoot =
          [[Particle alloc] initParticleAt:visibleEnemy.frame.origin.x
                                         y:visibleEnemy.center.y
                                     width:5
                                    height:5
                                     alpha:1.0
                                  lifetime:50
                                   gravity:0.1
                                      wind:0.0
                                        rX:-5.0
                                        rY:0.0
                                       col:[UIColor yellowColor]
                                parentView:canvas];
          [alienshots addObject:shoot];
        }
        
        break;
      case jumper:
        posX = posX-3;
        posY = startY-100*sinus[((int)(posX*2)+314)%314]; // nur Springen
        
        // einfache Schuesse
        if (zaehler%50 == 0) {
          Particle *shoot =
          [[Particle alloc] initParticleAt:visibleEnemy.frame.origin.x
                                         y:visibleEnemy.center.y 
                                     width:40 
                                    height:5 
                                     alpha:1.0 
                                  lifetime:200 
                                   gravity:0.0 
                                      wind:0.0 
                                        rX:-8.0 
                                        rY:0.0 
                                       col:[UIColor redColor]
                                parentView:canvas];
          [alienshots addObject:shoot];
        }
        
        break;
      case jumper2:
        posX = posX-3;
        posY = startY-200*sinus[((int)(posX*2)+314)%314]; // nur Springen
        // Torpedostorm
        if (zaehler%4 == 0) {
          Particle *shoot =
          [[Particle alloc] initParticleAt:visibleEnemy.frame.origin.x
                                         y:visibleEnemy.center.y 
                                     width:4
                                    height:4 
                                     alpha:1.0 
                                  lifetime:0 
                                   gravity:0.25
                                      wind:-0.5
                                        rX:5.0
                                        rY:-4.0 
                                       col:[UIColor blueColor]
                                parentView:canvas];
          [alienshots addObject:shoot];
        }
        break;
      case  guerilla:
        posX = posX - 1; // = Tile-Geschwindigkeit
        if (
            (posX > screenWidth - 100) &&
            (posX < screenWidth - 50 ) &&
            (posY > startY-50)
            ) posY = posY-1;
        if (
            (posX < 250) && (posY < startY)) posY = posY+1;
        // diagonal
        if (zaehler%20 == 1) {
          Particle *shoot = 
          [[Particle alloc] initParticleAt:visibleEnemy.frame.origin.x+5
                                         y:visibleEnemy.frame.origin.y+5
                                     width:3 
                                    height:3 
                                     alpha:1.0 
                                  lifetime:0 
                                   gravity:0.0 
                                      wind:0.0 
                                        rX:-4.0
                                        rY:-2.0
                                       col:[UIColor orangeColor]
                                parentView:canvas];
          [alienshots addObject:shoot];
        }
        break;
      case twist:
        posX = screenWidth + maxSpriteWidth - (zaehler - startX) - 
                                                    50*sinus[(zaehler*10)%628];
        posY = startY + 50 * sinus[((zaehler+78)*10)%628];
        break;
      case twistFollow1:
        posX = screenWidth + maxSpriteWidth - (zaehler - startX) - 
                                            50*sinus[(628+(zaehler-3)*10)%628];
        posY = startY + 50 * sinus[(628+(zaehler-3+78)*10)%628];
        break;
      case twistFollow2:
        posX = screenWidth + maxSpriteWidth - (zaehler - startX) -
                                            50*sinus[(628+(zaehler-5)*10)%628];
        posY = startY + 50 * sinus[(628+(zaehler-5+78)*10)%628];
        // Mine
        if (zaehler%10 == 0) {
          Particle *shoot = 
          [[Particle alloc] initParticleAt:visibleEnemy.frame.origin.x 
                                         y:visibleEnemy.center.y 
                                     width:2 
                                    height:2 
                                     alpha:1.0 
                                  lifetime:50 
                                   gravity:0.0 
                                      wind:0.0 
                                        rX:0.0 
                                        rY:0.0 
                                       col:[UIColor whiteColor]
                                parentView:canvas];
          [alienshots addObject:shoot];
        }        
        break;
      case bigtwist:
        posX = screenWidth + maxSpriteWidth - 2 * (zaehler - startX) - 
                                                  100*sinus[(zaehler*10)%628];
        posY = startY + 100 * sinus[((zaehler+78)*10)%628];
        break;
      case bigtwistFollow1:
        posX = screenWidth + maxSpriteWidth - 2 * (zaehler - startX) -
                                          100*sinus[(628+(zaehler-1)*10)%628];
        posY = startY + 100 * sinus[(628+(zaehler-1+78)*10)%628];
        break;
      case bigtwistFollow2:
        posX = screenWidth + maxSpriteWidth - 2 * (zaehler - startX) -
                                          100*sinus[(628+(zaehler-2)*10)%628];
        posY = startY + 100 * sinus[(628+(zaehler-2+78)*10)%628];
        break;
      case attack:
        posX = posX-2;
        if (player.center.y>posY) posY+=1; else posY-=1;
        // wurfgeschoss
        if (zaehler%20 == 1) {
          Particle *shoot = 
          [[Particle alloc] initParticleAt:visibleEnemy.frame.origin.x 
                                         y:visibleEnemy.center.y
                                     width:3 
                                    height:3 
                                     alpha:1.0 
                                  lifetime:0 
                                   gravity:0.1 
                                      wind:0.0
                                        rX:-4.0
                                        rY:-3.0 
                                       col:[UIColor yellowColor]
                                parentView:canvas];
          [alienshots addObject:shoot];
        }
        break;
        
      default:
        break;
    }
    // Alien positionieren
    [visibleEnemy setCenter:posX y:posY];
    
    // Kollisionsabfrage Alien
    if ([player detectCollisionWithMask: visibleEnemy]) {
      normalAction=NO;
      [player setAnimationTyp:[animationSource objectAtIndex:explosion]
                    spriteTyp:0
                     duration:1.0
                       repeat:1];
      [self performSelector:@selector(restartLevel)
                 withObject:nil
                 afterDelay:1.0];
    }
    
    // Alien entfernen, wenn aus Display raus
    if (visibleEnemy.center.x<-visibleEnemy.frame.size.width/2) {
      [visibleEnemy removeFromSuperview];
      [enemy removeObject:visibleEnemy];
    }
    
  }    
  
  // Handling Alien Schuesse
  for (int i=0;i<[alienshots count];i++) {
    Particle* shot=[alienshots objectAtIndex:i];
    [shot go];
    
    // Kollisionsabfrage Alien Schuesse
    if ([shot detectCollisionWithFrame:[player frame]]) {
      normalAction=NO;
      [player setAnimationTyp:[animationSource objectAtIndex:explosion]
                    spriteTyp:0
                     duration:1.0
                       repeat:1];
      [self performSelector:@selector(restartLevel)
                 withObject:nil
                 afterDelay:1.0];
    }
    
    // Schuesse: Partikel loeschen
    if ([shot lifetimeHasEnded]) {
      [alienshots removeObject:shot];
    }      
  }
  
  
}


- (void)shotEngine {
  for (int i=[shots count]-1;i>=0;i--) {
    Particle* shot = [shots objectAtIndex:i];
    
    [shot go];
    
    // Kollisionsabfrage mit Aliens
    int visibleAliens=[enemy count];
    for (int p=0;p<visibleAliens;p++) {
      Sprite * hitAlien = [enemy objectAtIndex:p];
      if ([shot detectCollisionWithFrame:[hitAlien frame]]) {
        // Schuss entfernen
        [shot die];
        
        // Schutzschild schwaechen
        [hitAlien setShieldPower:[hitAlien shieldPower]-1];

        // wenn Schutzschirm erloschen: getroffenes Alien entfernen
        if ([hitAlien shieldPower]==0) {
          
          // Explosionspartikel
          for (int z=0;z<20;z++) {
            Particle* explosive =
            [[Particle alloc] initParticleAt:hitAlien.center.x
                                           y:hitAlien.center.y
                                       width:5
                                      height:5
                                       alpha:1.0
                                    lifetime:arc4random()%20+30
                                     gravity:0.1
                                        wind:-0.1
                                          rX:fmod(arc4random(),6.1)-4.0
                                          rY:fmod(arc4random(),6.1)-3
                                         col:[UIColor grayColor]
                                  parentView:canvas];
            [explosive setParticleImage:[UIImage imageNamed:@"spark.png"]];
            [backgroundParticles addObject:explosive];
          }
          
          
          [hitAlien removeFromSuperview];
          [enemy removeObject:hitAlien];
          
          visibleAliens--;
        }
      }
    }
    
    if ([shot lifetimeHasEnded]) {
      [shots removeObject:shot];
    }
  }
}

// sonstige Partikelaktionen (Sterne, Explosionen etc.)
- (void)bgParticles {
  for (int i=[backgroundParticles count]-1;i>=0;i--) {
    Particle* bg = [backgroundParticles objectAtIndex:i];
    [bg go];
    if ([bg lifetimeHasEnded]) [backgroundParticles removeObject:bg];
  }
}

// -------------------
// --- Game Loop -----
// -------------------

-(void) gameEngine {
  
  if (normalAction) {
    
    // Zaehler fuer Animationen
    zaehler++;
    
    [self tileEngine];
    [self enemyEngine];
    [self shotEngine];
    [self bgParticles];
    
    [player moveBy:playerSpeedX y: playerSpeedY];
    
    // z-Indizes sortieren
    [self.view bringSubviewToFront:player];
    [self.view bringSubviewToFront:joypad];
    
  }
}    

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  [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-joypad.center.x)*(coord.x-joypad.center.x) +
      (coord.y-joypad.center.y)*(coord.y-joypad.center.y)
      <= (50 * 50)
      ) {
    playerSpeedX = (coord.x-joypad.center.x)/7;
    playerSpeedY = (coord.y-joypad.center.y)/7;
  }
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  NSArray *allTouches = [touches allObjects]; 
  
  CGPoint coord = [[allTouches objectAtIndex:[allTouches count]-1]
                   locationInView:self.view];
  if (
      (coord.x-joypad.center.x)*(coord.x-joypad.center.x) +
      (coord.y-joypad.center.y)*(coord.y-joypad.center.y)
      <= (50 * 50)
      ) {
    playerSpeedX = 0;
    playerSpeedY = 0;
  }
}



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
}

@end

Klassen:

#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) changeMovingDirection;
- (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 "leveldesign.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;
}


- (CGRect) frame {return pic.frame;}
- (CGPoint) center {return pic.center;}
- (int) spriteTyp { return spriteTyp; }
- (int) movingDirection { return movingDirection; }
- (void) changeMovingDirection { movingDirection = - movingDirection;}
- (void) setAlpha: (float) a {pic.alpha = a;};
- (void) mirrorSprite:(int) direction { pic.transform = CGAffineTransformMakeScale(direction,1);}

- (void) setId: (int) a {sId=a;}
- (int) sId {return sId;}
- (void) setShieldPower: (int) a  {shieldPower=a;}
- (int) shieldPower {return shieldPower;}

@end
#import <UIKit/UIKit.h>

@interface Particle : UIView {
  UIImageView *particle;
  double x;
  double y;
  double rX;
  double rY;
  float alpha;
  int lifetime;
  int step;
  double gravity;
  double wind;
  int width;
  int height;
  bool lifetimeHasEnded;
}

@property (nonatomic, strong) UIImageView *particle;

- (id) initParticleAt: (double) posX
                    y: (double) posY
                width: (double) w
               height: (double) h
                alpha: (double) a
             lifetime: (double) l
              gravity: (double) g
                 wind: (double) wx
                   rX: (double) rx
                   rY: (double) ry
                  col: (UIColor*) color
           parentView: (UIView*) parentView;

- (void) setParticleImage: (UIImage*) img;
- (void) go;

- (bool) detectCollisionWithFrame: (CGRect) sprite;
- (CGRect) frame;
- (CGPoint) center;
- (bool) lifetimeHasEnded;
- (void) die;

@end
#import "Particle.h"

#define screenWidth 480
#define screenHeight 320

@implementation Particle
@synthesize particle;


- (id) initParticleAt: (double) posX
                    y: (double) posY
                width: (double) w
               height: (double) h
                alpha: (double) a
             lifetime: (double) l
              gravity: (double) g
                 wind: (double) wx
                   rX: (double) rx
                   rY: (double) ry
                  col: (UIColor*) color
           parentView: (UIView*) parentView {
  if (self == [super init]) {
    particle = [[UIImageView alloc] initWithFrame:CGRectMake(posX-w/2, posY-h/2, w, h)];
    particle.backgroundColor=color;
    //[self addSubview:particle];
    [parentView addSubview:particle];
    x = posX;
    y = posY;
    rX = rx;
    rY = ry;
    alpha = a;
    lifetime = l;
    step = l;
    gravity = g;
    wind = wx;
    width = w;
    height = h;
    lifetimeHasEnded = NO;
  }
  return self;
}

- (void) setParticleImage: (UIImage*) img {
  particle.image = img;
  particle.backgroundColor=[UIColor clearColor];
  
}

- (void) go {
  if ((step>0)||(lifetime==0)) {
    step--;
    float faktor = (float)step/(float)lifetime;
    
    if (lifetime!=0) {
      particle.alpha=alpha * faktor;
    }
    
    rX += wind;
    rY += gravity;
    
    x = x + rX ;
    y = y + rY;
    
    particle.center=CGPointMake(x, y);
    
    if (
        (particle.frame.origin.x+particle.frame.size.width<0) ||
        (particle.frame.origin.x>screenWidth) ||
        (particle.frame.origin.y+particle.frame.size.height<0) ||
        (particle.frame.origin.y>screenHeight)
        ) {
      
      [self die];
    }
  }
  else [self die];
}

- (bool) detectCollisionWithFrame: (CGRect) sprite {
  bool collision = NO;
  if (CGRectIntersectsRect(sprite, particle.frame)){
    collision = YES;
  }    
  return collision;
}


- (CGRect) frame {return particle.frame;}
- (CGPoint) center {return particle.center;}
- (bool) lifetimeHasEnded {return lifetimeHasEnded;}
- (void) die {
  [particle removeFromSuperview];
  lifetimeHasEnded=YES;
}

@end

Leveldesign:

#define tileSize 80
#define tilesProPattern 5
#define patternProLevel 10
#define aliensProLevel 25

// Animationen
#define spaceship 0
#define explosion 1

// Aliens
#define alien 0
#define eyeball 1
#define staticRobot 2
#define snake 3
#define snakeFollow 4

// Aliens Choreografie
#define jumper 0
#define jumper2 1
#define wobble 2
#define guerilla 3
#define twist 4
#define twistFollow1 5
#define twistFollow2 6
#define bigtwist 7
#define bigtwistFollow1 8
#define bigtwistFollow2 9
#define attack 10

// Bewegungsrichtungen
#define left -1
#define right 1
#define up -1
#define down 1

extern double screenWidth;
extern double screenHeight;

extern int pattern[10][tilesProPattern][2][2];
extern int patternSequence[1][patternProLevel];
extern int aliens[1][aliensProLevel][5];

@interface leveldesign : NSObject {}
@end
#import "leveldesign.h"

int patternSequence[1][patternProLevel]=
{
  // Level 1
  {0,1,1,2,3,3,4,5,7,0}
};

int aliens[1][aliensProLevel][5]=
{
    {
        {120,280,alien,jumper,2},
        {200,280,alien,jumper,2},
        
        {340,100,eyeball,wobble,1},
        {360,140,eyeball,wobble,1},
        {370,60, eyeball,wobble,1},
        {380,180,eyeball,wobble,1},
        {400,240,eyeball,wobble,1},
        
        {500,160,snake,twist,2},
        {500,160,snakeFollow,twistFollow1,2},
        {500,160,snakeFollow,twistFollow2,2},
        
        {600,290,snake,jumper2,2},
        {601,290,snakeFollow,jumper2,2},
        {602,290,snakeFollow,jumper2,2},
        
        {620,320,staticRobot,guerilla,3},
        {700,320,staticRobot,guerilla,3},
        
        {900,150,alien,wobble,2},
        
        {1000,170,eyeball,attack,1},
        {1050,170,eyeball,attack,1},
        {1100,170,eyeball,attack,1},
        
        {1200,140,snake,twist,2},
        {1200,140,snakeFollow,twistFollow1,2},
        {1200,140,snakeFollow,twistFollow2,2},

        {1650,180,snake,bigtwist,2},
        {1650,180,snakeFollow,bigtwistFollow1,2},
        {1650,180,snakeFollow,bigtwistFollow2,2}

    }
    
};

int pattern[10][tilesProPattern][2][2]=
  { // 10 Pattern a 5 Segmente
    { // (oben: y-Koordinate, Typ)
      // (unten: y-Koordinate, Typ)
      {{  0, 0 },{ 0, 0 }},
      {{  0, 0 },{ 0, 0 }},
      {{  0, 0 },{ 20, 0 }},
      {{  0, 0 },{ 40, 0 }},
      {{  0, 0 },{ 20, 0 }}
    },
    {
      {{ 20, 0 },{ 20, 1 }},
      {{ 20, 1 },{ 20, 0 }},
      {{ 20, 2 },{ 20, 2 }},
      {{ 20, 2 },{ 20, 0 }},
      {{ 20, 1 },{ 20, 1 }}
    },
    {
      {{  20, 0 },{ 20, 0 }},
      {{  60, 2 },{ 40, 1 }},
      {{ 140, 3 },{ 60, 0 }},
      {{  60, 0 },{ 80, 1 }},
      {{  40, 2 },{ 60, 2 }}
    },
    {
      {{  20, 0 },{  40, 1 }},
      {{ 100, 2 },{  20, 2 }},
      {{ 100, 1 },{ 100, 1 }},
      {{ 120, 2 },{ 120, 4 }},
      {{ 100, 0 },{ 100, 0 }}
    },
    {
      {{ 80, 1 },{  80, 0 }},
      {{ 60, 0 },{  80, 0 }},
      {{ 60, 2 },{ 100, 1 }},
      {{ 20, 1 },{ 120, 1 }},
      {{ 40, 0 },{ 140, 0 }}
    },
    {
      {{ 20, 0 },{ 160, 2 }},
      {{ 20, 1 },{ 160, 2 }},
      {{ 40, 2 },{ 140, 0 }},
      {{ 60, 1 },{ 120, 4 }},
      {{ 80, 1 },{ 100, 0 }}
    },
    {
      {{ 100, 2 },{ 80, 1 }},
      {{ 120, 0 },{ 60, 0 }},
      {{ 140, 2 },{ 40, 2 }},
      {{ 160, 0 },{ 20, 2 }},
      {{ 160, 3 },{ 20, 0 }}
    },
    {
      {{ 60, 1 },{  80, 1 }},
      {{ 80, 1 },{ 100, 0 }},
      {{ 60, 0 },{ 100, 2 }},
      {{ 60, 0 },{ 120, 2 }},
      {{ 80, 2 },{ 100, 4 }}
    },
    {
      {{ 100, 4 },{ 40, 1 }},
      {{  80, 2 },{ 40, 2 }},
      {{  60, 1 },{ 20, 2 }},
      {{  40, 1 },{ 20, 1 }},
      {{  20, 0 },{ 40, 0 }}
    },
    {
      {{ 40, 1 },{ 40, 1 }},
      {{ 60, 2 },{ 40, 0 }},
      {{ 40, 0 },{ 60, 0 }},
      {{ 60, 0 },{ 80, 1 }},
      {{ 80, 1 },{ 80, 0 }}
    }
};

@implementation leveldesign
@end

Einen Kommentar schreiben

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