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

Video des Gameplays:


Verwendete Grafiken: Download

Quellcode:

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
#import <QuartzCore/QuartzCore.h>

@interface marblemazeViewController : UIViewController {
	UIImageView *canvas;
	UIImageView *ball;
	UIImageView *ballSchatten;
	NSMutableArray *walls;
	NSMutableArray *holes;
	
	CMMotionManager *motionManager;
	
	double ballSpeedX;
	double ballSpeedY;
	
	bool normalAction;
}

@property (nonatomic,strong) UIImageView *canvas;
@property (nonatomic,strong) UIImageView *ball;
@property (nonatomic,strong) UIImageView *ballSchatten;
@property (nonatomic, strong) NSMutableArray *walls;
@property (nonatomic, strong) NSMutableArray *holes;
@property (nonatomic, strong) CMMotionManager *motionManager;

- (void)missionFailed: (int) holeId;
- (void)gameEngine;


@end
#import "marblemazeViewController.h"
#include "leveldesign.h"

@implementation marblemazeViewController
@synthesize canvas, ball, ballSchatten, walls, holes, motionManager;

- (void)loadView {

  [[UIApplication sharedApplication] setStatusBarHidden:YES];  
  [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
  
  // Hintergrund furnieren
  canvas = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen]
                                               applicationFrame]];
  [canvas setImage:[UIImage imageNamed:@"canvas.png"]];
  canvas.userInteractionEnabled = YES;
  self.view = canvas;

  // Loecher bohren
  holes = [[NSMutableArray alloc] init];
  for(int i = 0; i < sizeof(holeX)/sizeof(holeX[0]); i++) {
    UIImageView *tempImgView = [[UIImageView alloc]initWithFrame:
                                CGRectMake(holeX[i]-15, holeY[i]-15, 30, 30)];
    [tempImgView setImage:[UIImage imageNamed:@"hole.png"]];
    if (i==0)[tempImgView setImage:[UIImage imageNamed:@"ziel.png"]];
    [holes addObject:tempImgView];
    [canvas addSubview:[holes objectAtIndex:i]];
  }
  
  // Waende ziehen
  walls = [[NSMutableArray alloc] init];
  for(int i = 0; i < sizeof(wallX0)/sizeof(wallX0[0]); i++) {
    UIImageView *tempImgView = [[UIImageView alloc] initWithFrame:
                                CGRectMake(wallX0[i], wallY0[i],
                                           wallX1[i]-wallX0[i],
                                           wallY1[i]-wallY0[i])];
    [tempImgView setImage:[UIImage imageNamed:@"wall.png"]];
    [walls addObject:tempImgView];
    [canvas addSubview:[walls objectAtIndex:i]];
  }
  
  // netter Effekt: Schlagschatten für die Murmel
  ballSchatten = [[UIImageView alloc] initWithFrame:CGRectMake(40+8, 440+8,
                                                               25, 25)];
  [ballSchatten setImage:[UIImage imageNamed:@"ball_shadow.png"]];
  [canvas addSubview:ballSchatten];
  
  // darueber die Murmel
  ball = [[UIImageView alloc] initWithFrame:CGRectMake(40, 440, 25, 25)];
  [ball setImage:[UIImage imageNamed:@"ball.png"]];
  [canvas addSubview:ball];
  
  // der uebliche Accelerometer
  motionManager = [[CMMotionManager alloc] init];
  motionManager.accelerometerUpdateInterval = 0.060;
  [motionManager startAccelerometerUpdates];
  
  ballSpeedX=0;
  ballSpeedY=0;
  
  normalAction = YES;
  
  CADisplayLink *callGameEngine = [CADisplayLink
                                   displayLinkWithTarget:self
                                   selector:@selector(gameEngine)];
  [callGameEngine setFrameInterval:2];
  [callGameEngine addToRunLoop:[NSRunLoop currentRunLoop]
                       forMode:NSDefaultRunLoopMode];
  
}

// Murmel im Loch: Animation
- (void)missionFailed: (int) holeId {
  normalAction = NO;
  __block int x=holeX[holeId];
  __block int y=holeY[holeId];
  
  // Verschachtelte Animationsbloecke:
  // Ball ins Loch
  [UIView transitionWithView:self.view
                    duration:0.3
                     options:UIViewAnimationOptionCurveEaseIn
                  animations:^{
    ball.center = CGPointMake(x, y);
    ballSchatten.center = CGPointMake(x, y);
    ball.transform = CGAffineTransformMakeScale(0.9,0.9);
  } completion:^(BOOL finished) {
    
    // Wenn Ball im Loch: ausblenden
    [UIView transitionWithView:self.view
                      duration:1.0
                       options:UIViewAnimationOptionCurveEaseIn
                    animations:^{
      ball.alpha=0.0;
      ballSchatten.alpha=0.0;
    } completion:^(BOOL finished) {
      ball.center = CGPointMake(40,440);
      ballSchatten.center = CGPointMake(40-4,440-4);
      ball.alpha=1.0;
      ballSchatten.alpha=1.0;
      normalAction=YES;
      ball.transform = CGAffineTransformMakeScale(1,1);
    }];
  }];
}

-(void) gameEngine {
  if (normalAction) {

    // Steuerung ueber Accelerometer
    CMAccelerometerData *acceleration = motionManager.accelerometerData;
    ballSpeedX+=acceleration.acceleration.x;
    ballSpeedY-=acceleration.acceleration.y;
  
    // Kollision mit Spielfeldrand
    if ((ball.center.x+ballSpeedX>320-10) || (ball.center.x+ballSpeedX<0+10)) {
      ballSpeedX=-ballSpeedX/4;
      if (ballSpeedX*ballSpeedX>0.5) ballSpeedY=ballSpeedY/4;
    }
    if ((ball.center.y+ballSpeedY>480-10) || (ball.center.y+ballSpeedY<0+10)) {
      if (ballSpeedY*ballSpeedY>0.5) ballSpeedX=ballSpeedX/4;
      ballSpeedY=-ballSpeedY/4;
    }
  
    // ins Loch fallen?
    for(int i = 0; i < sizeof(holeX)/sizeof(holeX[0]); i++) {
      UIImageView *hole = [holes objectAtIndex:i];
      if (
        (hole.center.x-ball.center.x)*(hole.center.x-ball.center.x) +
        (hole.center.y-ball.center.y)*(hole.center.y-ball.center.y) < 15*15
        )
        if (i==0) ball.center=CGPointMake(hole.center.x, hole.center.y);
        else [self missionFailed:i];
      }  
    
    
    // Kollision mit Waenden
    for(int i = 0; i < sizeof(wallX0)/sizeof(wallX0[0]); i++) {
      UIImageView *wall = [walls objectAtIndex:i];
      
      // Ueberlappung der Boundingboxen?
      if (CGRectIntersectsRect(CGRectMake(ball.frame.origin.x+ballSpeedX,
                                          ball.frame.origin.y+ballSpeedY,
                                          25, 25), wall.frame))
        // Murmel kommt von links
        {
        if ((ballSpeedX>0) &&
               (ball.center.x < wall.center.x) &&
               (ball.center.y > wallY0[i]) &&
               (ball.center.y < wallY1[i]) ) {
          ball.center = CGPointMake(wallX0[i]-13, ball.center.y);
          ballSpeedX=-ballSpeedX/4;
          if (ballSpeedX*ballSpeedX>0.5) ballSpeedY=ballSpeedY/4;
          
          // Murmel kommt von rechts
        } else if ((ballSpeedX<0) &&
                   (ball.center.x > wall.center.x) &&
                   (ball.center.y > wallY0[i]) &&
                   (ball.center.y < wallY1[i]) ) {
          ball.center = CGPointMake(wallX1[i]+13, ball.center.y);
          ballSpeedX=-ballSpeedX/4;
          if (ballSpeedX*ballSpeedX>0.5) ballSpeedY=ballSpeedY/4;
          
          // Murmel kommt von oben
        } else if ((ballSpeedY>0) &&
                   (ball.center.y < wall.center.y) &&
                   (ball.center.x > wallX0[i]) &&
                   (ball.center.x < wallX1[i]) ) {
          ball.center = CGPointMake(ball.center.x, wallY0[i]-13);
          if (ballSpeedY*ballSpeedY>0.5) ballSpeedX=ballSpeedX/4;
          ballSpeedY=-ballSpeedY/4;
          
          // Murmel kommt von unten

        } else if ((ballSpeedY<0) &&
                   (ball.center.y > wall.center.y) &&
                   (ball.center.x > wallX0[i]) &&
                   (ball.center.x < wallX1[i]) ) {
          ball.center = CGPointMake(ball.center.x, wallY1[i]+13);
          if (ballSpeedY*ballSpeedY>0.5) ballSpeedX=ballSpeedX/4;
          ballSpeedY=-ballSpeedY/4;
        }
      }
    }

    // Murmel bewegen
    ball.center = CGPointMake(ball.center.x+ballSpeedX,
                              ball.center.y+ballSpeedY);
    ballSchatten.center = CGPointMake(ball.center.x+8, ball.center.y+8);
  }  

}

- (void)didReceiveMemoryWarning {
  // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
  
  // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
  // Release any retained subviews of the main view.
  // e.g. self.myOutlet = nil;
}

@end
extern int holeX[15];
extern int holeY[15];

extern int wallX0[21];
extern int wallY0[21];
extern int wallX1[21];
extern int wallY1[21];

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

int holeX[15]={23,183,143,103,183,223,303,23,103,223,263,263,223,23,63};
int holeY[15]={23,23,63,103,143,223,183,223,263,383,463,303,103,143,343};

int wallX0[21]={240,80,240,280,240,120,280,
  0,120,80,160,200,240,0,
  200,280,80,200,80,240,0};
int wallY0[21]={40,0,40,80,120,160,160,
  200,160,240,200,200,280,360,
  360,360,240,440,320,280,80};
int wallX1[21]={280,86,246,320,280,240,320,
  126,126,160,166,206,320,86,
  280,286,86,206,86,246,40};
int wallY1[21]={46,160,240,86,126,166,166,
  206,200,246,480,360,286,366,
  366,400,280,480,360,320,86};

@implementation leveldesign
@end

Einen Kommentar schreiben

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