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