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