Exploration du cadre de connectivité Multipeer Game Logic

Dans ce didacticiel, je vais vous montrer comment créer un jeu simple et multijoueur à l'aide du cadre de connectivité Multipeer introduit dans iOS 7. Dans le premier volet de cette série, nous avons jeté les bases du jeu. Dans cet article, nous allons implémenter la logique du jeu..

1. Implémentation de la logique de jeu

À ce stade, l'application est en mesure de découvrir d'autres lecteurs à proximité, d'établir une connexion et d'afficher les homologues connectés dans la vue texte du contrôleur de vue des options. Cependant, la mise en œuvre de la OptionsViewController la classe n'est pas encore terminée.

Étape 1

Le contrôleur de vue des options contient un champ de texte en haut de sa vue. Nous utiliserons ce champ de texte pour permettre à l'utilisateur de modifier le nom d'affichage du périphérique. Pour le moment, le nom de l'appareil est utilisé comme nom d'affichage de l'homologue. Voyons comment personnaliser ce nom d'affichage.

Commençons par adopter le UITextFieldDelegate protocole dans le OptionsViewController classe. Ouvrir OptionsViewController.h et modifier l'interface de la classe comme indiqué ci-dessous.

@interface OptionsViewController: UIViewController 

Dans le fichier d’implémentation de la classe, définissez le contrôleur de vue comme délégué du champ de texte dans viewDidLoad méthode.

- (void) viewDidLoad //… // [self.txtPlayerName setDelegate: self]; 

Nous n'avons besoin que de mettre en œuvre une méthode du UITextFieldDelegate protocole, textFieldShouldReturn:.

- (BOOL) textFieldShouldReturn: (UITextField *) textField [self.txtPlayerName resignFirstResponder]; if (self.appDelegate.mpcHandler.peerID! = nil) [self.appDelegate.mpcHandler.session disconnect]]; self.appDelegate.mpcHandler.peerID = nil; self.appDelegate.mpcHandler.session = nil;  [self.appDelegate.mpcHandler setupPeerWithDisplayName: self.txtPlayerName.text]; [self.appDelegate.mpcHandler setupSession]; [self.appDelegate.mpcHandler advertiseSelf: self.swVisible.isOn]; retourner OUI; 

Nous appelons d'abord resignFirstResponder sur le champ de texte pour fermer le clavier. Ensuite, si le peerID et session les objets ne sont pas néant, nous réinitialisons à la fois en les mettant à néant. Nous appelons aussi déconnecter sur le session objet pour déconnecter le périphérique de tous les pairs auxquels il peut être connecté. Nous initialisons ensuite le peerID objet en utilisant le nom saisi par l'utilisateur dans le champ de texte et configurez le session objet. Essayez ceci en exécutant l'application et en changeant le nom d'affichage. Si tout se passe bien, le nom personnalisé sera utilisé à la place du nom du périphérique..

Il y a une mise en garde: lorsque vous utilisez un nom d'affichage personnalisé, le périphérique se déconnecte de toute session active à laquelle il fait actuellement partie. Cela signifie également que tout jeu en cours est terminé. Bien que nous n'ayons ajouté aucune mesure pour empêcher cela, veillez à ne pas autoriser les utilisateurs à modifier le nom d'affichage lorsque le périphérique fait partie d'une session active..

Étape 2

La prochaine étape consiste à mettre en œuvre le toggleVisibility: action que nous avons déclarée plus tôt. Sa mise en œuvre ne pourrait être plus simple. Chaque fois que le commutateur est basculé, nous invoquons le advertiseSelf: méthode du mpcHandler objet et transmettez-lui l'état du commutateur. Lancer l'application pour l'essayer.

- (IBAction) toggleVisibility: (id) expéditeur [self.appDelegate.mpcHandler advertiseSelf: self.swVisible.isOn]; 

Étape 3

Nous devons également mettre en œuvre le déconnecter: action. Déconnecter un appareil d'une session est tout aussi simple. Jetez un coup d’œil à la mise en œuvre de déconnecter: au dessous de.

- (IBAction) disconnect: (id) expéditeur [self.appDelegate.mpcHandler.session disconnect]; 

Cela le termine pour le OptionsViewController classe. L'application dans son état actuel est capable d'établir une connexion, de mettre à jour le nom d'affichage du périphérique et de se déconnecter d'une session active. Il est temps de se concentrer sur le jeu lui-même en explorant les moyens d'échanger des données entre pairs..

2. Créer un nouveau jeu

Étape 1

Passons maintenant à la mise en œuvre de la ViewController classe. Commencez par déclarer une propriété pour le délégué d’application, puis définissez-la dans le viewDidLoad méthode. Cela implique trois étapes.

  1. Ouvrir ViewController.m et ajouter une déclaration d'importation pour le AppDéléguer classe.
     #import "AppDelegate.h"
  2. Déclarer une propriété pour le AppDéléguer objet.
     @interface ViewController () @property (nonatomic, strong) AppDelegate * appDelegate; @fin
  3. Dans viewDidLoad, stocker une référence au délégué de l'application dans la appDéléguer propriété.
     - (void) viewDidLoad [super viewDidLoad]; self.appDelegate = (AppDelegate *) [UIApplication sharedApplication] .delegate; 

Étape 2

Dans l'étape suivante, nous déclarons trois propriétés que nous utiliserons pour suivre l'état du jeu..

@interface ViewController () @property (nonatomic, strong) AppDelegate * appDelegate; @property (nonatomic) int secretNumber; @property (nonatomic) BOOL hasCreatedGame; @property (nonatomic) BOOL isGameRunning; @fin
  • le numéro secret la propriété stockera le numéro secret choisi par le joueur hébergeant la partie.
  • le hasCreatedGame drapeau indique si le joueur actuel est celui qui a démarré la partie en cours.
  • le isGameRunning drapeau indique si un jeu est en cours.

Étape 3

Pour qu'une nouvelle partie puisse commencer, un numéro secret doit être défini par le joueur qui commence la partie. L'objectif principal de ce didacticiel est la structure de connectivité Multipeer. Nous ne nous intéresserons donc pas à un mécanisme complexe permettant de définir un numéro secret. Et quoi de plus facile qu'une vue d'alerte demandant au joueur un numéro secret?

Une nouvelle partie commence quand un joueur tape le Début bouton dans la barre de navigation, ce qui signifie que nous devons implémenter le démarrer jeu: action. Comme vous pouvez le voir dans son implémentation ci-dessous, nous vérifions d'abord si un jeu est déjà en cours avant de présenter la vue alerte. Nous ne voulons pas commencer un nouveau jeu alors qu'un autre jeu est en cours.

- (IBAction) startGame: (id) expéditeur if (! Self.isGameRunning) UIAlertView * newGameAlert = [[UIAlertView alloc] initWithTitle: @ message "MPCDemo": @ "Entrez un nombre compris entre 1 et 100:" delegate: self cancelButtonTitle: @ "Annuler" otherButtonTitles: @ "Start Game", nil]; newGameAlert.alertViewStyle = UIAlertViewStylePlainTextInput; [[newGameAlert textFieldAtIndex: 0] setKeyboardType: UIKeyboardTypeNumberPad]; [newGameAlert show]; 

En mettant le alertViewStyle à UIAlertViewStylePlainTextInput, un champ de texte est ajouté à la vue d'alerte.


Étape 4

Une fois que le joueur a entré un numéro secret, il y a trois choses à prendre en compte.

  1. Nous devons gérer le robinet du joueur de la Démarrer jeu bouton.
  2. Nous devons également vérifier si le nombre choisi se situe entre 1 et 100.
  3. Les autres joueurs du jeu doivent être informés que le jeu a commencé et qu'un numéro secret a été défini..

Commençons par la première tâche en mettant en œuvre le alertView: clickedButtonAtIndex: méthode déléguée du UIAlertViewDelegate protocole. Ouvrez le fichier d’en-tête du contrôleur de vue et adoptez le UIAlertViewDelegate protocole comme indiqué ci-dessous.

@interface ViewController: UIViewController 

Ensuite, implémentez le alertView: clickedButtonAtIndex: méthode du UIAlertViewDelegate protocole. Pour nous assurer que la vue d’alerte contient un champ de texte, nous vérifions d’abord son contenu. alertViewStyle propriété pour voir si elle est égale à UIAlertViewStylePlainTextInput. Nous nous assurons également que le Démarrer jeu bouton a été tapoté en vérifiant que le buttonIndex propriété du bouton taraudé est égale à 1.

- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput && buttonIndex == 1) 

Nous extrayons ensuite l'entrée du champ de texte et le convertissons en un entier, que nous stockons dans le contrôleur de vue. numéro secret propriété.

- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput && buttonIndex == 1) UITextField * textField = [alertView texteField self.secretNumber = [textField.text intValue]; 

L'étape suivante consiste à vérifier si le nombre choisi est compris entre 1 et 100, ce qui est très facile à faire. Si le nombre ne se situe pas dans la plage requise, nous affichons une vue d'alerte pour le lecteur. Si le numéro secret réussit notre test, nous créons un message pour les autres joueurs et l'envoyons aux pairs connectés à l'aide du cadre de connexion Multipeer. Comment cela marche-t-il?

- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput && buttonIndex == 1) UITextField * textField = [alertView texteField self.secretNumber = [textField.text intValue]; // Assurez-vous que le nombre donné est compris entre 1 et 100. if (self.secretNumber> = 1 && self.secretNumber <= 100)  // Create a message to tell other players that a new game has been created, // convert it to a NSData object and send it. NSString *messageToSend = @"New Game"; NSData *messageAsData = [messageToSend dataUsingEncoding:NSUTF8StringEncoding]; NSError *error; [self.appDelegate.mpcHandler.session sendData:messageAsData toPeers:self.appDelegate.mpcHandler.session.connectedPeers withMode:MCSessionSendDataReliable error:&error]; // If any error occurs, just log it. // Otherwise set the following couple of flags to YES, indicating that the current player is the creator // of the game and a game is in progress. if (error != nil)  NSLog(@"%@", [error localizedDescription]);  else self.hasCreatedGame = YES; self.isGameRunning = YES; [self.tvHistory setText:@""];   else UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"MPCDemo" message:@"Please enter a valid number." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Okay", nil]; [alert show];   

Nous créons un NSString par exemple, définissez sa valeur sur Nouveau jeu, et encoder la chaîne en un NSData objet. Rappelez-vous qu'un NSString Cette instance ne peut pas être envoyée à l’aide de la structure Multipeer Connectivity. Il doit d'abord être converti en un NSData objet.

La ligne de code la plus intéressante est celle présentée ci-dessous. Dans cette seule ligne, nous envoyons le NSData objecter à tous les pairs connectés. Nous passons l'adresse d'un NSError pointeur pour détecter les erreurs éventuelles au cours du processus.

[self.appDelegate.mpcHandler.session sendData: messageAsData toPeers: self.appDelegate.mpcHandler.session.connectedPeers withMode: erreur MCSessionSendDataReliable: & error];

Comme vous l'avez peut-être deviné, le sendData: toPeers: withMode: error: La méthode est déclarée dans la structure Multipeer Connectivity. Parce que nous voulons que chaque pair reçoive le message, nous passons self.appDelegate.mpcHandler.session.connectedPeers comme deuxième argument. Le troisième argument de la méthode, MCSessionSendDataReliable, spécifie le mode de transmission. Si vous vous souvenez de l'introduction, le framework Multipeer Connectivity peut envoyer des données de deux manières, de manière fiable ou non. Dans cet exemple, il est essentiel d’envoyer les données de manière fiable pour s’assurer que chaque joueur reçoit le message sans problème..

Si aucune erreur n'a été générée, nous définissons hasCreatedGame et isGameRunning à OUI. Nous désactivons également l'affichage du texte pour préparer l'interface utilisateur pour le nouveau jeu..

3. Mise à jour de l'interface utilisateur

Si vous testiez l'application dans son état actuel, vous remarquerez que rien n'a changé du point de vue du joueur. Les autres joueurs ne sont pas avertis quand une nouvelle partie est lancée. Nous devons encore nous occuper de quelques choses pour accomplir cela..

Cependant, nous devons d’abord mettre à jour l’interface utilisateur de l’application pour refléter l’état du jeu en cours. Actuellement, les boutons et les champs de texte sont activés même lorsqu'un nouveau jeu a commencé. Par exemple, lorsqu'un joueur commence une nouvelle partie, un joueur qui a rejoint la partie ne devrait pas pouvoir commencer une nouvelle partie. Nous allons implémenter une méthode d'assistance simple pour résoudre ce problème.

- (void) toggleSubviewsState: (BOOL) shouldEnable self.btnCancel.enabled = shouldEnable; self.txtGuess.enabled = shouldEnable; self.btnSend.enabled = shouldEnable; 

Dans toggleSubviewsState:, nous activons ou désactivons les boutons et le champ de texte en fonction de l'état du jeu. Invoquons toggleSubviewsState: dans le contrôleur de vue viewDidLoad méthode.

- (void) viewDidLoad //… // [self toggleSubviewsState: NO]; 

4. Gestion des messages

Chaque fois qu'un pair reçoit un NSData objet, le session: didReceiveData: fromPeer: La méthode déléguée du framework Multipeer Connectivity est appelée. Cela entraîne également la publication d'une notification, comme vous vous en souviendrez peut-être au début de ce didacticiel. Pour recevoir et gérer ces notifications, nous devons ajouter le contrôleur de vue en tant qu'observateur, comme indiqué ci-dessous. Chaque fois qu'une notification avec un nom de MPCDemo_DidReceiveDataNotification est affiché, le handleReceivedDataWithNotification: la méthode est invoquée.

- (void) viewDidLoad //… // [[[NSNotificationCenter defaultCenter]] addObserver: sélecteur automatique: @selector (handleReceivedDataWithNotification :) name: @ "MPCDemo_DidReceiveDataNotification" object: nil]; 

L'implémentation de handleReceivedDataWithNotification: peut sembler décourageant alors brisons-le en morceaux digestibles.

- (void) handleReceivedDataWithNotification: (NSNotification *) notification // Récupère le dictionnaire d'informations utilisateur qui a été reçu avec la notification. NSDictionary * userInfoDict = [notification userInfo]; // Convertit les données reçues en un objet NSString. NSData * receiveData = [userInfoDict objectForKey: @ "data"]; NSString * message = [[NSString alloc] initWithData: receiveData encoding: NSUTF8StringEncoding]; // Conserve le peerID de l'expéditeur et obtient son nom complet. MCPeerID * senderPeerID = [userInfoDict objectForKey: @ "peerID"]; NSString * senderDisplayName = senderPeerID.displayName; 

Nous recevons la notification informations utilisateur dictionnaire, extraire le NSData objet, recréer le NSString objet, et le stocker dans une variable nommée message. L’action que nous entreprenons ensuite dépend de la valeur de la message objet. Nous extrayons également le nom de l'homologue qui a envoyé le message afin de pouvoir l'utiliser pour mettre à jour l'interface utilisateur du jeu..

Si la valeur de message est égal à la Nouveau jeu, un nouveau jeu a été lancé. Nous informons ensuite l'utilisateur de cet événement, mettons à jour la valeur de isGameRunning, et mettre à jour l'interface utilisateur pour permettre au joueur de deviner. Jetez un coup d’œil à l’implémentation mise à jour de handleReceivedDataWithNotification:.

- (void) handleReceivedDataWithNotification: (NSNotification *) notification // Récupère le dictionnaire d'informations utilisateur qui a été reçu avec la notification. NSDictionary * userInfoDict = [notification userInfo]; // Convertit les données reçues en un objet NSString. NSData * receiveData = [userInfoDict objectForKey: @ "data"]; NSString * message = [[NSString alloc] initWithData: receiveData encoding: NSUTF8StringEncoding]; // Conserve le peerID de l'expéditeur et obtient son nom complet. MCPeerID * senderPeerID = [userInfoDict objectForKey: @ "peerID"]; NSString * senderDisplayName = senderPeerID.displayName; if ([message isEqualToString: @ "Nouvelle partie"]) // Si le message concerne un nouveau jeu, affichez une vue alerte indiquant que l'expéditeur du message // vient de commencer une nouvelle partie. NSString * alertMessage = [NSString stringWithFormat: @ "% @ a lancé un nouveau jeu.", SenderDisplayName]; UIAlertView * alert = [[UIAlertView alloc] initWithTitle: @ "MPCDemo" message: délégué alertMessage: nil cancelButtonTitle: nil otherButtonTitles: @ "Terminé", nil]; [émission d'alerte]; // Indiquez également qu'une partie est en cours. self.isGameRunning = YES; // Activer toutes les sous-vues. [self toggleSubviewsState: YES]; // Efface tout l'historique précédent de la vue texte. [self.tvHistory setText: @ ""]; 

Deux détails sont intéressants à souligner. Tout d'abord, le nom du joueur qui a lancé le jeu est mentionné dans le message de la vue d'alerte pour s'assurer que les autres joueurs savent qui héberge le jeu. Deuxièmement, nous invoquons toggleSubviewsState: mettre à jour l'interface utilisateur. Si vous testez l'application une fois de plus, vous remarquerez qu'une vue d'alerte est affichée pour chaque joueur connecté lors du lancement d'une nouvelle partie..


5. jouer

Étape 1

L'étape suivante consiste à ajouter la possibilité pour les autres joueurs de deviner le numéro secret choisi par l'hôte du jeu. Le flux que nous utilisons pour notifier les homologues connectés est très similaire à ce que nous avons vu jusqu'à présent. Commençons par implémenter le sendGuess: action.

Avant d’envoyer une proposition aux autres joueurs du jeu, nous vérifions si celle-ci est un nombre valide et qu’elle se situe dans la plage requise. Si c’est le cas, nous convertissons le contenu du txtGuess champ de texte à un NSData objet et l'envoyer aux pairs connectés. Sur l'appareil du joueur qui a fait la conjecture, nous ajoutons la conjecture au contenu de la vue texte..

- (IBAction) sendGuess: (id) expéditeur // Vérifie si un numéro a été entré ou non, et s'il est valide. if (self.txtGuess.text.length == 0 || [self.txtGuess.text intValue] < 1 || [self.txtGuess.text intValue] > 100) UIAlertView * alert = [[UIAlertView alloc] initWithTitle: @ "MPCDemo" message: @ "Veuillez entrer un nombre valide." délégué: nil cancelButtonTitle: nil otherButtonTitles: @ "OK", nil]; [émission d'alerte];  else // Convertit la chaîne de test en objet NSData et l'envoie à tous les pairs (lecteurs). NSData * supposeAsData = [self.txtGuess.text dataUsingEncoding: NSUTF8StringEncoding]; NSError * error; [self.appDelegate.mpcHandler.session sendData: guessAsData toPeers: self.appDelegate.mpcHandler.session.connectedPeers withMode: erreur MCSessionSendDataReliable: & error]; // Si une erreur survient, il suffit de consigner sa description. if (erreur! = nil) NSLog (@ "% @", [erreur localiséeDescription]);  // Ajouter au texte de l'historique voir le nombre donné par le joueur actuel. NSString * history = [NSString stringWithFormat: @ "J'ai deviné le numéro:% @ \ n \ n", self.txtGuess.text]; [self.tvHistory setText: [history stringByAppendingString: self.tvHistory.text]];  self.txtGuess.text = @ ""; [self.txtGuess resignFirstResponder]; 

Étape 2

Quand une proposition valide est envoyée aux autres joueurs du jeu, handleReceivedDataWithNotification: est invoqué. Nous avons déjà partiellement implémenté cette méthode précédemment dans ce didacticiel pour informer les autres joueurs du début d'une nouvelle partie. L'implémentation actuelle ne comprend qu'une seule instruction conditionnelle permettant de rechercher une nouvelle partie..

- (void) handleReceivedDataWithNotification: (NSNotification *) notification //… // if ([message isEqualToString: @ "Nouveau jeu"]) //… // //… //

Il est temps d'ajouter un autre clause pour gérer les autres messages entrants. Pour le moment, nous ne souhaitons gérer qu’une supposition faite par un autre joueur, ce qui signifie que nous devons vérifier si le message contient un numéro valide. L'extrait de code suivant détecte si le NSString objet comprend un nombre.

NSCharacterSet * numbersSet = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet * messageSet = [NSCharacterSet characterSetWithCharactersInString: message]; if ([numbersSet isSupersetOfSet: messageSet]) 

Si le message contient effectivement une proposition valide, nous l’afficherons dans la vue texte. De plus, nous vérifions si le joueur est l'hôte du jeu et, le cas échéant, nous affichons un affichage d'alerte avec trois actions possibles pour permettre à l'application d'envoyer des commentaires aux autres joueurs. Jetez un coup d’œil à l’implémentation mise à jour de handleReceivedDataWithNotification: pour clarification.

- (void) handleReceivedDataWithNotification: (NSNotification *) notification //… // if ([message isEqualToString: @ "Nouvelle partie"]) // ... // else // Vérifiez si le message ne contient que des chiffres. Si c'est le cas, // cela signifie qu'il contient une estimation du joueur qui l'a envoyé. NSCharacterSet * numbersSet = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet * messageSet = [NSCharacterSet characterSetWithCharactersInString: message]; if ([numbersSet isSupersetOfSet: messageSet]) // Le message contient la proposition d'un autre joueur. // Convertissez-le en nombre. int suppose = [message intValue]; // Ajoute cette proposition à la vue texte de l'historique. NSString * history = [NSString stringWithFormat: @ "Le joueur% @ a deviné le numéro:% d \ n \ n", senderDisplayName, suppose]; [self.tvHistory setText: [history stringByAppendingString: self.tvHistory.text]]; // Si self est le créateur du jeu, affichez toutes les options disponibles concernant cette proposition. if (self.hasCreatedGame) NSString * optionsMessage = [NSString stringWithFormat: @ "% @ \ n \ nLe numéro secret est% d. \ n \ nQuelle est votre réponse?", historique, self.secretNumber]; UIAlertView * optionsAlert = [[UIAlertView alloc] initWithTitle: @ message "MPCDemo": délégué optionsMessage: self cancelButtonTitle: nil otherButtonTitle: @ "Corrigez devinez!", @ "Attribuez un nombre supérieur", @ "Attribuez un nombre supérieur", @ "Nul ]; [optionsAlert show]; 

La capture d'écran suivante montre la vue d'alerte que l'hôte verra lorsqu'un joueur fait une proposition valide.


Étape 3

Pour gérer la réponse de l'hôte, nous devons mettre à jour le alertView: clickedButtonAtIndex: méthode du UIAlertViewDelegate protocole comme indiqué ci-dessous. Tout ce que nous faisons, c'est envoyer le titre du bouton sous forme de message aux autres joueurs du jeu..

- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput && buttonIndex == 1) //… // autre // Obtenir le titre du bouton coché , convertissez-le en objet NSData et envoyez-le à d’autres joueurs. NSString * selectedAnswer = [alertView buttonTitleAtIndex: buttonIndex]; NSData * answerAsData = [selectedAnswer dataUsingEncoding: NSUTF8StringEncoding]; NSError * error; [self.appDelegate.mpcHandler.session sendData: answerAsData toPeers: self.appDelegate.mpcHandler.session.connectedPeers withMode: erreur MCSessionSendDataReliable: & error]; if (erreur! = nil) NSLog (@ "% @", [erreur localiséeDescription]);  // En cas de doute, désactivez les drapeaux. if (buttonIndex == 0) self.hasCreatedGame = NO; self.isGameRunning = NO; 

Lorsqu'un adversaire fait une supposition correcte, nous terminons le jeu en définissant hasCreatedGame et isGameRunning à NON. Dans l'étape suivante, nous allons gérer le message envoyé aux autres joueurs du jeu..

Étape 4

Je suis sûr que vous commencez à comprendre comment les différentes pièces du jeu vont de pair. C'est un peu comme une partie de tennis dans laquelle les joueurs se frappent une balle jusqu'à ce qu'on la laisse tomber. Pour terminer le jeu, nous devons revisiter handleReceivedDataWithNotification: une fois de plus pour gérer la réponse envoyée par l'hôte du jeu après qu'un joueur ait fait une proposition valable.

Nous commençons par ajouter un autre clause à la seconde si déclaration comme indiqué ci-dessous. Tout ce que nous faisons, c'est ajouter le message, le titre du bouton tapé par l'hôte, au contenu de la vue texte. Si le message est égal à Guess correct, nous terminons le jeu et désactivons les commandes du jeu en appelant toggleSubviewsState: et en passant NON à cela.

- (void) handleReceivedDataWithNotification: (NSNotification *) notification //… // else // Vérifiez si le message ne contient que des chiffres. Si c'est le cas, // cela signifie qu'il contient une estimation du joueur qui l'a envoyé. NSCharacterSet * numbersSet = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet * messageSet = [NSCharacterSet characterSetWithCharactersInString: message]; if ([numbersSet isSupersetOfSet: messageSet]) //… // else // Si le message ne contient pas de chiffres, il contient la réponse du joueur qui a lancé le jeu. // Pour commencer, affichez simplement la réponse à la vue texte de l'historique. NSString * history = [NSString stringWithFormat: @ "% @ dit: \ n% @ \ n \ n", senderDisplayName, message]; [self.tvHistory setText: [history stringByAppendingString: self.tvHistory.text]]; // Vérifie si le créateur du jeu a répondu que la dernière hypothèse était la bonne. Dans ce cas, le jeu // devrait s'arrêter. if ([message isEqualToString: @ "Corriger Devinez!"]) self.isGameRunning = NO; [self toggleSubviewsState: NO]; 

Étape 5

L'application est presque terminée. Tout ce qui nous reste à faire est de mettre en œuvre le annuler action. Dans cette méthode, nous masquons le clavier en appelant resignFirstResponder sur le txtGuess champ de texte.

- (IBAction) cancelGuessing: (id) expéditeur [self.txtGuess resignFirstResponder]; 

6. Construire et exécuter

Notre jeu simple est maintenant prêt à jouer. Gardez à l'esprit que la mise en œuvre du jeu est simple car l'objectif principal de ce didacticiel est d'explorer le cadre de connectivité Multipeer introduit dans iOS 7. La capture d'écran suivante devrait vous donner une idée des différents états dans lesquels le jeu peut se.


Conclusion

J'espère que je vous ai convaincu que le cadre de connectivité Multipeer est un excellent ajout au SDK iOS. Ce tutoriel vous a montré qu'il est très facile d'envoyer des données entre homologues avec le framework Multipeer Connectivity. Le cadre a beaucoup plus à offrir, je vous encourage donc à explorer la documentation d'Apple pour mieux comprendre ses possibilités..