UIAccelerometer Sample Code
Vamos a ver en este ejemplo como utilizar los acelerometros que trae el iPhone para detectar la inclinación del mismo.
Crear un Proyecto OpenGL
Como siempre vamos a empezar desde 0 y es creando un proyecto en OpenGL Es, abrimos el XCode vamos a File > New Proyect y seleccionamos un proyecto “OpenGL ES Application“, pulsamos el botón choose y le damos el nombre que nos interese:
Nuestra Clase GL
Por ahora no vamos a aportar nada nuevo a nuestra clase GL para dibujar sprites, asi que os toca copiar los pasos que ya hicimos en nuestro capitulo Sprites en OpenGL os recuerdo que ahi solamente vamos a definir la clase GL.m vamos a agregar el Framework CoreGraphics.Framework, y vamos a añadir un nuevo archivo grafico a los resources del proyecto.
También deberemos copiar todas las modificaciones que hicimos a la clase EAGLView.m, los metodos inicializar, setupView, clearBuffer y swapBuffer que agregamos.
Implementando UIAcclerometer
Ahora viene la finalidad del proyecto … y realmente lo facil, enseguida veréis que no tiene ninguna dificultad:
Vamos a EAGLView.h
y dentro de la interfaz, añadimos estas variables:
| C | | copy code | | ? |
| 1 | |
| 2 | GLuint texture; |
| 3 | GLfloat angle; |
| 4 | GLfloat angle2; |
| 5 | UILabel *label1, *label2, *label3; |
Por un lado vemos que tenemos la textura que vamos a usar, un par de variables para guardar un angulo … y vemos 3 lables. Estas labels serán para poner texto en pantalla, algo que se sale un poco de la finalidad del ejemplo pero que es muy facil de implementar y nos ayudará a ver que está pasando realmente.
Ademas, que vamos a añadir estas Labels al proyecto sin pasar por el InterfaceBuilder, las ponemos a pelo, como los hombres de verdad
Seguimos en EAGLView.h y añadimos (ya fuera de la interfaz) estos métodos:
| C | | copy code | | ? |
| 1 | |
| 2 | -(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration ; |
| 3 | -(UILabel *) newLabelWithOffset:(float)offset numberOfLines:(NSUInteger) lines; |
Y ya está, por aqui todo está listo.
Abrimos el archivo EAGLView.m
En primer lugar vamos a ver como se implementan las labels, para ello tenemos el método newLabelWithOffset que crea una label en la posición indicada:
| C | | copy code | | ? |
| 01 | |
| 02 | -(UILabel *) newLabelWithOffset:(float)offset numberOfLines:(NSUInteger) lines |
| 03 | { |
| 04 | float textHeight = 20.0; |
| 05 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.origin.x + 10.0, offset, self.frame.size.width - 20.0, textHeight * lines)]; |
| 06 | |
| 07 | // Set the font size, text color, background color, and alignment. |
| 08 | label.font = [UIFont systemFontOfSize:18.0]; |
| 09 | label.textColor = [UIColor lightTextColor]; |
| 10 | label.backgroundColor = [UIColor clearColor]; |
| 11 | label.textAlignment = UITextAlignmentLeft; |
| 12 | |
| 13 | // Set the number of lines |
| 14 | label.numberOfLines = lines; |
| 15 | // Set the linebreak mode if there is more than one line. |
| 16 | if (lines > 1) label.lineBreakMode = UILineBreakModeWordWrap; |
| 17 | |
| 18 | // Initialize as an empty string |
| 19 | label.text = @""; |
| 20 | return label; |
| 21 | } |
y dentro de nuestro metodo ‘initWithCoder‘ crearemos las 3 labels asi:
| C | | copy code | | ? |
| 01 | |
| 02 | label1 = [self newLabelWithOffset:(self.frame.origin.y + 25) numberOfLines: 1]; |
| 03 | label1.text = @"Acceleration.x"; |
| 04 | [self addSubview:label1]; |
| 05 | |
| 06 | label2 = [self newLabelWithOffset:(self.frame.origin.y + 45) numberOfLines: 1]; |
| 07 | label2.text = @"Acceleration.y"; |
| 08 | [self addSubview:label2]; |
| 09 | |
| 10 | label3 = [self newLabelWithOffset:(self.frame.origin.y + 65) numberOfLines: 1]; |
| 11 | label3.text = @"Angulo"; |
| 12 | [self addSubview:label3]; |
UIAccelerometer
Aqui teneis todo el codigo necesario, en nuestro metodo inicializar inicializamos el acelerometro diciendole que delege sus eventos sobre esta clase, y debajo tenemos el metodo accelerometer implementado que es quien recibe los eventos.
| C | | copy code | | ? |
| 01 | |
| 02 | -(void)inicializar |
| 03 | { |
| 04 | // Cargamos la unica textura que vamos a usar |
| 05 | texture1 = [GL loadTexture:@"4Sprites.png"]; |
| 06 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 07 | |
| 08 | // Configure and start the accelerometer |
| 09 | [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 30)]; |
| 10 | [[UIAccelerometer sharedAccelerometer] setDelegate:self]; |
| 11 | |
| 12 | } |
| 13 | |
| 14 | - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration |
| 15 | { |
| 16 | float x = acceleration.x; |
| 17 | float y = acceleration.y; |
| 18 | |
| 19 | angle = atan2(y, x); |
| 20 | angle *= 180.0/3.14159; |
| 21 | angle += 90; |
| 22 | |
| 23 | label1.text = [NSString stringWithFormat:@"Acceleration.x = %4.4f ", x]; |
| 24 | label2.text = [NSString stringWithFormat:@"Acceleration.y = %4.4f ", y]; |
| 25 | label3.text = [NSString stringWithFormat:@"Angulo = %4.1f ",angle]; |
| 26 | |
| 27 | float dif = angle2 - angle; |
| 28 | if(abs(dif)>180) dif+= 360; |
| 29 | angle2 -= dif * 0.5f; |
| 30 | |
| 31 | } |
En este método acceleratometer podéis ver como sacamos los valores X e Y de aceleración.. que realmente nos indican el coseno y el seno de la inclinación del dispositivo, y mediante un atan sabemos el angulo de inclinación … sólo son matemáticas.
Podéis ver como se meten estos valores en las 3 labels para poder verlos en pantalla, veréis como tanto x como y representan valores comprendidos entre 1 y -1 (propios del seno y coseno unitario de toda la vida).
Bueno a lo que vamos si os fijáis bien tengo una segunda variable llamada angle2 que no es mas que una interpolacion del angulo actual con el angulo anterior (queeee???) … si eso, los acerelometros tienen bastante variación, aunque dejemos el dispositivo quiero están fluctuando a lo loco .. y esto hace que el angulo no quede estable, mediante esta segunda variable solo intentamos suavizar esos cambios bruscos. El efecto es visible así que esperar a ejecutar y lo comprenderéis mejor.
Porque solo nos queda nuestro metodo draw!!!!
| C | | copy code | | ? |
| 01 | |
| 02 | - (void)drawView |
| 03 | { |
| 04 | [self clearBuffer]; |
| 05 | glLoadIdentity(); |
| 06 | |
| 07 | glPushMatrix(); |
| 08 | [GL setSprite:texture1 frame:0]; |
| 09 | glTranslatef(-80,0,0); |
| 10 | glRotatef(-angle,0,0,1); |
| 11 | [GL drawSprite:-64 y1:-64 x2:64 y2:64]; |
| 12 | glPopMatrix(); |
| 13 | |
| 14 | glPushMatrix(); |
| 15 | [GL setSprite:texture1 frame:3]; |
| 16 | glTranslatef(80,0,0); |
| 17 | glRotatef(-angle2,0,0,1); |
| 18 | [GL drawSprite:-64 y1:-64 x2:64 y2:64]; |
| 19 | glPopMatrix(); |
| 20 | |
| 21 | [self swapBuffer]; |
| 22 | } |
Aquí podemos ver como dibujamos 2 sprites en pantalla, uno usando el angle que va un poco a lo loco, y otro mediante angle2, podéis girar el dispositivo y veréis como los 2 van juntitos … pero que nuestro sprite de la derecha parece mas cuerdo que el otro.



frocco on May 4th, 2009
Buenas!
No tenes el .zip del proyecto????
Estoy aprendiendo OpenGL para Iphone y todavia me hace falta seguimiento
Abrazo grande y muy bueno el blog!!!