• Skip to main content
  • Skip to footer

Programación Multimedia

Diseño Gráfico y Desarrollo Web

  • Inicio
  • Qué hacemos
  • Portafolio
  • Blog
  • Contacto
You are here: Home / iOS / iOS: Sable láser con UIAccelerometer y sonido (III)

iOS: Sable láser con UIAccelerometer y sonido (III)

26 mayo, 2012 Por Raúl Flores Leave a Comment

Detalles del tutorial

  • Tecnología: iOS
  • Dificultad: Nivel medio
  • Tiempo de realización: 45 - 60 minutos

Descargar Proyecto

Comenzamos con la 3ª y última parte del tutorial. Ya tenemos todas las clases necesarias creadas y lo que necesitamos es ir picando un poco de código dentro de ellas para rematar la cuestión. En la 2ª parte habiamos creado la vista SaberOnView que será controlada por SaberOnViewController. SaberOnView ya no necesita más código por lo que nos vamos a meter de lleno con SaberOnViewController.

SaberOnViewController

Vamos a utilizar un patrón de delegación para poder devolver el control a ViewController cuando desaparezca la vista modal SaberOnView mediante un toque del usuario en la pantalla. Presuponemos unos conocimientos básicos de creación de protocolos para este tutorial. Crearemos el protocolo SaberOnViewControllerDelegate y su delegado estará en ViewController. Aquí vamos a tener toda la lógica del desplazamiento del láser y de disparar sonidos y vibración. Los valores de las constantes se pueden variar a gusto, yo les he dado esos valores después de testear bastante.

Cuando apretemos el botón de lanzar el sable ocurrirán las siguientes cosas:

  • Lanzamos la vista modal SaberOnView y se activará de inicio, un sonido constante (pulse) y una vibración será disparada
  • Se activará el acelerómetro y dependiendo de nuestros movimientos en el espacio y la brusquedad de estos, serán lanzados determinados sonidos y vibración algunos de forma aleatoria y otros fija. Además el sable se moverá por el eje X
  • Cuando toquemos la pantalla será disparado un sonido de final y la vista SaberOnView se ocultará y volveremos a la vista inicial

Os dejo el código completo de la clase:


#import <uikit /UIKit.h>
#import <avfoundation /AVFoundation.h>

#import "SaberOnView.h"

@protocol SaberOnViewControllerDelegate;

@interface SaberOnViewController : UIViewController <uiaccelerometerdelegate , AVAudioPlayerDelegate>{

    AVAudioPlayer *pulse;
    AVAudioPlayer *startLaser;
    AVAudioPlayer *stopLaser;
    AVAudioPlayer *pasada1;
    AVAudioPlayer *pasada2;
    AVAudioPlayer *pasada3;
    AVAudioPlayer *pasada4;

    NSMutableArray *saberSoundsArray;
    UIAccelerometer *acelerometro;
    //SaberOnView *saberOnView;

    double min;
    double max;
    double negMin;

}

@property (nonatomic, assign) id <saberonviewcontrollerdelegate> delegate;

@property (nonatomic, strong) SaberOnView *saberOnView;
@property (nonatomic, strong)  NSMutableArray *saberSoundsArray;

- (void) done;
- (void) createSounds;

@end

@protocol SaberOnViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(SaberOnViewController *)controller;
@end


#import "SaberOnViewController.h"
#import <audiotoolbox /AudioToolbox.h>

@implementation SaberOnViewController

@synthesize delegate=_delegate;
@synthesize saberOnView;
@synthesize saberSoundsArray = _saberSoundsArray;

double const kminimum = 0.8;
double const knegativeMinimum = -0.8;
double const kmaximum = 1.3;
double const knegativeMaximum = -1.3;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.saberOnView=nil;
    acelerometro=nil;
    self.saberSoundsArray=nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)loadView {

    UIApplication *thisApp = [UIApplication sharedApplication];
    thisApp.idleTimerDisabled = YES;

	saberOnView = [[SaberOnView alloc] initWithFrame:CGRectZero];
	[saberOnView canBecomeFirstResponder];
	[saberOnView becomeFirstResponder];

    [self createSounds];

    acelerometro = [UIAccelerometer sharedAccelerometer];

    [acelerometro setUpdateInterval:0.0416];

    [acelerometro setDelegate:self];

    //variables del acelerometro
    min=kminimum;
    max=kmaximum;
    negMin=knegativeMinimum;

	NSLog(@"monitoring accelerometer");

	self.view = saberOnView;

    [startLaser play];

    [pulse play];

}

- (void)touchesBegan:(NSSet *)touches
           withEvent:(UIEvent *)event
{
    NSLog(@"stopLaser!!");
    [self done];

}

- (void)done
{
    [acelerometro setDelegate:nil];
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    [pulse stop];

    [stopLaser play];

    UIApplication *thisApp = [UIApplication sharedApplication];
    thisApp.idleTimerDisabled = NO;

    NSLog(@"not monitoring accelerometer");

    [self.delegate flipsideViewControllerDidFinish:self];

}

- (void)accelerometer:(UIAccelerometer *)meter didAccelerate:(UIAcceleration *)accel
{

    saberOnView.xShift = saberOnView.xShift * 0.8 + [accel x] * 20.0;
    NSLog(@"monitoring accelerometer2");

    // Redraw the view
    [self.view setNeedsDisplay];

    if (  accel.x > min && accel.x < kmaximum)

    {

        &#91;pasada1 play&#93;;
        min=accel.x;
        negMin=knegativeMinimum;

    }

    if (  accel.x < negMin && accel.x > knegativeMaximum)

    {

        [pasada2 play];
        negMin=accel.x;
        min=kminimum;
    }

    if (  accel.y > min && accel.y < kmaximum)

    {

        &#91;pasada3 play&#93;;
        min=accel.y;
        negMin=knegativeMinimum;
        max=kmaximum;
    }

    if (  accel.y < negMin && accel.y > knegativeMaximum)

    {

        [pasada4 play];
        negMin=accel.y;
        min=kminimum;
    }

    if (  accel.y > max)

    {
        int randomHit = 7 + arc4random() % 7;
        //NSLog(@"randomHit:%i",randomHit);

        [(AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:randomHit]    play] ;
        max=accel.y;

        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

    }

    //NSLog(@"accel.x:%f",accel.x);
    //NSLog(@"accel.y:%f",accel.y);
    //NSLog(@"accel.z:%f",accel.z);

}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

}

-(void) createSounds
{

    //sonido constante*************************
    pulse = (AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:0];

    pulse.numberOfLoops=-1;
    pulse.delegate=self;

    //sonido entrada*************************

    startLaser=(AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:1];

    //sonido salida*************************
    stopLaser = (AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:2];

    //sonido pasada1*************************

    pasada1 = (AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:3];

    //sonido pasada2*************************
    pasada2 = (AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:4];

    //sonido pasada3*************************

    pasada3 = (AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:5];

    //sonido pasada4*************************

    pasada4 = (AVAudioPlayer *)[self.saberSoundsArray objectAtIndex:6];

}

-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
    //NSLog(@"audioPlayerBeginInterruption");
    [pulse stop];

}
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player
{
    //NSLog(@"audioPlayerEndInterruption");
    [pulse play];
}

@end

ViewController

Para concluir vamos a añadir la delegación a esta clase con lo cual añadiremos el protocolo SaberOnViewControllerDelegate a ViewController, asignaremos como delegado de SaberOnViewController a ViewController e implementaremos el método flipsideViewControllerDidFinish.

@interface ViewController : UIViewController <saberonviewcontrollerdelegate>{

ViewController.m quedará de la siguiente forma:


#import "ViewController.h"

@implementation ViewController
@synthesize saberSoundsArray=_saberSoundsArray;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.saberSoundsArray = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)startLaser:(id)sender {

    //vibración
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

    SaberOnViewController *controller = [[SaberOnViewController alloc] init];

    [controller setDelegate:self];

    [controller setSaberSoundsArray: _saberSoundsArray];

    [self presentModalViewController:controller animated:YES];

}

- (void)flipsideViewControllerDidFinish:(SaberOnViewController *)controller
{
    [self dismissModalViewControllerAnimated:YES];

}

@end

Conclusión

Supongo que a estas alturas ya habeis compilado en vuestro dispositivo y vereis que cumple dignamente, pero hay muchas otras cosas que se pueden hacer… Tampoco creo que ésta sea la única o mejor forma de hacerlo ni nada parecido, es simplemente una forma más que espero os pueda servir de base para otros proyectos.
Espero os haya gustado, podeis descargar el proyecto completo de Xcode:

Descargar Proyecto

Filed Under: iOS Tagged With: acelerómetro, ARC, sonidos, vibración

En el blog

La Edad de Oro del software español

Esta vez quiero comentar la reciente publicación del volumen 2 del fabuloso libro Ocho Quilates. Una historia de la Edad … [Leer más...] about La Edad de Oro del software español

CSS3: Añadir borde a una tipografía

Buscando la forma de crear un borde para algún titular de esta web, sin tener que hacerlo vía imagen/Photoshop, me … [Leer más...] about CSS3: Añadir borde a una tipografía

tutorial ios tabla personalizada

iOS: Crear vista de tabla personalizada sin usar UITableView

Muchas veces queremos crear una vista de tabla usando UITableView y a la hora de personalizarla nos encontramos con … [Leer más...] about iOS: Crear vista de tabla personalizada sin usar UITableView

Ayúdanos a difundir

Si te ha parecido útil esta información, por favor compártela en las redes sociales.

Reader Interactions

Deja un comentario Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Footer

Desarrollo Web
hazte visible

DA EL PRIMER PASO

Diseño web programacion multimedia

Copyright 2012 | www.programacionmultimedia.net | Raúl Flores