SlideShare ist ein Scribd-Unternehmen logo
1 von 49
Downloaden Sie, um offline zu lesen
iPhone to iPhone
                            Peer to Peer networking with Game Kit




Tuesday, October 13, 2009
Where We Are Headed




Tuesday, October 13, 2009
The ‘Game’
                                 One becomes the ‘server’
                                   and creates new disks
                                adds them locally to the view
                              and packages them up and sends
                                     them to the client


                                   One becomes the ‘client’
                              listens for new disks, when found
                            creates a new one and adds it locally




Tuesday, October 13, 2009
The ‘Game’
                             User taps on the disks and they
                                 spin in 3D and disappear
                                the game sends what was
                              hit to the other peer so both
                                 know what has been hit




Tuesday, October 13, 2009
How to get there

                    • Connect Peers
                    • Run Game Loop
                    • Process Events


Tuesday, October 13, 2009
Application Startup




                                             Connect Peers
            •      Start looking for peers




Tuesday, October 13, 2009
Application Startup




                                             Connect Peers
            •      Peer found and selected




Tuesday, October 13, 2009
Application Startup




                                           Connect Peers
            •      Shall we play a game?




Tuesday, October 13, 2009
Peer Picker Process
                                          Anyone There? (A, B)




                                                                               Connect Peers
                                             I’m Here (A, B)
                                              Display A (B)
                                              Display B (A)

                             Client A                               Client B

                                              Choose B (A)
                                             Confirm A (B)
                                        Conn passed to App (A, B)
                                           Send/Receive (A,B)




Tuesday, October 13, 2009
Connect




                                                   Connect Peers
                              Server Mode
                             wait for connection
                                   requests




                               Client Mode
                              look for servers




Tuesday, October 13, 2009
Connect




                                                  Connect Peers
                               Peer Mode
                             wait for conn reqs
                              look for servers




Tuesday, October 13, 2009
Peer Picker Controller




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




Tuesday, October 13, 2009
Peer Picker
                            Controller




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




Tuesday, October 13, 2009
Connect




                                           Connect Peers
                Peer Mode
            wait for conn reqs
             look for servers




Tuesday, October 13, 2009
Connect




                                                            Connect Peers
                Peer Mode                  Peer Picker
            wait for conn reqs
             look for servers


                                             Bill’s iPod
                                           Bill’s 2G iPod
                                           Bill’s 1G iPod



Tuesday, October 13, 2009
Connect




                                                            Connect Peers
                Peer Mode                  Peer Picker
            wait for conn reqs
             look for servers


                                             Bill’s iPod
                                   Tap     Bill’s 2G iPod
                                           Bill’s 1G iPod



Tuesday, October 13, 2009
Connect Peers
Tuesday, October 13, 2009
Connect
                            Bill’s 3G iPhone                     Bill’s 2G iPod




                                                                                    Connect Peers
                              Peer Mode            connected     Peer Mode
                            wait for conn reqs                 wait for conn reqs
                             look for servers                   look for servers




Tuesday, October 13, 2009
Session




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




Tuesday, October 13, 2009
Make the Connection
- (void)peerPickerController:(GKPeerPickerController *)picker
              didConnectPeer:(NSString *)peerId




                                                                    Connect Peers
                   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];
}




Tuesday, October 13, 2009
Make the Connection
- (void)peerPickerController:(GKPeerPickerController *)picker
              didConnectPeer:(NSString *)peerId




                                                                    Connect Peers
                   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];
}




Tuesday, October 13, 2009
Loose Connection?




                                                                                          Connect Peers/Game Loop
 - (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];
      }
    }
 }




Tuesday, October 13, 2009
Session




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




Tuesday, October 13, 2009
Game Loop
- (id) init {




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


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




Tuesday, October 13, 2009
Game Loop




                                               Run Game Loop
                    • Start the peer picker
                    • Send new disk messages


Tuesday, October 13, 2009
Start the Picker
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send New Disks
  - (void)gameLoop {
    _loopId++;




                                                                                Run Game Loop
    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
Send Data




                                                                                   Run Game Loop
- (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];
}




Tuesday, October 13, 2009
Receive Data
- (void) receiveData:(NSData *)data
            fromPeer:(NSString *)peer




                                                                      Run Game Loop
           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) {
...
  }
}




Tuesday, October 13, 2009
Messages
                                new disk




                            Client A        {color, location}   Client B




Tuesday, October 13, 2009
Messages
                                new disk                          new disk




                            Client A        {color, location}   Client B




Tuesday, October 13, 2009
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
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
Smash A Disk
                                       tap




                            Client A




Tuesday, October 13, 2009
Smash A Disk
                                       tap




                            Client A         {smash location}   Client B




Tuesday, October 13, 2009
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
Smashing Disks

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




Tuesday, October 13, 2009
Sending Smashes

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




Tuesday, October 13, 2009
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
Remote Smash Forward

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




Tuesday, October 13, 2009
Remote Smash

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




Tuesday, October 13, 2009
Conclusion

                    • Getting Connected is easy!
                    • Sending Data is easy
                    • Designing a good game, not so much.


Tuesday, October 13, 2009
Thanks!
                                Pragmatic iPhone Studio




                            PragProg.com discount code
                               voices_bill_dudney_10


Tuesday, October 13, 2009

Weitere ähnliche Inhalte

Andere mochten auch

#SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences
#SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences #SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences
#SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences Search Engine Journal
 
Convert Excel Spreadsheet into Mobile iPhone Android App
Convert Excel Spreadsheet into Mobile iPhone Android AppConvert Excel Spreadsheet into Mobile iPhone Android App
Convert Excel Spreadsheet into Mobile iPhone Android AppHarendraSingh Rajput
 
Online bioinformatics forums: why do we keep asking the same questions?
Online bioinformatics forums: why do we keep asking the same questions?Online bioinformatics forums: why do we keep asking the same questions?
Online bioinformatics forums: why do we keep asking the same questions?Neil Saunders
 
Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...
Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...
Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...Search Engine Journal
 
How to Combine text from two or more cells in Excel
How to Combine text from two or more cells in ExcelHow to Combine text from two or more cells in Excel
How to Combine text from two or more cells in ExcelNick Weisenberger
 
Predikin and PredikinDB: tools to predict protein kinase peptide specificity
Predikin and PredikinDB:  tools to predict protein kinase peptide specificityPredikin and PredikinDB:  tools to predict protein kinase peptide specificity
Predikin and PredikinDB: tools to predict protein kinase peptide specificityNeil Saunders
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1Dave Cross
 
Link Building Metrics: Managing Projects and SEOs with Page One Power
Link Building Metrics: Managing Projects and SEOs with Page One PowerLink Building Metrics: Managing Projects and SEOs with Page One Power
Link Building Metrics: Managing Projects and SEOs with Page One PowerSearch Engine Journal
 
Winning with Authority - 15 Experts on Integrated Online Marketing
Winning with Authority - 15 Experts on Integrated Online MarketingWinning with Authority - 15 Experts on Integrated Online Marketing
Winning with Authority - 15 Experts on Integrated Online MarketingTopRank Marketing Agency
 
How to Get More Engagement on Instagram with Kelsey Jones
How to Get More Engagement on Instagram with Kelsey JonesHow to Get More Engagement on Instagram with Kelsey Jones
How to Get More Engagement on Instagram with Kelsey JonesSearch Engine Journal
 
Transforming Customer Experience: From Moments to Journeys
Transforming Customer Experience: From Moments to JourneysTransforming Customer Experience: From Moments to Journeys
Transforming Customer Experience: From Moments to JourneysMcKinsey on Marketing & Sales
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheLeslie Samuel
 

Andere mochten auch (12)

#SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences
#SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences #SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences
#SEJThinkTank: Harnessing the Networks of Your Podcast Guests & Audiences
 
Convert Excel Spreadsheet into Mobile iPhone Android App
Convert Excel Spreadsheet into Mobile iPhone Android AppConvert Excel Spreadsheet into Mobile iPhone Android App
Convert Excel Spreadsheet into Mobile iPhone Android App
 
Online bioinformatics forums: why do we keep asking the same questions?
Online bioinformatics forums: why do we keep asking the same questions?Online bioinformatics forums: why do we keep asking the same questions?
Online bioinformatics forums: why do we keep asking the same questions?
 
Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...
Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...
Steal from the Startups: Entrepreneur Style Growth Tactics for Big Brands by ...
 
How to Combine text from two or more cells in Excel
How to Combine text from two or more cells in ExcelHow to Combine text from two or more cells in Excel
How to Combine text from two or more cells in Excel
 
Predikin and PredikinDB: tools to predict protein kinase peptide specificity
Predikin and PredikinDB:  tools to predict protein kinase peptide specificityPredikin and PredikinDB:  tools to predict protein kinase peptide specificity
Predikin and PredikinDB: tools to predict protein kinase peptide specificity
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Link Building Metrics: Managing Projects and SEOs with Page One Power
Link Building Metrics: Managing Projects and SEOs with Page One PowerLink Building Metrics: Managing Projects and SEOs with Page One Power
Link Building Metrics: Managing Projects and SEOs with Page One Power
 
Winning with Authority - 15 Experts on Integrated Online Marketing
Winning with Authority - 15 Experts on Integrated Online MarketingWinning with Authority - 15 Experts on Integrated Online Marketing
Winning with Authority - 15 Experts on Integrated Online Marketing
 
How to Get More Engagement on Instagram with Kelsey Jones
How to Get More Engagement on Instagram with Kelsey JonesHow to Get More Engagement on Instagram with Kelsey Jones
How to Get More Engagement on Instagram with Kelsey Jones
 
Transforming Customer Experience: From Moments to Journeys
Transforming Customer Experience: From Moments to JourneysTransforming Customer Experience: From Moments to Journeys
Transforming Customer Experience: From Moments to Journeys
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your Niche
 

Kürzlich hochgeladen

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 

Kürzlich hochgeladen (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 

Game Kit - iPhone

  • 1. iPhone to iPhone Peer to Peer networking with Game Kit Tuesday, October 13, 2009
  • 2. Where We Are Headed Tuesday, October 13, 2009
  • 3. The ‘Game’ One becomes the ‘server’ and creates new disks adds them locally to the view and packages them up and sends them to the client One becomes the ‘client’ listens for new disks, when found creates a new one and adds it locally Tuesday, October 13, 2009
  • 4. The ‘Game’ User taps on the disks and they spin in 3D and disappear the game sends what was hit to the other peer so both know what has been hit Tuesday, October 13, 2009
  • 5. How to get there • Connect Peers • Run Game Loop • Process Events Tuesday, October 13, 2009
  • 6. Application Startup Connect Peers • Start looking for peers Tuesday, October 13, 2009
  • 7. Application Startup Connect Peers • Peer found and selected Tuesday, October 13, 2009
  • 8. Application Startup Connect Peers • Shall we play a game? Tuesday, October 13, 2009
  • 9. Peer Picker Process Anyone There? (A, B) Connect Peers I’m Here (A, B) Display A (B) Display B (A) Client A Client B Choose B (A) Confirm A (B) Conn passed to App (A, B) Send/Receive (A,B) Tuesday, October 13, 2009
  • 10. Connect Connect Peers Server Mode wait for connection requests Client Mode look for servers Tuesday, October 13, 2009
  • 11. Connect Connect Peers Peer Mode wait for conn reqs look for servers Tuesday, October 13, 2009
  • 12. Peer Picker Controller Connect Peers - (void)startPeerPicker { !GKPeerPickerController *picker = [[GKPeerPickerController alloc] init]; !picker.delegate = self; ![picker show]; } Tuesday, October 13, 2009
  • 13. Peer Picker Controller Connect Peers - (void)startPeerPicker { !GKPeerPickerController *picker = [[GKPeerPickerController alloc] init]; !picker.delegate = self; ![picker show]; } Tuesday, October 13, 2009
  • 14. Connect Connect Peers Peer Mode wait for conn reqs look for servers Tuesday, October 13, 2009
  • 15. Connect Connect Peers Peer Mode Peer Picker wait for conn reqs look for servers Bill’s iPod Bill’s 2G iPod Bill’s 1G iPod Tuesday, October 13, 2009
  • 16. Connect Connect Peers Peer Mode Peer Picker wait for conn reqs look for servers Bill’s iPod Tap Bill’s 2G iPod Bill’s 1G iPod Tuesday, October 13, 2009
  • 18. Connect Bill’s 3G iPhone Bill’s 2G iPod Connect Peers Peer Mode connected Peer Mode wait for conn reqs wait for conn reqs look for servers look for servers Tuesday, October 13, 2009
  • 19. Session Connect Peers - (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type { return [[[GKSession alloc] initWithSessionID:@"_net.dudney.examples_" displayName:nil sessionMode:GKSessionModePeer] autorelease]; } Tuesday, October 13, 2009
  • 20. Make the Connection - (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerId Connect Peers 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]; } Tuesday, October 13, 2009
  • 21. Make the Connection - (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerId Connect Peers 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]; } Tuesday, October 13, 2009
  • 22. Loose Connection? Connect Peers/Game Loop - (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]; } } } Tuesday, October 13, 2009
  • 23. Session Connect Peers/Game Loop - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { // index zero is the 'End Game' button, the only one !if(buttonIndex == 0) { !! _status = kServerNotStartedStatus; !} } Tuesday, October 13, 2009
  • 24. Game Loop - (id) init { Run Game Loop self = [super init]; if (self != nil) { ... self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)]; self.link.frameInterval = 2; ... } return self; } - (void)start { [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; } Tuesday, October 13, 2009
  • 25. Game Loop Run Game Loop • Start the peer picker • Send new disk messages Tuesday, October 13, 2009
  • 26. Start the Picker - (void)gameLoop { _loopId++; Run Game Loop 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
  • 27. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 28. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 29. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 30. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 31. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 32. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 33. Send New Disks - (void)gameLoop { _loopId++; Run Game Loop 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
  • 34. Send Data Run Game Loop - (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]; } Tuesday, October 13, 2009
  • 35. Receive Data - (void) receiveData:(NSData *)data fromPeer:(NSString *)peer Run Game Loop 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) { ... } } Tuesday, October 13, 2009
  • 36. Messages new disk Client A {color, location} Client B Tuesday, October 13, 2009
  • 37. Messages new disk new disk Client A {color, location} Client B Tuesday, October 13, 2009
  • 38. 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
  • 39. 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
  • 40. Smash A Disk tap Client A Tuesday, October 13, 2009
  • 41. Smash A Disk tap Client A {smash location} Client B Tuesday, October 13, 2009
  • 42. 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
  • 43. Smashing Disks - (void)diskSmashedAt:(CGPoint)point { [self.server sendSmashAtPoint:point]; } Tuesday, October 13, 2009
  • 44. Sending Smashes - (void)sendSmashAtPoint:(CGPoint)point { NSData *data = [NSData dataWithBytes:&point length:sizeof(point)]; [self sendMessageTypeID:kServerSmashMessageType data:data]; } Tuesday, October 13, 2009
  • 45. 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
  • 46. Remote Smash Forward - (void)remoteDiskSmashedAtPoint:(CGPoint)point { DiskSmashView *smashView = (DiskSmashView *)self.view; [smashView remoteSmash:point]; } Tuesday, October 13, 2009
  • 47. Remote Smash - (void)remoteSmash:(CGPoint)point { CALayer *layer = [self.layer hitTest:point]; if(layer != self.layer) { [(DiskLayer *)layer smash]; } } Tuesday, October 13, 2009
  • 48. Conclusion • Getting Connected is easy! • Sending Data is easy • Designing a good game, not so much. Tuesday, October 13, 2009
  • 49. Thanks! Pragmatic iPhone Studio PragProg.com discount code voices_bill_dudney_10 Tuesday, October 13, 2009