Pregunta

Tengo clase UIView subclase de una clase de rebote con el acelerómetro. Esta clase de rebote mostrar una imagen y se mueven en la pantalla. Cuando el dispositivo iPhone se mueve, esta imagen de rebote en la pantalla.

Cuando creo instancia múltiple, solamente última instancia properlty trabajo:

// in the MainViewController.m

Bounce *heart[100];


for(int i = 0; i < 10; i++) {
    rx = (arc4random() % 300) + 10;
    ry = (arc4random() % 300) + 10;
    NSLog(@"random %d %d", rx, ry);
    heart[i] = [[Bounce alloc] initWithPNG:@"Heart.png" 
                       position:CGPointMake(rx, ry) size:CGSizeMake(64, 64)];
    heart[i].velocity = CGPointMake(1.0, 1.0);
    [self.view addSubview: heart[i]];
}

Esta es la clase de rebote:

//
//  Bounce.h
//  iMakeLove
//
//  Created by Giovambattista Fazioli on 06/11/09.
//  Copyright 2009 Saidmade srl. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface Bounce : UIView <UIAccelerometerDelegate> {

    CGPoint     position;
    CGSize      size;
    CGPoint     velocity;
    NSTimer     *objTimer;
    NSString    *pngName;
    CGFloat     bounce;
    CGFloat     gravity;
    CGPoint     acceleratedGravity;
    CGPoint     lastTouch;
    CGPoint     currentTouch;
    BOOL        dragging;

    UIAccelerometer *accelerometer;

}



@property CGPoint position;
@property CGSize size;
@property CGPoint velocity;
@property(nonatomic,retain)NSString *pngName;
@property(nonatomic,retain)NSTimer *objTimer;
@property CGFloat bounce;
@property CGFloat gravity;
@property CGPoint acceleratedGravity;
@property CGPoint lastTouch;
@property CGPoint currentTouch;
@property BOOL dragging;

- (id)initWithPNG:(NSString*)imageName position:(CGPoint)p size:(CGSize)s;

- (void)update;
- (void)onTimer;
- (void)startPrevent;

@end

Implementación:

//
//  Bounce.m
//  iMakeLove
//
//  Created by Giovambattista Fazioli on 06/11/09.
//  Copyright 2009 Saidmade srl. All rights reserved.
//

#import "Bounce.h"

@implementation Bounce

@synthesize position, size;
@synthesize objTimer;
@synthesize velocity;
@synthesize pngName;
@synthesize bounce;
@synthesize gravity, acceleratedGravity;
@synthesize lastTouch, currentTouch;
@synthesize dragging;



- (id)initWithPNG:(NSString*)imageName position:(CGPoint)p size:(CGSize)s {

    if (self = [super initWithFrame:CGRectMake(p.x, p.y, s.width, s.height)]) {

        [self setPngName:imageName];
        [self setPosition:p];
        [self setSize:s];
        [self setBackgroundColor:[UIColor clearColor]];

        // Set default gravity and bounce

        [self setBounce:-0.9f];
        [self setGravity:0.5f];
        [self setAcceleratedGravity:CGPointMake(0.0, gravity)];
        [self setDragging:NO];

        UIImageView *prezzie = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, s.width, s.height)];

        prezzie.image = [UIImage imageNamed:imageName];

        [self addSubview:prezzie];

        [prezzie release];

        self.accelerometer = [UIAccelerometer sharedAccelerometer];
        self.accelerometer.delegate = self;

    }
    return self;
}

- (void)startPrevent {
    if (objTimer == nil) {
        objTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
    }
}


- (void)update {

    [self setNeedsDisplay];

    if(dragging) return;

    velocity.x += acceleratedGravity.x;
    velocity.y += acceleratedGravity.y;
    position.x += velocity.x;
    position.y += velocity.y;

    if(position.x + size.width >= 320.0) {
        position.x = 320.0 - size.width;
        velocity.x *= bounce;
    } else if(position.x <= 0.0) {
        velocity.x *= bounce;
    }

    if(position.y + size.height >= 480.0) {
        position.y = 480.0 - size.height;
        velocity.y *= bounce;
    } else if(position.y <= 0.0) {
        velocity.y *= bounce;
    }
    self.frame = CGRectMake(position.x, position.y, size.width, size.height);
}



- (void)onTimer {
    [self update];
}



- (void)drawRect:(CGRect)rect {

    // Drawing code

}

/* EVENTS */


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    acceleratedGravity.x = acceleration.x * gravity;
    acceleratedGravity.y = -acceleration.y * gravity;
}



- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    // First, lets check to make sure the timer has been initiated

    if (objTimer == nil) {
        objTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
    }

    UITouch *touch = [touches anyObject];

    [self setCurrentTouch:[touch locationInView:self]];
    CGFloat dx = currentTouch.x - position.x;
    CGFloat dy = currentTouch.y - position.y;
    CGFloat dist = sqrt(dx * dx + dy * dy);

    if(dist < size.width) {
        [self setVelocity:CGPointMake(0.0, 0.0)];
        [self setDragging:YES];
    }
    [self setLastTouch:currentTouch];

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    [self setCurrentTouch:[touch locationInView:self]];
    [self setDragging:YES];
    [self setVelocity:CGPointMake(currentTouch.x - lastTouch.x, currentTouch.y - lastTouch.y)];
    [self setLastTouch:currentTouch];

}



- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [self setDragging:NO];
}





- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Initialization code
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}


@end

¿Me puede ayudar?

¿Fue útil?

Solución

Esto se debe a self.accelerometer.delegate = self; es cambiar el delegado del sharedAccelerometer y sólo la última asignación tendrá efecto.

Otros consejos

Creo que sólo la más frontal vista obtendrá los mensajes del acelerómetro. Es posible que desee los mensajes acelerómetro para ser enviados a su viewcontroller lugar.

Lo que podría hacer aquí. (Puede que no sea lo mejor a largo plazo, pero se solucionará el problema inmediato) es la siguiente:

Me gustaría hacer la gravedad acelerado una variable estática compartida entre todas las instancias de rebote. Esto hace que el SENCE para mí, porque en el mundo real (el que estamos simulando) Accelerated gravedad sería la misma para todos los rebotes. (También me cambio el nombre de rebote a algo así como BouncingView). Me acceder a esa variable a través de un par de métodos de clase. Además, me gustaría hacer el acelerómetro compartida, y tienen su método delegado, un método de clase. Poner esto en su clase y que debería funcionar:. (. Que había prueba, pero mi máquina de desarrollo se encuentra en la tienda de Apple consiguiendo fija) Además, hay un par de errores de sintaxis en el código de ejemplo informados

  static CGCGPoint acceleratedGravity;
  static UIAccelerometer *accelerometer;

    -(void) init {
        /* Everything Else */
        self.accelerometer = [UIAccelerometer sharedAccelerometer];
        self.accelerometer.delegate = self;
        /*Everything Else */
    }

    +(CGPoint) acceleratedGravity {
        return acceleratedGravity;
    }

    +(void) setAcceleratedGravity:(CGPoint) _acceleratedGravity {
        acceleratedGravity = _acceleratedGravity;
    }

+ (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    acceleratedGravity.x = acceleration.x * gravity;
    acceleratedGravity.y = -acceleration.y * gravity;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top