Crea un juego de Buscaminas multijugador Creación del lado del cliente

Esta es la segunda entrega de la miniserie del juego Buscaminas. En este tutorial, aprenderá cómo implementar completamente el lado del cliente de la aplicación. Utilizaremos una aplicación iOS nativa que se conecta a los servidores web, analiza los datos y muestra la interacción de la interfaz de usuario..


Descripción del proyecto

Minesweeper Flag es un juego de mesa multijugador que se juega entre dos oponentes. Comúnmente, se asigna azul o rojo a cada jugador. El tablero está compuesto por 256 cuadrados iguales, y cada tablero tiene 51 minas colocadas en posiciones completamente aleatorias.


Vista previa del efecto final

Revisión de la parte 1

Antes de comenzar la segunda parte de la serie, asegúrese de tener la primera parte completamente probada e implementada.


Paso 1: Instalando Cocos 2D

El primer paso es descargar e instalar el motor de juego Cocos 2D. Para este tutorial, utilizamos Cocos 2D versión 2..

Una vez descargado, necesitas instalarlo e integrarlo con Xcode. Descomprima el archivo descargado anteriormente y verá un archivo llamado install-templates.sh. Abra una ventana de terminal y ejecute ese archivo con el siguiente comando

 ./ instalar-plantillas -f.

Paso 2: Crear un nuevo proyecto

Usando Xcode, crea un nuevo proyecto: Archivo -> Nuevo -> Proyecto.

Elegir la Cocos2d v2.x en el menú del lado izquierdo y Cocos2d iOS a la derecha.


Paso 3: Configurar las opciones del proyecto

Dale a tu proyecto un nombre y un identificador de empresa. Para este tutorial, usamos la opción de familia de dispositivos iPad..


Paso 4: Verifique la configuración

Si todo es correcto debería ver una ventana similar a la siguiente:


Paso 5: Añadir nuevas clases

Ahora debes agregar dos nuevos C objetivo clases Para ello, accede a la opción de menú. Archivo -> Nuevo -> Archivo.

Añade las siguientes clases:

  • LoadingScene: Esta clase servirá como pantalla de carga para el usuario mientras él / ella está esperando que otro jugador se una al juego..
  • GameScene: Esta es la clase principal del juego; Es donde se programa la lógica principal..

Paso 6: Agregar archivos de recursos

Para ejecutar correctamente el juego, debe agregar los archivos de recursos a su proyecto. Aquí puedes descargar los archivos de recursos utilizados. A continuación, cópialos en la carpeta de recursos..


Paso 7: Crea la clase HelloWorldLayer

Cambie su archivo de encabezado HelloWorldLayer a lo siguiente:

 #importar  #importar "cocos2d.h" @interface HelloWorldLayer: CCLayer  @property (no atómico, retener) NSURLConnection * connectionConnectGame; @ propiedad (no atómica, retener) NSMutableData * responseData; @ propiedad (no atómica, retener) NSString * URL; @property (nonatomic) int playerID; @property (no atómico, retener) NSString * playerIDString; @property (nonatomic) BOOL launchFlag; @property (no atómico, retener) NSString * gameID; @ propiedad (no atómica, retener) NSString * turnID; + (CCScene *) escena; - (void) connectTheWebService: (NSString *) id; @fin

Cambie el archivo de implementación HelloWorldLayer a lo siguiente:

 #import "HelloWorldLayer.h" #import "GameScene.h" #import "LoadingScene.h" #import "cocos2d.h" #import "AppDelegate.h" #pragma markGame @synthesize URL = _URL; @synthesize responseData = _responseData; @synthesize launchFlag = _launchFlag; @synthesize gameID = _gameID; @synthesize playerID = _playerID; @synthesize playerIDString = _playerIDString; @synthesize turnID = _turnID; + (Escena CCScene *) escena CCScene * = [nodo CCScene]; HelloWorldLayer * layer = [nodo HelloWorldLayer]; [escena addChild: capa]; escena de retorno  - (id) init if ((self = [super init])) [self setLaunchFlag: FALSE]; // CAMBIAR EL ENLACE en consecuencia [auto setURL: @ "http://10.0.6.178:8080/Minesweeper_Flag/resources/generic/connectGame/"]; CGSize size = [[CCDirector sharedDirector] winSize]; // Fondo CCSprite * background = [CCSprite spriteWithFile: @ "background.jpg"]; background.position = ccp (size.width / 2, size.height / 2); [auto addChild: fondo]; CCSprite * flags = [CCSprite spriteWithFile: @ "bandeiras.png"]; flags.scale = .30; flags.position = ccp (size.width - size.width / 1.15, size.height - size.height / 1.25); [auto addChild: flags]; // Etiqueta del título CCLabelTTF * label = [CCLabelTTF labelWithString: @ "Minesweeper Flags" fontName: @ "Marker Felt" fontSize: 64]; label.position = ccp (size.width / 2, size.height - size.height / 4); [auto addChild: etiqueta]; // Generación de ID de jugador NSDateFormatter * date = [[NSDateFormatter alloc] init]; [fecha setDateFormat: @ "mm"]; int minute = [[date stringFromDate: [NSDate date]] intValue]; [fecha setDateFormat: @ "ss"]; int seconds = [[date stringFromDate: [NSDate date]] intValue]; int pID = minuto + segundos + (rand ()% 1000000); [self setPlayerID: pID]; NSString * playerIDInStringFormat = [NSString stringWithFormat: @ "% d", _playerID]; [self setPlayerIDString: playerIDInStringFormat]; NSLog (@ "ID DO PLAYER% @", _ playerIDString); [self setResponseData: [NSMutableData data]]; // Menús [CCMenuItemFont setFontSize: 38]; CCMenuItem * itemNewGame = [CCMenuItemFont itemWithString: @ bloque "Nuevo juego": ^ (remitente de identificación) [self connectTheWebService: playerIDInStringFormat]; ]; CCMenu * menu = [CCMenu menuWithItems: itemNewGame, nil]; [menú alignItemsVerticallyWithPadding: 20]; [menu setPosition: ccp (size.width / 2, size.height / 2 - 50)]; [auto addChild: menu];  devuélvete a ti mismo;  // conectar el método del servidor web - (void) connectTheWebService: (NSString *) id NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: [[_ URL autorelease] stringByAppendingString: id]]]; _connectionConnectGame = [[NSURLConnection alloc] initWithRequest: delegado de solicitud: self];  // Respuestas del servidor web. - (void) connection: (NSURLConnection *) connection didReceiveResponse: (NSURLResponse *) response [_responseData setLength: 0];  - (void) conexión: (NSURLConnection *) conexión didReceiveData: (NSData *) data [_responseData appendData: data];  - conexión (anulada): (NSURLConnection *) conexión didFailWithError: (NSError *) error NSLog (@ "Falló la conexión:% @", [descripción del error]);  - (void) connectionDidFinishLoading: (NSURLConnection *) connection NSString * responseString = [[NSString alloc] initWithData: _responseData encoding: NSUTF8StringEncoding]; NSLog (@ "HelloWorld responseString% @", responseString); NSArray * resultArray = [[NSArray alloc] init]; resultArray = [responseString componentsSeparatedByString: @ ","]; if ([[resultArray objectAtIndex: 1] isEqualToString: @ "no"]) [self setGameID: [resultArray objectAtIndex: 0]]; [self setLaunchFlag: TRUE];  else [self setGameID: [resultArray objectAtIndex: 0]]; _playerID = [[resultArray objectAtIndex: 1] integerValue]; [self setPlayerID: [[resultArray objectAtIndex: 1] integerValue]]; [self setLaunchFlag: FALSE];  if (_launchFlag) GameScene * scene = [[GameScene alloc] initializeInternalDataWithPlayerID: _playerIDString andWithGameID: _gameID andWithTurnID: @ "no"]; [[CCDirector sharedDirector] replaceScene: scene];  else LoadingScene * scene = [LoadingScene initializeWithPlayerID: _playerIDString andWithGameID: _gameID]; [[CCDirector sharedDirector] replaceScene: scene];  - (void) dealloc [super dealloc];  @final

Paso 8: Crea la clase LoadingScene

Cambie su archivo de encabezado LoadingScene a lo siguiente:

 #import "cocos2d.h" @interface LoadingScene: CCLayer  @propiedad (no atómica, retener) NSURLConnection * connectionConnectGame; @ propiedad (no atómica, retener) NSMutableData * responseData; @property (no atómico, retener) NSString * gameID; @propiedad (no atómica, retener) NSString * playerID; @property (nonatomic) BOOL launchFlag; @ propiedad (no atómica, retener) NSString * URL; + (CCScene *) escena; + (id) initializeWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid; - (id) initializeInternalDataWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid; - (void) connectTheWebService: (NSString *) id; @fin

Cambie su archivo de implementación LoadingScene a lo siguiente:

 #import "LoadingScene.h" #import "GameScene.h" @implementation LoadingScene @synthesize responseData = _responseData; @synthesize connectionConnectGame = _connectionConnectGame; @synthesize gameID = _gameID; @synthesize playerID = _playerID; @synthesize launchFlag = _launchFlag; @synthesize URL = _URL; + (Escena CCScene *) escena CCScene * = [nodo CCScene]; LoadingScene * layer = [nodo LoadingScene]; [escena addChild: capa]; escena de retorno  - (id) init if ((self = [super init]))  return self;  // Inicializador personalizado + (id) initializeWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid return [[[allocual]] initializeInternalDataWithPlayerID: playerid yWithGameID: gameid] autorelease];  - (id) initializeInternalDataWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid self = [super init]; if (self) CGSize _size = [[CCDirector sharedDirector] winSize]; _gameID = [[NSString alloc] init]; [self setLaunchFlag: FALSE]; [self setPlayerID: playerid]; [self setGameID: gameid]; CCSprite * background = [CCSprite spriteWithFile: @ "background.jpg"]; background.position = ccp (_size.width / 2, _size.height / 2); [auto addChild: fondo]; CCLabelTTF * label = [CCLabelTTF labelWithString: @ "Cargando ..." fontName: @ "Marker Felt" fontSize: 40]; label.position = ccp (_size.width / 2, _size.height / 2); [auto addChild: etiqueta]; CCLabelTTF * label2 = [CCLabelTTF labelWithString: @ "Esperando a otro jugador" fontName: @ "Marker Felt" fontSize: 25]; label2.position = ccp (_size.width / 2, _size.height - _size.height / 1.80); [auto addChild: label2]; [self setResponseData: [NSMutableData data]]; // CAMBIARLO DE ACUERDO [auto setURL: @ "http://10.0.6.178:8080/Minesweeper_Flag/resources/generic/player2Available/"]; [programación propia: @selector (actualización :) intervalo: 2];  devuélvete a ti mismo;  - (nula) actualización: (ccTime) dt [self connectTheWebService: _gameID];  - (void) connectTheWebService: (NSString *) id NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: [[_ URL autorelease] stringByAppendingString: id]]]; _connectionConnectGame = [[NSURLConnection alloc] initWithRequest: delegado de solicitud: self];  - (void) conexión: (NSURLConnection *) conexión didReceiveResponse: (NSURLResponse *) respuesta [_responseData setLength: 0];  - (void) conexión: (NSURLConnection *) conexión didReceiveData: (NSData *) data [_responseData appendData: data];  - conexión (anulada): (NSURLConnection *) conexión didFailWithError: (NSError *) error NSLog (@ "Falló la conexión:% @", [descripción del error]);  - (void) connectionDidFinishLoading: (NSURLConnection *) connection NSString * responseString = [[NSString alloc] initWithData: _responseData encoding: NSUTF8StringEncoding]; if ([responseString isEqualToString: @ "nulo"]) [self setLaunchFlag: FALSE];  else [self setLaunchFlag: TRUE];  if (_launchFlag) GameScene * scene = [[GameScene alloc] initializeInternalDataWithPlayerID: _playerID andWithGameID: _gameID andWithTurnID: _playerID]; [[CCDirector sharedDirector] replaceScene: scene];  else [self schedule: @selector (update :) interval: 2];  - (void) dealloc [super dealloc];  @final

Paso 9: Crea la clase GameScene

Cambie su archivo de cabecera GameScene a lo siguiente:

 #import "cocos2d.h" @interface GameScene: CCLayer  NSString * turno;  @property (nonatomic) int gameGridSize, initialSpriteXXPosition, initialSpriteYYPosition, deslocamentoNoEixoXX, deslocamentoNoEixoYY, tamanhoSprite, playerBlueScore, playerRedScore, lastSpriteTouch; @property (no atómico, retener) NSMutableArray * spritesMutableArray; @ propiedad (no atómica, retener) NSMutableArray * TouchLocations; @ tamaño de propiedad (no atómico) CGSize; @property (nonatomic) CGPoint initialSpritePositon; @propiedad (no atómico, retener) CCSprite * sprites; @property (nonatomic) int spritePositionInGrid; @property (nonatomic) int webServerResult; @ propiedad (no atómica, fuerte) NSMutableData * responseData; @property (nonatomic, strong) NSString * resourceImage; @property (no atómico, retener) CCSprite * playerBlueSprite; @property (no atómico, retener) CCSprite * playerRedSprite; @property (no atómico, retener) CCSprite * playerTurnSprite; @ propiedad (no atómica, retener) CCSprite * youArrow; @ propiedad (no atómica, retener) CCLabelTTF * playerBlueLabel; @ propiedad (no atómica, retener) CCLabelTTF * playerRedLabel; @property (no atómico, retener) NSString * gameID; @ propiedad (no atómica, retener) NSString * userID; @propiedad (no atómica, retención) NSString * colorPlayer; @property (no atómico, retener) CCSprite * positionTouchedSprite; @propiedad (no atómica, retener) NSString * turno; @property (no atómico, retener) NSMutableString * gameBoardInfoS; + (CCScene *) escena; - (void) getMinesAtPosition: (int) pos; - (void) drawGameBoard; - (void) setInitialAppValues; - (void) setArrowonTheRightPlayer; + (id) initializeWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid yWithTurnID: (NSString *) turnid; - (id) initializeInternalDataWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid yWithTurnID: (NSString *) turnid; @fin

Cambie su archivo de implementación de GameScene a lo siguiente:

 #import "GameScene.h" #import "cocos2d.h" #import "LoadingScene.h" @implementation GameScene @synthesize spritesMutableArray = _spritesMutableArray; @synthesize TouchLocations = _touchedLocations; @synthesize size = _size; @synthesize initialSpritePositon = _initialSpritePositon; @synthesize sprites = _sprites; @synthesize spritePositionInGrid = _spritePositionInGrid; @synthesize webServerResult = _webServerResult; @synthesize gameGridSize = _gameGridSize; @synthesize initialSpriteXXPosition = _initialSpriteXXPosition; @synthesize initialSpriteYYPosition = _initialSpriteYYPosition; @synthesize deslocamentoNoEixoXX = _deslocamentoNoEixoXX; @synthesize deslocamentoNoEixoYY = _deslocamentoNoEixoYY; @synthesize tamanhoSprite = _tamanhoSprite; @synthesize responseData = _responseData; @synthesize resourceImage = _resourceImage; @synthesize playerTurnSprite = _playerTurnSprite; @synthesize youArrow = _youArrow; @synthesize playerBlueSprite = _playerBlueSprite; @synthesize playerRedSprite = _playerRedSprite; @synthesize playerBlueLabel = _playerBlueLabel; @synthesize playerRedLabel = _playerRedLabel; @synthesize playerBlueScore = _playerBlueScore; @synthesize playerRedScore = _playerRedScore; @synthesize gameID = _gameID; @synthesize userID = _userID; @synthesize colorPlayer = _colorPlayer; @synthesize turn = _turn; @synthesize gameBoardInfoS; @synthesize lastSpriteTouch; @synthesize positionTouchedSprite = _positionTouchedSprite; + (CCScene *) escena // + (id) escena CCScene * scene = [nodo CCScene]; GameScene * layer = [nodo GameScene]; [escena addChild: capa]; escena de retorno  - (id) init if ((self = [super init]))  return self;  // nuevo método de inicialización para recibir parámetros como playerID, turnID y gameID + (id) initializeWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid andWithTurnID: (NSString *) turnid return [[[auto atribuir]] initializeInternalDataWithPlayerID: playerid yWithGameID: gameid yWithTurnID: turnid] autorelease];  // inicializa varios valores y llama a los métodos para generar y dibujar toda la escena - (id) initializeInternalDataWithPlayerID: (NSString *) playerid yWithGameID: (NSString *) gameid andWithTurnID: (NSString *) turnid self = [super init]; if (self) // Activar eventos táctiles [super setIsTouchEnabled: YES]; // establece los parámetros [self setGameID: gameid]; [self setUserID: playerid]; [auto setTurn: turnid]; [self setInitialAppValues]; // generar y dibujar gameBoard [self drawGameBoard]; // llame al actualizador una vez para el segundo [self schedule: @selector (update :) interval: 1];  devuélvete a ti mismo;  // detectar toques y qué sprite fue tocado - (void) ccTouchesBegan: (NSSet *) toca withEvent: (UIEvent *) event // verifica si el usuario tiene el turno si (! [_ turn isEqualToString: _userID]) / / En caso de que el usuario no tenga el turno de retorno;  UITouch * touch = [toca cualquier Objeto]; CGPoint location = [touch locationInView: [touch view]]; CGPoint convertido = [[CCDirector sharedDirector] convertToGL: location]; _spritePositionInGrid = 0; para (CCSprite * spr en _spritesMutableArray) CCSprite * currentSprite = [_spritesMutableArray objectAtIndex: _spritePositionInGrid]; if (CGRectContainsPoint ([currentSprite boundingBox], convertido)) // Verificar si se ha seleccionado una posición para BOOL jaExiste = FALSE; para (int i = 0; i < [_touchedLocations count]; i++) if (_spritePositionInGrid == [[_touchedLocations objectAtIndex:i] integerValue]) jaExiste=TRUE;  //was touched? if([gameBoardInfoS characterAtIndex:_spritePositionInGrid] != '9') return;  if (!jaExiste) [_touchedLocations addObject:[NSNumber numberWithInt:_spritePositionInGrid]]; lastSpriteTouch = _spritePositionInGrid; self.responseData = [NSMutableData data]; _positionTouchedSprite = [_spritesMutableArray objectAtIndex:_spritePositionInGrid]; NSMutableString* enderecoReturnValue = [NSMutableString stringWithFormat:@"http://10.0.6.178:8080/Minesweeper_Flag/resources/generic/returnValue/%@/%@/%d",_userID,_gameID,_spritePositionInGrid]; NSLog(@"%@",enderecoReturnValue); NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:enderecoReturnValue]]; [[NSURLConnection alloc] initWithRequest:request delegate:self];   _spritePositionInGrid++;   -(void) update: (ccTime) dt  if(![_turn isEqualToString:_userID]) NSMutableString* returnUpdateURL = [NSMutableString stringWithFormat:@"http://10.0.6.178:8080/Minesweeper_Flag/resources/generic/returnUpdates/%@",_gameID]; NSURL *url = [NSURL URLWithString:returnUpdateURL]; NSData *jsonData = [NSData dataWithContentsOfURL:url]; NSString *value = [[NSString alloc] init]; NSRange a; if(jsonData != nil)  NSError *error = nil; id result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; if(error == nil)  NSString* resultString = [result objectForKey:@"Uncover_Matrix"]; int positionAt, positionDiff=-1; for(positionAt= 0; positionAt< resultString.length; positionAt++) a = NSMakeRange(positionAt, 1); if(![[gameBoardInfoS substringWithRange:a] isEqualToString:[resultString substringWithRange:a]]) positionDiff = positionAt; value = [[NSString alloc] initWithString:[resultString substringWithRange:a]]; break;   if(positionDiff != -1) [self setTurn:[result objectForKey:@"Turn"]]; [gameBoardInfoS replaceCharactersInRange:a withString:value]; if([value isEqualToString:@"*"]) _playerBlueScore++; NSString *stringBlueScore = [NSString stringWithFormat:@"%d",_playerBlueScore]; [_playerBlueLabel setString:stringBlueScore]; value = @"9";  if([value isEqualToString:@"#"]) _playerRedScore++; NSString *stringRedScore = [NSString stringWithFormat:@"%d",_playerRedScore]; [_playerRedLabel setString:stringRedScore]; value = @"10";  [self setArrowonTheRightPlayer]; CGPoint coordenates = [self getReversePositionGameBoard:positionDiff]; [self getMinesAtPosition:[value integerValue] withXCoord:coordenates.x andYYpos:coordenates.y];   else NSLog(@"error");    //recive the position and the value returned from Web Services and replace in the board -(void)getMinesAtPosition:(int)pos withXCoord:(int)xxpos andYYpos:(int)yypos _webServerResult = pos; switch (_webServerResult)  case 0: [self setResourceImage:@"0.png"]; break; case 1: [self setResourceImage:@"1.png"]; break; case 2: [self setResourceImage:@"2.png"]; break; case 3: [self setResourceImage:@"3.png"]; break; case 4: [self setResourceImage:@"4.png"]; break; case 5: [self setResourceImage:@"5.png"]; break; case 6: [self setResourceImage:@"6.png"]; break; case 7: [self setResourceImage:@"7.png"]; break; case 8: [self setResourceImage:@"8.png"]; break; case 9: [self setResourceImage:@"flag_b.png"]; break; case 10: [self setResourceImage:@"flag_r.png"]; break; default: _resourceImage = @"flag_r.png"; break;  // New sprite substitution after the WS invocation CCSprite* newSprite = [CCSprite spriteWithFile:_resourceImage]; newSprite.scale = .25; newSprite.position = ccp(xxpos,yypos); [self addChild:newSprite];  // communication - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response  [[self responseData] setLength:0];  - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data  [[self responseData] appendData:data];  - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error  NSLog(@"Connection failed: %@", [error description]);  - (void)connectionDidFinishLoading:(NSURLConnection *)connection  NSString* responseString = [[NSString alloc] initWithData:[self responseData] encoding:NSUTF8StringEncoding]; NSRange range = NSMakeRange(lastSpriteTouch, 1); [gameBoardInfoS replaceCharactersInRange:range withString:responseString]; //assign the turn after the request if([responseString isEqualToString:@"*"]) _playerBlueScore++; NSString *stringBlueScore = [NSString stringWithFormat:@"%d",_playerBlueScore]; [_playerBlueLabel setString:stringBlueScore]; _turn = _userID; responseString = @"9";  else if([responseString isEqualToString:@"#"]) _playerRedScore++; NSString *stringRedScore = [NSString stringWithFormat:@"%d",_playerRedScore]; [_playerRedLabel setString:stringRedScore]; _turn = _userID; responseString = @"10";  else _turn = @"is not you";  [self setArrowonTheRightPlayer]; [self getMinesAtPosition:[responseString integerValue] withXCoord:_positionTouchedSprite.position.x andYYpos:_positionTouchedSprite.position.y];  //put the arrow on the player that holds the turn -(void)setArrowonTheRightPlayer if([_turn isEqualToString:_userID])  if ([_colorPlayer isEqualToString:@"blue"]) _playerTurnSprite.position = ccp(_size.width/1.30, _size.height/1.10); else _playerTurnSprite.position = ccp(_size.width/1.30, _size.height/1.48);  if(![_turn isEqualToString:_userID])  if ([_colorPlayer isEqualToString:@"blue"]) _playerTurnSprite.position = ccp(_size.width/1.30, _size.height/1.48); else _playerTurnSprite.position = ccp(_size.width/1.30, _size.height/1.10);   //calculate the reverse position to change the sprite on gameBoard -(CGPoint)getReversePositionGameBoard:(int)positionTouched NSInteger linha = (int) positionTouched / 16.0; NSInteger y = 688 - _tamanhoSprite * linha; NSInteger x = ( (int) positionTouched % 16) * 38 + _initialSpriteXXPosition; CGPoint position = CGPointMake(x, y); return position;  //draw the gameBoard (background, sprites blue (water), and the playerss avatar -(void)drawGameBoard for (int i = 0 ; i < _gameGridSize; i++)  _sprites = [CCSprite spriteWithFile:@"water.png"]; _sprites.scale = .25; _initialSpritePositon = CGPointMake(_initialSpriteXXPosition+_deslocamentoNoEixoXX, _size.height-_initialSpriteYYPosition-(_deslocamentoNoEixoYY*_tamanhoSprite)); _sprites.position = ccp(_initialSpritePositon.x,_initialSpritePositon.y); _deslocamentoNoEixoXX+=_tamanhoSprite; if (((i+1) % 16) == 0) _deslocamentoNoEixoXX=0; _deslocamentoNoEixoYY++;  [_spritesMutableArray addObject:_sprites]; [self addChild:_sprites];  [self addChild:_playerTurnSprite z:4]; [self addChild:_playerBlueSprite]; [self addChild:_playerRedSprite]; [self addChild:_youArrow]; [self addChild:_playerBlueLabel]; [self addChild:_playerRedLabel];  //set initial values -(void)setInitialAppValues _size = [[CCDirector sharedDirector] winSize]; _gameGridSize = 256, _tamanhoSprite = 38; _initialSpriteXXPosition = 80, _initialSpriteYYPosition = 80; _deslocamentoNoEixoXX=0, _deslocamentoNoEixoYY=0; _spritesMutableArray = [[NSMutableArray alloc] initWithCapacity:256]; _touchedLocations = [[NSMutableArray alloc] initWithCapacity:256]; [self setResourceImage:@""]; CCSprite * background = [CCSprite spriteWithFile:@"background.jpg"]; background.position = ccp(_size.width/2,_size.height/2); [self addChild:background]; //init the gameBoard array gameBoardInfoS = [[NSMutableString alloc] init]; for(int i=0;i<256;i++) [gameBoardInfoS appendString:@"9"];  _playerBlueSprite = [CCSprite spriteWithFile:@"player_bue.png"]; _playerBlueSprite.scale = .5; _playerBlueSprite.position = ccp(_size.width/1.30, _size.height/1.25); _playerRedSprite = [CCSprite spriteWithFile:@"player_red.png"]; _playerRedSprite.scale = .5; _playerRedSprite.position = ccp(_size.width/1.30, _size.height/1.75); //identify the players on field if([_turn isEqualToString:_userID]) _youArrow = [CCSprite spriteWithFile:@"you.png"]; _youArrow.scale = .3; _youArrow.position = ccp(_size.width/1.30, _size.height/1.30); [self setColorPlayer:@"blue"];  else _youArrow = [CCSprite spriteWithFile:@"you.png"]; _youArrow.scale = .3; _youArrow.position = ccp(_size.width/1.30, _size.height/1.85); [self setColorPlayer:@"red"];  _playerTurnSprite = [CCSprite spriteWithFile:@"arrowTurn.png"]; _playerTurnSprite.scale = 1; _playerTurnSprite.position = ccp(_size.width/1.30, _size.height/1.10); _playerBlueLabel = [CCLabelTTF labelWithString:@"0" fontName:@"Marker Felt" fontSize:50.0]; _playerBlueLabel.position = ccp(_size.width/1.15, _size.height/1.25); _playerRedLabel = [CCLabelTTF labelWithString:@"0" fontName:@"Marker Felt" fontSize:50.0]; _playerRedLabel.position = ccp(_size.width/1.15, _size.height/1.75); [self setPlayerBlueScore:0]; [self setPlayerRedScore:0];  -(void) registerWithTouchDispatcher  NSLog(@"registerWithTouchDispatcher"); [[[CCDirector sharedDirector] touchDispatcher] addStandardDelegate:self priority:0];  - (void) dealloc  [turn release]; [super dealloc];  @end

Paso 10: construir y ejecutar el juego

Después de incluir el código mencionado anteriormente, el siguiente paso es compilar y probar la aplicación. Utilizar el cmd + b atajo. Si todo está bien, debería ver el simulador de iPad en funcionamiento y funcionando..


Paso 11: Disfruta el juego

En este paso final el objetivo es disfrutar del juego. Dado que el juego es para dos jugadores, la mejor manera de jugar es con un amigo.!

En las siguientes pantallas podemos ver el tablero final del juego a través de la visión de los dos jugadores (azul y rojo). La flecha sobre el avatar del jugador indica el turno del jugador actual; el jugador que esta jugando actualmente.

Tablero de juego del jugador azul:

Tablero de juego del jugador rojo:


Paso 12: Conclusiones

Con esto concluye la Parte II de cómo crear un juego de Minesweeper Flag utilizando tanto el código del lado del servidor como del cliente. A estas alturas, deberías tener suficiente conocimiento para crear un juego simple de Cocos2D con el mismo motor de juego. Si tiene preguntas o comentarios, no dude en dejarlos en la sección de comentarios aquí..