Last active
August 10, 2018 08:19
-
-
Save bcernesto/94b19be8a124655d9b159f3507a6f8aa to your computer and use it in GitHub Desktop.
Creación del juego Tres en Raya (gato, tic tac toe o similar) utilizando creación de vistas programáticas en Objective C.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Este archivo es solo una parte de la aplicación original, pero es el que incorpora toda la lógica. | |
Todo el código puede ser encontrado en GitHub en el siguiente repositorio: | |
https://github.com/bcernesto/Tres-En-Raya | |
Insisto: Este código no funcionará por sí solo! Es necesario clonar todo el repo */ | |
// Importación de otros archivos | |
#import "ViewController.h" | |
#import "SoundManager.h" | |
#import "UIView+Toast.h" | |
@interface ViewController (){ | |
// Creamos todas las variables que necesitaremos a nivel de Controller | |
NSMutableArray *arrayDeBotones; | |
UIButton *nuevoBoton; | |
UIView *menu; | |
float anchoVentana; | |
float altoVentana; | |
int jugador; | |
int jugada; | |
}@end | |
@implementation ViewController | |
// Método que se ejecutará cuando la app esté totalmente cargada, es decir, al inicio de la app. | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
// Establecemos valores iniciales para algunas variables | |
anchoVentana=self.view.bounds.size.width; | |
altoVentana=self.view.bounds.size.height; | |
jugador=1; | |
jugada=0; | |
[self agregarBotones]; | |
// Los sonidos hacen uso de una librería externa, incluída en el repositorio | |
[[SoundManager sharedManager] setMusicVolume:0.2]; | |
[[SoundManager sharedManager] playMusic:@"intro.mp3" looping:YES]; | |
} | |
// Método que agrega todos los botones de la interfaz | |
- (void) agregarBotones{ | |
// Establecemos algunas variables | |
float anchoBoton=anchoVentana/3; | |
float altoBoton=altoVentana/3; | |
arrayDeBotones = [[NSMutableArray alloc] init]; | |
int x=0; | |
int y=0; | |
// Con un for, creamos los 9 botones que conformarán la interfaz | |
for (int i=0; i<9; i++) { | |
nuevoBoton = [[UIButton alloc] initWithFrame:CGRectMake(anchoBoton*x+1, altoBoton*y+1, anchoBoton, altoBoton)]; | |
[nuevoBoton setBackgroundColor:[UIColor blueColor]]; | |
[nuevoBoton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | |
[nuevoBoton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; | |
[nuevoBoton setAccessibilityLabel:@"Casilla vacía"]; | |
[nuevoBoton addTarget:self action:@selector(botonPulsado:) forControlEvents:UIControlEventTouchUpInside]; | |
nuevoBoton.tag = i; | |
nuevoBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15]; | |
nuevoBoton.layer.masksToBounds = YES; | |
nuevoBoton.layer.cornerRadius = 5; | |
nuevoBoton.layer.borderWidth = 1; | |
nuevoBoton.layer.borderColor = [[UIColor blackColor] CGColor]; | |
[arrayDeBotones addObject:nuevoBoton]; | |
if(x==2){ | |
x=0; | |
y=y+1; | |
}else{ | |
x=x+1; | |
} | |
} | |
// Agregamos todos los botones a la View principal | |
for(UIButton *boton in arrayDeBotones){ | |
[self.view addSubview:boton]; | |
} | |
} | |
// Método que se ejecutará cuando se pulse cualquiera de los botones | |
-(void) botonPulsado:(UIButton *) sender { | |
// Se comprueba que haya un turno, y que el botón no haya sido pulsado ya antes | |
if((jugador>0)&&([self tituloBoton:sender.tag]==nil)){ | |
// Se realizan acciones dependiendo el turno del jugador que pulsó | |
switch(jugador){ | |
case 1: | |
[sender setAccessibilityLabel:@"X"]; | |
[sender setTitle:@"X" forState:UIControlStateNormal]; | |
[[SoundManager sharedManager] playSound:@"gato.mp3" looping:NO]; | |
break; | |
case 2: | |
[sender setAccessibilityLabel:@"O"]; | |
[sender setTitle:@"O" forState:UIControlStateNormal]; | |
[[SoundManager sharedManager] playSound:@"perro.mp3" looping:NO]; | |
break; | |
} | |
// Se incrementa el contador de jugadas, y se hacen comprobaciones para saber si ha ganado alguno | |
jugada=jugada+1; | |
int resultado=[self ComprobarPartida]; | |
if(resultado>0) { | |
[self finPartida:resultado]; | |
}else{ | |
[self turnoSiguiente]; | |
} | |
}else{ | |
[[SoundManager sharedManager] playSound:@"vaca.mp3" looping:NO]; | |
} | |
} | |
// Método que cambia el turno al siguiente jugador, en caso de que no haya finalizado la partida con empate | |
-(void) turnoSiguiente{ | |
switch(jugador){ | |
case 1: | |
jugador=2; | |
break; | |
case 2: | |
jugador=1; | |
break; | |
} | |
// Se hace uso de una librería externa para crear avisos emergentes al estilo Android, también incluída en el repositorio | |
[self.view makeToast:[NSString stringWithFormat:@"Turno del jugador %i", jugador] | |
duration:3.0 | |
position:CSToastPositionCenter]; | |
} | |
// Método que comprueba si la partida ha finalizado con un empate (retorna 2), o si alguno ha ganado (retorna 1). De lo contrario retorna 0 | |
- (int) ComprobarPartida{ | |
if (([[self tituloBoton:0] isEqual:[self tituloBoton:1]])&&([[self tituloBoton:1] isEqual:[self tituloBoton:2]])) return 1; | |
if (([[self tituloBoton:3] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:5]])) return 1; | |
if (([[self tituloBoton:6] isEqual:[self tituloBoton:7]])&&([[self tituloBoton:7] isEqual:[self tituloBoton:8]])) return 1; | |
if (([[self tituloBoton:0] isEqual:[self tituloBoton:3]])&&([[self tituloBoton:3] isEqual:[self tituloBoton:6]])) return 1; | |
if (([[self tituloBoton:1] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:7]])) return 1; | |
if (([[self tituloBoton:2] isEqual:[self tituloBoton:5]])&&([[self tituloBoton:5] isEqual:[self tituloBoton:8]])) return 1; | |
if (([[self tituloBoton:0] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:8]])) return 1; | |
if (([[self tituloBoton:2] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:6]])) return 1; | |
if(jugada==9) return 2; | |
return 0; | |
} | |
// Método que obtiene el título de un botón, a partir de su tag | |
-(NSString*) tituloBoton:(int) tagBoton{ | |
for(UIButton *boton in arrayDeBotones){ | |
if(boton.tag==tagBoton) return boton.currentTitle; | |
} | |
return NULL; | |
} | |
// Método que notifica si la partida a finalizado y su resultado | |
-(void) finPartida:(int) resultado{ | |
NSString *mensajeAlerta; | |
switch(resultado){ | |
case 1: | |
mensajeAlerta=[NSString stringWithFormat:@"Ha ganado el jugador %i",jugador]; | |
[[SoundManager sharedManager] playSound:@"aplausos.mp3" looping:NO]; | |
break; | |
case 2: | |
mensajeAlerta=@"La partida ha finalizado con un empate"; | |
[[SoundManager sharedManager] playSound:@"abucheo.mp3" looping:NO]; | |
break; | |
} | |
UIAlertController *alerta = [UIAlertController | |
alertControllerWithTitle:@"¡Partida terminada!" | |
message:mensajeAlerta | |
preferredStyle:UIAlertControllerStyleAlert]; | |
UIAlertAction *ok=[UIAlertAction | |
actionWithTitle:@"Aceptar" | |
style:UIAlertActionStyleDefault | |
handler:^(UIAlertAction *action) | |
{ | |
[alerta dismissViewControllerAnimated:YES completion:nil]; | |
[self menuPartida:mensajeAlerta]; | |
}]; | |
[alerta addAction:ok]; | |
[self presentViewController:alerta animated:YES completion:nil]; | |
} | |
// Método que da la opción de volver a jugar | |
-(void) menuPartida:(NSString*) mensaje{ | |
jugador=0; | |
jugada=0; | |
[[SoundManager sharedManager] stopMusic:NO]; | |
[[SoundManager sharedManager] stopAllSounds:NO]; | |
for(UIButton *boton in arrayDeBotones){ | |
[boton removeFromSuperview]; | |
} | |
[arrayDeBotones removeAllObjects]; | |
menu = [[UIView alloc] | |
initWithFrame:CGRectMake(20,20,anchoVentana-40,altoVentana-40)]; | |
float anchoVistaMenu=menu.bounds.size.width; | |
float altoVistaMenu=menu.bounds.size.height; | |
UILabel *MenuEtiqueta = [[UILabel alloc] | |
initWithFrame:CGRectMake(0,0,anchoVistaMenu,altoVistaMenu/4*3)]; | |
MenuEtiqueta.text=[NSString stringWithFormat:@"Partida terminada. %@", mensaje]; | |
[menu addSubview:MenuEtiqueta]; | |
UIButton *menuBoton = [[UIButton alloc] | |
initWithFrame:CGRectMake(0,altoVistaMenu/4*3+1,anchoVistaMenu,altoVistaMenu/4)]; | |
[menuBoton setBackgroundColor:[UIColor blueColor]]; | |
[menuBoton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | |
[menuBoton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; | |
[menuBoton setTitle:@"Jugar de nuevo" forState:UIControlStateNormal]; | |
[menuBoton addTarget:self action:@selector(jugarDeNuevo:) forControlEvents:UIControlEventTouchUpInside]; | |
menuBoton.tag = 9; | |
menuBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15]; | |
menuBoton.layer.masksToBounds = YES; | |
menuBoton.layer.cornerRadius = 5; | |
menuBoton.layer.borderWidth = 1; | |
menuBoton.layer.borderColor = [[UIColor blackColor] CGColor]; | |
[menu addSubview:menuBoton]; | |
[self.view addSubview:menu]; | |
} | |
// Método que limpia las variables y la interfaz, y las regresa a su estado original para jugar nuevamente | |
-(void) jugarDeNuevo:(UIButton *) sender { | |
[menu removeFromSuperview]; | |
[self agregarBotones]; | |
jugador=1; | |
[[SoundManager sharedManager] playMusic:@"intro.mp3" looping:YES]; | |
} | |
// Método incluído en todos los Controllers | |
- (void)didReceiveMemoryWarning { | |
[super didReceiveMemoryWarning]; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Este archivo es solo una parte de la aplicación original, pero es el que incorpora toda la lógica. | |
Todo el código puede ser encontrado en GitHub en el siguiente repositorio: | |
https://github.com/bcernesto/Tres-En-Raya | |
Insisto: Este código no funcionará por sí solo! Es necesario clonar todo el repo */ | |
// Importación de otros archivos | |
#import "ViewController.h" | |
#import "SoundManager.h" | |
#import "UIView+Toast.h" | |
@interface ViewController (){ | |
// Creamos todas las variables que necesitaremos a nivel de Controller | |
NSMutableArray *arrayDeBotones; | |
UIButton *nuevoBoton; | |
UIView *menu; | |
float anchoVentana; | |
float altoVentana; | |
int jugador; | |
int jugada; | |
}@end | |
@implementation ViewController | |
// Método que se ejecutará cuando la app esté totalmente cargada, es decir, al inicio de la app. | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
// Establecemos valores iniciales para algunas variables | |
anchoVentana=self.view.bounds.size.width; | |
altoVentana=self.view.bounds.size.height; | |
jugador=1; | |
jugada=0; | |
[self agregarBotones]; | |
// Los sonidos hacen uso de una librería externa, incluída en el repositorio | |
[[SoundManager sharedManager] setMusicVolume:0.2]; | |
[[SoundManager sharedManager] playMusic:@"intro.mp3" looping:YES]; | |
} | |
// Método que agrega todos los botones de la interfaz | |
- (void) agregarBotones{ | |
// Establecemos algunas variables | |
float anchoBoton=anchoVentana/3; | |
float altoBoton=altoVentana/3; | |
arrayDeBotones = [[NSMutableArray alloc] init]; | |
int x=0; | |
int y=0; | |
// Con un for, creamos los 9 botones que conformarán la interfaz | |
for (int i=0; i<9; i++) { | |
nuevoBoton = [[UIButton alloc] initWithFrame:CGRectMake(anchoBoton*x+1, altoBoton*y+1, anchoBoton, altoBoton)]; | |
[nuevoBoton setBackgroundColor:[UIColor blueColor]]; | |
[nuevoBoton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | |
[nuevoBoton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; | |
[nuevoBoton setAccessibilityLabel:@"Casilla vacía"]; | |
[nuevoBoton addTarget:self action:@selector(botonPulsado:) forControlEvents:UIControlEventTouchUpInside]; | |
nuevoBoton.tag = i; | |
nuevoBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15]; | |
nuevoBoton.layer.masksToBounds = YES; | |
nuevoBoton.layer.cornerRadius = 5; | |
nuevoBoton.layer.borderWidth = 1; | |
nuevoBoton.layer.borderColor = [[UIColor blackColor] CGColor]; | |
[arrayDeBotones addObject:nuevoBoton]; | |
if(x==2){ | |
x=0; | |
y=y+1; | |
}else{ | |
x=x+1; | |
} | |
} | |
// Agregamos todos los botones a la View principal | |
for(UIButton *boton in arrayDeBotones){ | |
[self.view addSubview:boton]; | |
} | |
} | |
// Método que se ejecutará cuando se pulse cualquiera de los botones | |
-(void) botonPulsado:(UIButton *) sender { | |
// Se comprueba que haya un turno, y que el botón no haya sido pulsado ya antes | |
if((jugador>0)&&([self tituloBoton:sender.tag]==nil)){ | |
// Se realizan acciones dependiendo el turno del jugador que pulsó | |
switch(jugador){ | |
case 1: | |
[sender setAccessibilityLabel:@"X"]; | |
[sender setTitle:@"X" forState:UIControlStateNormal]; | |
[[SoundManager sharedManager] playSound:@"gato.mp3" looping:NO]; | |
break; | |
case 2: | |
[sender setAccessibilityLabel:@"O"]; | |
[sender setTitle:@"O" forState:UIControlStateNormal]; | |
[[SoundManager sharedManager] playSound:@"perro.mp3" looping:NO]; | |
break; | |
} | |
// Se incrementa el contador de jugadas, y se hacen comprobaciones para saber si ha ganado alguno | |
jugada=jugada+1; | |
int resultado=[self ComprobarPartida]; | |
if(resultado>0) { | |
[self finPartida:resultado]; | |
}else{ | |
[self turnoSiguiente]; | |
} | |
}else{ | |
[[SoundManager sharedManager] playSound:@"vaca.mp3" looping:NO]; | |
} | |
} | |
// Método que cambia el turno al siguiente jugador, en caso de que no haya finalizado la partida con empate | |
-(void) turnoSiguiente{ | |
switch(jugador){ | |
case 1: | |
jugador=2; | |
break; | |
case 2: | |
jugador=1; | |
break; | |
} | |
// Se hace uso de una librería externa para crear avisos emergentes al estilo Android, también incluída en el repositorio | |
[self.view makeToast:[NSString stringWithFormat:@"Turno del jugador %i", jugador] | |
duration:3.0 | |
position:CSToastPositionCenter]; | |
} | |
// Método que comprueba si la partida ha finalizado con un empate (retorna 2), o si alguno ha ganado (retorna 1). De lo contrario retorna 0 | |
- (int) ComprobarPartida{ | |
if (([[self tituloBoton:0] isEqual:[self tituloBoton:1]])&&([[self tituloBoton:1] isEqual:[self tituloBoton:2]])) return 1; | |
if (([[self tituloBoton:3] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:5]])) return 1; | |
if (([[self tituloBoton:6] isEqual:[self tituloBoton:7]])&&([[self tituloBoton:7] isEqual:[self tituloBoton:8]])) return 1; | |
if (([[self tituloBoton:0] isEqual:[self tituloBoton:3]])&&([[self tituloBoton:3] isEqual:[self tituloBoton:6]])) return 1; | |
if (([[self tituloBoton:1] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:7]])) return 1; | |
if (([[self tituloBoton:2] isEqual:[self tituloBoton:5]])&&([[self tituloBoton:5] isEqual:[self tituloBoton:8]])) return 1; | |
if (([[self tituloBoton:0] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:8]])) return 1; | |
if (([[self tituloBoton:2] isEqual:[self tituloBoton:4]])&&([[self tituloBoton:4] isEqual:[self tituloBoton:6]])) return 1; | |
if(jugada==9) return 2; | |
return 0; | |
} | |
// Método que obtiene el título de un botón, a partir de su tag | |
-(NSString*) tituloBoton:(int) tagBoton{ | |
for(UIButton *boton in arrayDeBotones){ | |
if(boton.tag==tagBoton) return boton.currentTitle; | |
} | |
return NULL; | |
} | |
// Método que notifica si la partida a finalizado y su resultado | |
-(void) finPartida:(int) resultado{ | |
NSString *mensajeAlerta; | |
switch(resultado){ | |
case 1: | |
mensajeAlerta=[NSString stringWithFormat:@"Ha ganado el jugador %i",jugador]; | |
[[SoundManager sharedManager] playSound:@"aplausos.mp3" looping:NO]; | |
break; | |
case 2: | |
mensajeAlerta=@"La partida ha finalizado con un empate"; | |
[[SoundManager sharedManager] playSound:@"abucheo.mp3" looping:NO]; | |
break; | |
} | |
UIAlertController *alerta = [UIAlertController | |
alertControllerWithTitle:@"¡Partida terminada!" | |
message:mensajeAlerta | |
preferredStyle:UIAlertControllerStyleAlert]; | |
UIAlertAction *ok=[UIAlertAction | |
actionWithTitle:@"Aceptar" | |
style:UIAlertActionStyleDefault | |
handler:^(UIAlertAction *action) | |
{ | |
[alerta dismissViewControllerAnimated:YES completion:nil]; | |
[self menuPartida:mensajeAlerta]; | |
}]; | |
[alerta addAction:ok]; | |
[self presentViewController:alerta animated:YES completion:nil]; | |
} | |
// Método que da la opción de volver a jugar | |
-(void) menuPartida:(NSString*) mensaje{ | |
jugador=0; | |
jugada=0; | |
[[SoundManager sharedManager] stopMusic:NO]; | |
[[SoundManager sharedManager] stopAllSounds:NO]; | |
for(UIButton *boton in arrayDeBotones){ | |
[boton removeFromSuperview]; | |
} | |
[arrayDeBotones removeAllObjects]; | |
menu = [[UIView alloc] | |
initWithFrame:CGRectMake(20,20,anchoVentana-40,altoVentana-40)]; | |
float anchoVistaMenu=menu.bounds.size.width; | |
float altoVistaMenu=menu.bounds.size.height; | |
UILabel *MenuEtiqueta = [[UILabel alloc] | |
initWithFrame:CGRectMake(0,0,anchoVistaMenu,altoVistaMenu/4*3)]; | |
MenuEtiqueta.text=[NSString stringWithFormat:@"Partida terminada. %@", mensaje]; | |
[menu addSubview:MenuEtiqueta]; | |
UIButton *menuBoton = [[UIButton alloc] | |
initWithFrame:CGRectMake(0,altoVistaMenu/4*3+1,anchoVistaMenu,altoVistaMenu/4)]; | |
[menuBoton setBackgroundColor:[UIColor blueColor]]; | |
[menuBoton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | |
[menuBoton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; | |
[menuBoton setTitle:@"Jugar de nuevo" forState:UIControlStateNormal]; | |
[menuBoton addTarget:self action:@selector(jugarDeNuevo:) forControlEvents:UIControlEventTouchUpInside]; | |
menuBoton.tag = 9; | |
menuBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15]; | |
menuBoton.layer.masksToBounds = YES; | |
menuBoton.layer.cornerRadius = 5; | |
menuBoton.layer.borderWidth = 1; | |
menuBoton.layer.borderColor = [[UIColor blackColor] CGColor]; | |
[menu addSubview:menuBoton]; | |
[self.view addSubview:menu]; | |
} | |
// Método que limpia las variables y la interfaz, y las regresa a su estado original para jugar nuevamente | |
-(void) jugarDeNuevo:(UIButton *) sender { | |
[menu removeFromSuperview]; | |
[self agregarBotones]; | |
jugador=1; | |
[[SoundManager sharedManager] playMusic:@"intro.mp3" looping:YES]; | |
} | |
// Método incluído en todos los Controllers | |
- (void)didReceiveMemoryWarning { | |
[super didReceiveMemoryWarning]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment