Vamos a seguir por donde íbamos: estábamos, si no recuerdo mal, en awakeFromNib, y acabábamos de introducir el código necesario para que el color no fuera un tono de gris.
Antes de nada, decir que los colores se definen en Cocoa como objetos de tipo NSColor, y se generan a partir de varios valores numéricos de tipo float en los métodos colorWithDevice y colorWithColorspace. Estos valores van de 0 a 1. Los métodos colorWith pueden generar el color a partir de rojo, verde y azul (RGB), a partir de cian, magenta, amarillo y negro (CMYK) o a partir de otros valores como el tono, la saturación y la luminosidad (HSV). En nuestro caso, vamos a generar nuestro color en base a los colores rojo, verde y azul.
Como los valores aleatorios que generamos el otro día eran enteros entre 0 y 6, vamos a dividirlos entre 6 para generar un número entre 0 y 1.
rrojo = rrojo / 6;
rverde = rverde / 6;
razul = razul / 6;
Ahora vamos a decirle al objeto NSColorWell que se ponga como color el color que hemos generado. Y lo hacemos así:
[colorobj setColor:[NSColor colorWithDeviceRed:rrojo green:rverde blue:razul alpha:1]];
utilizamos el método setColor: y le pasamos como color un objeto NSColor que creamos sobre la marcha con
colorWithDeviceRed:green:blue:alpha.
Vale. Ya hemos generado el color objetivo y, con ello, finalizada la zona de awakeFromNib. Ahora viene una parte que, aunque su código ocupa mucho, es simple.
Se trata de la acción a la que llamamos cada vez que el usuario cambia el valor de uno de los NSStepper. La acción que genera el color que estamos creando y comprueba si has ganado o no. La acción cambiavalor:.
Antes de nada, obtengamos los valores de los NSStepper:
double vrojo, vverde, vazul;
vrojo = [frojo doubleValue];
vverde = [fverde doubleValue];
vazul = [fazul doubleValue];
¿Fácil, no? Creamos tres variables en las que guardar el valor de los NSStepper y obtenemos ese valor.
Para mostrar cuanto más de cada color puedes añadir al color final, se me ocurrió que sería buena idea que los NSColorWell que estaban al lado de los NSStepper palidecieran según se iba echando color. Así que vamos a hacerlo.
double crojo = (vrojo / 5); // Se asignará 1 al rojo del //NSColorWell rojo y crojo al verde y al azul
double cverde = (vverde / 5); // Se asignará 1 al verde del //NSColorWell verde y cverde al rojo y al azul
double cazul = (vazul / 5); // Se asignará 1 al azul del //NSColorWell azul y crojo al rojo y al verde// Aplicamos los colores correspondientes en los //NSColorWell correspondientes
[rojo setColor:[NSColor colorWithDeviceRed:1 green:crojo blue:crojo alpha:1]];
[verde setColor:[NSColor colorWithDeviceRed:cverde green:1 blue:cverde alpha:1]];
[azul setColor:[NSColor colorWithDeviceRed:cazul green:cazul blue:1 alpha:1]];
Aunque parezca lioso, en el fondo es sencillo: Asignamos al color original del NSColorWell un 1, que es el máximo, y le añadimos una cantidad de los otros dos colores proporcional a la cantidad de rojo usada para generar el color, de forma que va palideciendo.
Ahora generamos el color final y lo colocamos en su NSColorWell correspondiente, tal y como hicimos en awakeFromNib (solo que cambiando las variables, claro)
vrojo = vrojo / 6;
vverde = vverde / 6;
vazul = vazul / 6;
[colorobj setColor:[NSColor colorWithDeviceRed:vrojo green:vverde blue:vazul alpha:1]];
Ahora, comprobamos si son iguales. No se pueden comparar dos objetos, así que diseccionamos sus colores en componentes y los comparamos. ¿Como los comparamos? Con la sentencia if.
La sentencia if es muy simple: le damos una condición que puede cumplirse, y unas instrucciones a seguir si se cumple. Podemos añadir instrucciones a seguir si no se cumple, o una segunda condición a comprobar si la primera no se cumple.
// Descomponemos los colores
float rtucolor, vtucolor, atucolor, rcolorobj, vcolorobj, acolorobj;
rtucolor = [utucolor redComponent];
vtucolor = [utucolor greenComponent];
atucolor = [utucolor blueComponent];
rcolorobj = [ucolorobj redComponent];
vcolorobj = [ucolorobj greenComponent];
acolorobj = [ucolorobj blueComponent];if (rtucolor == rcolorobj && vtucolor == vcolorobj && atucolor == acolorobj ) {
// Los comparamos
// Mostrar mensaje de victoria
[hasganado setStringValue:@"Has ganado!"];
// "Inhabilitar" los NSStepper
double currojo, curverde, curazul;
currojo = [frojo doubleValue];
curverde = [fverde doubleValue];
curazul = [fazul doubleValue];
[frojo setMinValue:currojo];
[frojo setMaxValue:currojo];
[fverde setMinValue:curverde];
[fverde setMaxValue:curverde];
[fazul setMinValue:curazul];
[fazul setMaxValue:curazul];
}
Sé que el paso de inhabilitar los NSStepper es muy complicado. En circunstancias normales lo inhabilitaríamos con una simple orden, pero por alguna razón esas propiedades son de solo lectura en NSStepper. Así que lo que hago es igualar su valor mínimo y máximo al valor actual. Así no nos afectan los clicks del usuario.
Y aquí acaba la función cambiavalor:. La función hasganado: solo tiene que “reiniciar” el juego, así que es un refrito de código de awakeFromNib y cambiavalor:. La copio entera:
- (IBAction)nuevojuego:(id)sender
{
// Volvemos a generar 3 números aleatorios tal y como //hicimos en awakeFromNib, solo que además sería
// buena idea comprobar que no sea otra vez la misma //combinación:
double rrojo = random() % 6;
double rverde = random() % 6;
double razul = random() % 6;// Comprobar que el valor no es un tono de gris de forma //recursiva
while (rrojo == rverde && rverde == razul) {
rrojo = rand() % 6;
rverde = rand() % 6;
razul = rand() % 6;
}// Comprobar que no sea otra vez lo mismo de antes
while ([frojo doubleValue] == rrojo &&
[fverde doubleValue] == rverde &&
[fazul doubleValue] == razul) {
rrojo = rand() % 6;
rverde = rand() % 6;
razul = rand() % 6;
}// Dividir entre 6
rrojo = rrojo / 6;
rverde = rverde / 6;
razul = razul / 6;// Colocarlo como objetivo
[colorobj setColor:[NSColor colorWithDeviceRed:rrojo green:rverde blue:razul alpha:1]];// Ahora, eliminemos el texto de "Has ganado!" de nuevo...
[hasganado setStringValue:@" "];// Y, por último, volvemos a colocar el valor mínimo y //máximo de los NSStepper en 0 y 5, como Jobs manda...
[frojo setMinValue:0];
[frojo setMaxValue:5];
[fverde setMinValue:0];
[fverde setMaxValue:5];
[fazul setMinValue:0];
[fazul setMaxValue:5];// Y colocamos el valor de los NSStepper en 0
[frojo setDoubleValue:0];
[fverde setDoubleValue:0];
[fazul setDoubleValue:0];// Y redibujamos los NSColorWell:
// Definimos las variables v{color} como copias de las //variables f{color}
double vrojo;
vrojo = [frojo doubleValue];
double vverde;
vverde = [fverde doubleValue];
double vazul;
vazul = [fazul doubleValue];// Definimos las variables c{color}
double crojo = (vrojo * 0.20); // Se asignará 1 al rojo del //NSColorWell rojo y crojo al verde y al azul
double cverde = (vverde * 0.20); // Se asignará 1 al verde del //NSColorWell verde y cverde al rojo y al azul
double cazul = (vazul * 0.20); // Se asignará 1 al azul del //NSColorWell azul y crojo al rojo y al verde// Aplicamos los colores correspondientes en los //NSColorWell correspondientes
[rojo setColor:[NSColor colorWithDeviceRed:1 green:crojo blue:crojo alpha:1]];
[verde setColor:[NSColor colorWithDeviceRed:cverde green:1 blue:cverde alpha:1]];
[azul setColor:[NSColor colorWithDeviceRed:cazul green:cazul blue:1 alpha:1]];// Dividimos entre 6
vrojo = vrojo / 6;
vverde = vverde / 6;
vazul = vazul / 6;// Colocar como objetivo
[tucolor setColor:[NSColor colorWithDeviceRed:vrojo green:vverde blue:vazul alpha:1]];}
Ahora, haced click en Build and Go para compilar y ejecutar la aplicación.
Espero que hayáis disfrutado con los tutoriales. De momento creo que este será el último, por que, aunque tengo ideas en mente, tengo estudios y otras cosas que hacer. Puede que los retome en unos meses. De cualquier manera, con un dominio simple del inglés, la documentación de XCode es buenísima, y la documentación de C está hasta en la sopa, así que espero que no tengáis problemas. Cualquier duda, en los comentarios o por e-mail, aunque, la verdad, yo no soy un gran experto.
Etiquetas: cocoa, Interface Builder, objective-c, programación, xcode


Para hacer un trackback a este artículo, usa
Para seguir los comentarios de este artículo por RSS, usa 

2 comentarios
Enhorabuena por el tutorial. Me está resolviendo más de una duda. Hacía falta un tutorial en español como este que fuese directo al grano. Estaré atento por si hay próximas entregas.
@Fernando: De momento no creo que las haya, pero en cuanto consiga una copia de Leopard (si hay suerte dentro de dos semanas) puede que haga algo relacionado con el iPhone… :D