sábado, 16 de abril de 2011

¡Adivina el personaje! mi primer juego para iPad



Mi primera aplicación para iPad ya está disponible para bajar de la app store. Os recomiendo a todos que descarguéis esta aplicación totalmente gratis.

¡Adivina el personaje! es un juego de adivinanza de dos jugadores. 

Cada jugador dispone de un tablero con 24 personajes animados.

El juego empieza con un personaje aleatorio para cada uno de los jugadores. 

El objetivo del juego es adivinar el personaje que tiene el jugador contrario. 

Los jugadores van realizando preguntas como ¿Lleva gafas? para ir descartando candidatos. 

Pueden jugar dos jugadores en un mismo iPad o un jugador contra la máquina.

Podesi ver unas fotos a continuación, pero os aconsejo que mireis la página principal del juego.

http://www.jandusoft.com

 

 

  

martes, 22 de febrero de 2011

CCSequenceHelper, CCSequence con NSMutableArray



Hoy quiero compartir con todos vosotros un pequeño fragmento de código que os puede ser útil en algún momento de vuestro desarrollo para iOS.

Si eres programador de cocos2d, sabrás que existen lasAnimaciones, (llamadasCCAnimation), y que puedes crear una secuencia de animaciones mediante la clase CCSequence.

El problema de esta clase es que solo puedes pasar una lista fija de animaciones, mediante el método 







(id) actions:



Sabemos que este método tiene como argumentos una lista de animaciones acabadas con nil, pero ¿Que pasa si no sabemos cuantas acciones queremos añadir?, o si estas acciones dependen de un bucle que tengamos.

Para solucionar este problema, voy a mostraros una solución basada en el uso de un NSMutableArray.

El objetivo es poder crear una secuencia de animaciones de forma dinámica, añadirlas a una variable de tipo NSMutableArray y pasar esta variable a una función que nos cree una secuencia. 

Para implementar esta solución, he decidido crear una clase Helper, denominada CCSequenceHelper. La utilización de la misma es muy fácil, simplemente creamos un NSMutableArray y añadimos CCAnimations a el (en este ejemplo, utilizo una animación especial que se encarga de ejecutar un método mediante un selector CCCallFuncND)



-(void) muestraAnimacionPreguntar:(NSMutableArray*) carasOcultar
{
int count = [carasOcultar count];
NSNumber *number;
NSMutableArray * secuencias = [NSMutableArray arrayWithCapacity:count+1];

for (int i = 0; i < count ;i++)
{
number = ((NSNumber*)[carasOcultar objectAtIndex:i]);
CCCallFunc * showX = [CCCallFuncND actionWithTarget:self selector:@selector(muestraCancelaCara:data:) data:(void*)[number intValue]];
showX.duration = 1;
[secuencias addObject:showX];
}
[secuencias addObject:[CCCallFunc actionWithTarget:self selector:@selector(endAnimacionPreguntar)]];
[self runAction:[CCSequenceHelper actionMutableArray:secuencias]];
}


y aquí la implementación de la clase Helper.


//
// CCSequenceHelper.h
//
// Created by Jose Antonio Andújar Clavell on 09/02/11.
// Alias "jandujar"
//
// More snippets on http://www.jandujar.com
//
// License http://creativecommons.org/licenses/by/3.0/
//
// Based upon code by daemonk
// http://www.cocos2d-iphone.org/forum/topic/2547
//

#import
#import "cocos2d.h"

@interface CCSequenceHelper : CCSequence {

}

+(id) actionMutableArray: (NSMutableArray*) _actionList;
@end



//
// CCSequenceHelper.m
// Created by Jose Antonio Andújar Clavell on 09/02/11.
// Alias "jandujar"
//
// More snippets on http://www.jandujar.com
//
// License http://creativecommons.org/licenses/by/3.0/
//
// Based upon code by daemonk
// http://www.cocos2d-iphone.org/forum/topic/2547
//

#import "CCSequenceHelper.h"


@implementation CCSequenceHelper

+(id) actionMutableArray: (NSMutableArray*) _actionList {
CCFiniteTimeAction *now;
CCFiniteTimeAction *prev = [_actionList objectAtIndex:0];

for (int i = 1 ; i < [_actionList count] ; i++) {
now = [_actionList objectAtIndex:i];
prev = [CCSequence actionOne: prev two: now];
}

return prev;
}

@end


Si os ha sido útil este fragmento de código, os animo a compartirlo. Saludos!!!

jueves, 10 de febrero de 2011

CCMenuItem con Imagen, Texto y tamaño dinámico

Hoy toca ser un poco productivos.

En esta ocasión, he decidido crear una clase para crear botones de menú de tamaño dinámico, que a su vez pueden tener un texto en su interior, con la fuente que se quiera. 

Seguramente no abreis entendido nada de lo que he dicho anteriormente, así que mostraré un video para que veais como funciona.

[yframe url='http://www.youtube.com/watch?v=eX_LKX71hpM&feature=mfu_in_order&list=UL']

Como desarrollador de iphone / ipad en algún momento necesitaras crear botones de menú. Para realizar estos botones, lo que se suele hacer es crear botones con photoshop/gimp de diferentes tamaños/colores. Este proceso (además de ser un engorro), nos acarrea ciertos problemas, ya que si disponemos de muchos botones, podemos quedarnos fácilmente sin memoria, o consumir mucha mas de la necesaria.

Para estos casos, he creado la clase JACDynamicButton que a su vez, utiliza una modificación de la clase Scale9Spriteobtenida del foro de cocos2d

Para este proceso es necesario que tengamos una o varias imagenes de tamaño 64x64 (se podría modificar, pero yo he optado por este tamaño, ya que es múltiplo de 2 y corresponde a una textura válida para iOS) como las siguientes.



A simple vista, puede parecer que es la misma imagen, pero no lo son, una tiene aura y servirá para saber cuando está pulsado el botón.

Mediante estas dos imagenes, podremos crear botones como los siguientes.



Por ejemplo, para realizar estos botones, solo ha sido necesario este fragmento de código.


JACDynamicButton* button1 = [JACDynamicButton itemWithText:@"Hello" font:@"Arial" fontSize:30 minSize:CGSizeMake(100,100) normalImage:@"boton_verde.png" selectedImage:@"boton_verde_sel.png" target:self selector:@selector(doMenu:)];
JACDynamicButton* button2 = [JACDynamicButton itemWithText:@"Hello Large" font:@"Arial" fontSize:30 minSize:CGSizeMake(200,50) normalImage:@"boton_verde.png" selectedImage:@"boton_verde_sel.png" target:self selector:@selector(doMenu:)];


Como podeis observar, se utiliza una fuente Arial con tamaño 30, esto se podría cambiar y se pide el tamaño mínimo del botón (que usualmente será el tamaño del mismo, a menos que la fuente nos obligue a hacer el botón mas grande) 

Y este es el código utilizado.


//
// JACDynamicButton.h
// JACDynamicButton
//
// Created by Jose Antonio Andújar Clavell on 09/02/11.
// Alias "jandujar"
//
// More snippets on http://www.jandujar.com
//
// License http://creativecommons.org/licenses/by/3.0/

#import "cocos2d.h"

@interface JACDynamicButton : CCMenuItemSprite {

}

+(id) itemWithText: (NSString*)text font:(NSString*)f fontSize:(int)fs minSize:(CGSize)ms normalImage:(NSString*)ni selectedImage:(NSString*)si target:(id) t selector:(SEL) s;

@end



//
// JACDynamicButton.m
// JACDynamicButton
//
// Created by Jose Antonio Andújar Clavell on 09/02/11.
// Alias "jandujar"
//
// More snippets on http://www.jandujar.com
//
// License http://creativecommons.org/licenses/by/3.0/

#import "JACDynamicButton.h"
#import "Scale9Sprite.h"

@implementation JACDynamicButton

+(id) itemWithText: (NSString*)text font:(NSString*)f fontSize:(int)fs minSize:(CGSize)ms normalImage:(NSString*)ni selectedImage:(NSString*)si target:(id) t selector:(SEL) s
{
//Create the label
CCLabelTTF *label = [CCLabelTTF labelWithString:text fontName:f fontSize:fs];

//Calculate the Dynamic Button size
int minWidth = label.contentSize.width>ms.width?label.contentSize.width:ms.width;
int minHeight = label.contentSize.height>ms.height?label.contentSize.height:ms.height;

CGSize size=CGSizeMake(minWidth+30,minHeight+24);

[label setPosition:CGPointMake(size.width*0.5, size.height*0.5)];

//Sprite normal
Scale9Sprite *normalSprite = [[[Scale9Sprite alloc] initWithFile:ni centreRegion:CGRectMake(20, 20, 24, 24)] autorelease];
[normalSprite setContentSize:size];

//Sprite selected
Scale9Sprite *selectedSprite = nil;
if(si){
selectedSprite = [[[Scale9Sprite alloc] initWithFile:si centreRegion:CGRectMake(20, 20, 24, 24)] autorelease];
[selectedSprite setContentSize:size];
}

//Create the CCMenuItemSprite
CCMenuItemSprite* returnItem;
returnItem = [self itemFromNormalSprite:normalSprite selectedSprite:selectedSprite target:t selector:s];


[returnItem addChild:label];

NSLog(@"Size = %f %f", returnItem.contentSize.width,returnItem.contentSize.height);

return returnItem;
}


@end

 Por último, comentaros que teneis a vuestra disposición el código fuente de este ejemplo, así como el fichero PSD para que podais modificar el color del botón a vuestro antojo.