2009-11-07 3 views
1

J'ai une classe UIView de sous-classe dans une classe Bounce avec un accéléromètre. Cette classe Bounce affiche une image et la déplace sur l'écran. Lorsque l'appareil iPhone est déplacé, cette image rebondit sur l'écran.L'instance multiple d'UIView ne fonctionne pas

Lorsque je crée plusieurs instances, que le travail dernière instance properlty:

// 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]]; 
} 

C'est la classe Bounce:

// 
// 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 

Mise en œuvre:

// 
// 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 

Pouvez-vous me aider?

+0

Détails ... Que se passe-t-il? Qu'est-ce qui ne va pas? Qu'est-ce qui ne fonctionne pas? – marcc

+0

Si vous faites 10 instances, elles s'affichent à l'écran mais seule la dernière instance de Bounce fonctionne correctement avec Accelerometer. – Undolog

+0

Bounce.m? iMakeLove? Je peux voir le rejet de l'application à partir d'ici :) –

Répondre

2

En effet, self.accelerometer.delegate = self; modifie le délégué de sharedAccelerometer et seule la dernière affectation aura un effet.

0

Je crois que seule la vue la plus en avant recevra les messages de l'accéléromètre. Vous pourriez vouloir que les messages de l'accéléromètre soient envoyés à votre viewcontroller à la place.

+0

Très bonne idée ... merci ... – Undolog

0

Ce que je pourrais faire ici. (Il ne peut pas être la meilleure chose à long terme, mais va résoudre le problème immédiat) est la suivante:

Je ferais de la gravité accélérée une variable statique partagée entre toutes les instances de Bounce. Cela me fait du sens parce que dans le monde réel (celui que nous simulons), la gravité accélérée serait la même pour tous les rebonds. (Je renommerais aussi Bounce à quelque chose comme BouncingView). J'accéderais à cette variable grâce à deux méthodes de classe. De plus, je ferais en sorte que l'accéléromètre soit partagé et que sa méthode de délégation soit une méthode de classe. Mettez ce truc dans votre classe et cela devrait fonctionner: (Je le testerais mais mon machine de développement est à l'Apple Store corrigé). Il y a aussi quelques erreurs de syntaxe dans l'exemple de code que vous avez posté.

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; 
} 
+0

le + dans la méthode délégué va le déplacer de la portée de l'instance à la portée de la classe. –

+0

Merci ... Erreur de syntaxe où? – Undolog

+0

Rien Major, rx et ry n'ont pas été effacés dans la boucle for du contrôleur de la vue principale. (au moins pas dans l'extrait) et dans la classe Bounce vous utilisez self.accelerometer dans l'implémentation, mais vous n'avez pas de déclaration de propriété (seulement la variable) dans l'en-tête et pas de @synthisize. Avez-vous pu régler votre problème d'accéléromètre? –