game kit - iphone

49
iPhone to iPhone Peer to Peer networking with Game Kit Tuesday, October 13, 2009

Upload: bdudney

Post on 08-May-2015

23.325 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Game Kit - iPhone

iPhone to iPhonePeer to Peer networking with Game Kit

Tuesday, October 13, 2009

Page 2: Game Kit - iPhone

Where We Are Headed

Tuesday, October 13, 2009

Page 3: Game Kit - iPhone

One becomes the ‘client’listens for new disks, when found

creates a new one and adds it locally

The ‘Game’One becomes the ‘server’

and creates new disksadds them locally to the view

and packages them up and sendsthem to the client

Tuesday, October 13, 2009

Page 4: Game Kit - iPhone

The ‘Game’User taps on the disks and they

spin in 3D and disappearthe game sends what was

hit to the other peer so bothknow what has been hit

Tuesday, October 13, 2009

Page 5: Game Kit - iPhone

How to get there

• Connect Peers

• Run Game Loop

• Process Events

Tuesday, October 13, 2009

Page 6: Game Kit - iPhone

Application Startup

• Start looking for peers

Connect Peers

Tuesday, October 13, 2009

Page 7: Game Kit - iPhone

Application Startup

• Peer found and selected

Connect Peers

Tuesday, October 13, 2009

Page 8: Game Kit - iPhone

Application Startup

• Shall we play a game?

Connect Peers

Tuesday, October 13, 2009

Page 9: Game Kit - iPhone

Peer Picker Process

Connect Peers

Client A Client B

Anyone There? (A, B)

I’m Here (A, B)

Display A (B)

Display B (A)

Choose B (A)

Confirm A (B)

Conn passed to App (A, B)

Send/Receive (A,B)

Tuesday, October 13, 2009

Page 10: Game Kit - iPhone

Connect

Connect Peers

Server Modewait for connection

requests

Client Modelook for servers

Tuesday, October 13, 2009

Page 11: Game Kit - iPhone

Connect

Connect Peers

Peer Mode

look for serverswait for conn reqs

Tuesday, October 13, 2009

Page 12: Game Kit - iPhone

Peer Picker Controller

- (void)startPeerPicker {!GKPeerPickerController *picker = [[GKPeerPickerController alloc] init];!picker.delegate = self;![picker show];}

Connect Peers

Tuesday, October 13, 2009

Page 13: Game Kit - iPhone

- (void)startPeerPicker {!GKPeerPickerController *picker = [[GKPeerPickerController alloc] init];!picker.delegate = self;![picker show];}

Peer Picker Controller

Connect Peers

Tuesday, October 13, 2009

Page 14: Game Kit - iPhone

Connect

Connect Peers

Peer Mode

look for serverswait for conn reqs

Tuesday, October 13, 2009

Page 15: Game Kit - iPhone

Connect

Connect Peers

Peer Mode

look for serverswait for conn reqs

Peer Picker

Bill’s iPod

Bill’s 2G iPod

Bill’s iPod

Bill’s 2G iPod

Bill’s 1G iPod

Tuesday, October 13, 2009

Page 16: Game Kit - iPhone

Connect

Connect Peers

Peer Mode

look for serverswait for conn reqs

Peer Picker

Bill’s iPod

Bill’s 2G iPod

Bill’s iPod

Bill’s 2G iPod

Bill’s 1G iPod

Tap

Tuesday, October 13, 2009

Page 17: Game Kit - iPhone

Connect Peers

Tuesday, October 13, 2009

Page 18: Game Kit - iPhone

Connect

Connect Peers

Peer Mode

look for serverswait for conn reqs

Bill’s 3G iPhone Bill’s 2G iPod

Peer Mode

look for serverswait for conn reqs

connected

Tuesday, October 13, 2009

Page 19: Game Kit - iPhone

Session

- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type { return [[[GKSession alloc] initWithSessionID:@"_net.dudney.examples_" displayName:nil sessionMode:GKSessionModePeer] autorelease];}

Connect Peers

Tuesday, October 13, 2009

Page 20: Game Kit - iPhone

Make the Connection- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerId toSession:(GKSession *)session { if([peerId hash] > [session.peerID hash]) { _status = kServerGameStartedClientStatus; } else { _status = kServerGameStartedServerStatus; } self.peerId = peerId; self.gameSession = session; self.gameSession.delegate = self; [self.gameSession setDataReceiveHandler:self withContext:NULL];

[picker dismiss]; picker.delegate = nil; [picker autorelease];}

Connect Peers

Tuesday, October 13, 2009

Page 21: Game Kit - iPhone

Make the Connection- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerId toSession:(GKSession *)session { if([peerId hash] > [session.peerID hash]) { _status = kServerGameStartedClientStatus; } else { _status = kServerGameStartedServerStatus; } self.peerId = peerId; self.gameSession = session; self.gameSession.delegate = self; [self.gameSession setDataReceiveHandler:self withContext:NULL];

[picker dismiss]; picker.delegate = nil; [picker autorelease];}

Connect Peers

Tuesday, October 13, 2009

Page 22: Game Kit - iPhone

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { if(_status != kServerPickerShownStatus) { if(GKPeerStateDisconnected == state) { // got disconnected from the other peer NSString *message = [NSString stringWithFormat:@"Could not reconnect with %@.", [session displayNameForPeer:peerID]]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Lost Connection" message:message delegate:self cancelButtonTitle:@"End Game" otherButtonTitles:nil]; [alert show]; [alert release]; } }}

Loose Connection? Connect Peers/G

ame Loop

Tuesday, October 13, 2009

Page 23: Game Kit - iPhone

Session Connect Peers/G

ame Loop

- (void)alertView:(UIAlertView *)alertViewclickedButtonAtIndex:(NSInteger)buttonIndex { // index zero is the 'End Game' button, the only one!if(buttonIndex == 0) {!! _status = kServerNotStartedStatus;!}}

Tuesday, October 13, 2009

Page 24: Game Kit - iPhone

Game Loop

Run G

ame Loop

- (void)start { [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];}

- (id) init { self = [super init]; if (self != nil) {... self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)]; self.link.frameInterval = 2;... } return self;}

Tuesday, October 13, 2009

Page 25: Game Kit - iPhone

Game Loop

• Start the peer picker

• Send new disk messages

Run G

ame Loop

Tuesday, October 13, 2009

Page 26: Game Kit - iPhone

Start the Picker

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 27: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 28: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 29: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 30: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 31: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } }}

Tuesday, October 13, 2009

Page 32: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 33: Game Kit - iPhone

Send New Disks

Run G

ame Loop

- (void)gameLoop { _loopId++; if(kServerNotStartedStatus == _status) { _status = kServerPickerShownStatus; [self startPeerPicker]; } else if(kServerGameStartedServerStatus == _status) { if(0 == (_loopId % _diskFrequency)) { srandom(_loopId); long x = random() % 300 + 10; long y = random() % 460 + 10; CGPoint location = CGPointMake((CGFloat)x, (CGFloat)y); long colorIndex = random() % _colors.count; NSMutableData *data = [NSMutableData dataWithBytes:&location length:sizeof(location)]; [data appendBytes:&colorIndex length:sizeof(colorIndex)]; [self sendMessageTypeID:kServerNewDiskMessageType data:data]; UIColor *color = [_colors objectAtIndex:colorIndex]; [self.delegate diskAtPoint:location withColor:color]; } } }

Tuesday, October 13, 2009

Page 34: Game Kit - iPhone

Send Data

- (void)sendMessageTypeID:(ServerPacketTypeId)packetTypeId data:(NSData *)data { NSMutableData *sentData = [NSMutableData data]; [sentData appendBytes:&packetTypeId length:sizeof(packetTypeId)]; [sentData appendData:data]; [self.gameSession sendData:sentData toPeers:[NSArray arrayWithObject:self.peerId] withDataMode:GKSendDataUnreliable error:nil];}

Run G

ame Loop

Tuesday, October 13, 2009

Page 35: Game Kit - iPhone

Receive Data- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context { ServerPacketTypeId typeId; [data getBytes:&typeId length:sizeof(typeId)]; if(kServerNewDiskMessageType == typeId) { CGPoint point; NSRange range; range.location = sizeof(typeId); range.length = sizeof(point); [data getBytes:&point range:range]; NSUInteger colorIndex = 0; range.location = range.location + range.length; range.length = sizeof(colorIndex); [data getBytes:&colorIndex range:range]; [self.delegate diskAtPoint:point withColor:[_colors objectAtIndex:colorIndex]]; } else if(kServerSmashMessageType == typeId) {... }}

Run G

ame Loop

Tuesday, October 13, 2009

Page 36: Game Kit - iPhone

Messages

Client A Client B{color, location}

new disk

Tuesday, October 13, 2009

Page 37: Game Kit - iPhone

Messages

Client A Client B{color, location}

new disk new disk

Tuesday, October 13, 2009

Page 38: Game Kit - iPhone

New Disk Layer- (void)displayDiskAt:(CGPoint)point ofColor:(UIColor *)color { DiskLayer *layer = [DiskLayer layerWithColor:color]; layer.position = point; [self.layer addSublayer:layer]; [self performSelector:@selector(disapearLayer:) withObject:layer afterDelay:0.1f];}

- (void)disapearLayer:(CALayer *)layer { layer.opacity = 0.0f;}

Tuesday, October 13, 2009

Page 39: Game Kit - iPhone

New Disk Layer- (id) initWithColor:(UIColor *)color { self = [super init]; if (self != nil) { CGRect frame = CGRectMake(0.0f, 0.0f, 40.0f, 40.0f); self.frame = frame; self.diskLayer = [CAShapeLayer layer]; self.diskLayer.frame = frame; CGPathRef path = [self newCirclePath]; self.diskLayer.path = path; self.diskLayer.fillColor = [color CGColor]; self.diskLayer.strokeColor = [color CGColor]; CFRelease(path); CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.duration = 4.9f; animation.delegate = self; self.actions = [NSDictionary dictionaryWithObject:animation forKey:@"opacity"]; [self addSublayer:self.diskLayer]; _smashed = NO; } return self;}

Tuesday, October 13, 2009

Page 40: Game Kit - iPhone

Smash A Disk

Client A

tap

Tuesday, October 13, 2009

Page 41: Game Kit - iPhone

Smash A Disk

Client A

tap

{smash location} Client B

Tuesday, October 13, 2009

Page 42: Game Kit - iPhone

Process Events- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint point = [[touches anyObject] locationInView:self]; CGPoint location = [self.layer convertPoint:point toLayer:self.layer.superlayer]; CALayer *layer = [self.layer hitTest:location]; if(layer != self.layer) { [self.delegate diskSmashedAt:location]; [(DiskLayer *)layer smash]; }}

Tuesday, October 13, 2009

Page 43: Game Kit - iPhone

Smashing Disks

- (void)diskSmashedAt:(CGPoint)point { [self.server sendSmashAtPoint:point];}

Tuesday, October 13, 2009

Page 44: Game Kit - iPhone

Sending Smashes

- (void)sendSmashAtPoint:(CGPoint)point { NSData *data = [NSData dataWithBytes:&point length:sizeof(point)]; [self sendMessageTypeID:kServerSmashMessageType data:data];}

Tuesday, October 13, 2009

Page 45: Game Kit - iPhone

Receive Smash- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context {... } else if(kServerSmashMessageType == typeId) { CGPoint point; NSRange range; range.location = sizeof(typeId); range.length = sizeof(point); [data getBytes:&point range:range]; [self.delegate remoteDiskSmashedAtPoint:point]; }}

Tuesday, October 13, 2009

Page 46: Game Kit - iPhone

Remote Smash Forward

- (void)remoteDiskSmashedAtPoint:(CGPoint)point { DiskSmashView *smashView = (DiskSmashView *)self.view; [smashView remoteSmash:point];}

Tuesday, October 13, 2009

Page 47: Game Kit - iPhone

Remote Smash

- (void)remoteSmash:(CGPoint)point { CALayer *layer = [self.layer hitTest:point]; if(layer != self.layer) { [(DiskLayer *)layer smash]; }}

Tuesday, October 13, 2009

Page 48: Game Kit - iPhone

Conclusion

• Getting Connected is easy!

• Sending Data is easy

• Designing a good game, not so much.

Tuesday, October 13, 2009