Frage

Ich habe die UIView -Unterklasse in einer Bounce -Klasse mit Beschleunigungsmesser. Diese Bounce -Klasse zeigt ein Bild an und verschiebt es auf dem Bildschirm. Wenn das iPhone -Gerät verschoben wird, springt dieses Bild auf dem Bildschirm.

Wenn ich mehrere Instanz erstelle, funktionieren nur die letzte Instanz richtig:

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

Dies ist die Bounce -Klasse:

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

Implementierung:

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

Kannst du mir helfen?

War es hilfreich?

Lösung

Das ist, weil self.accelerometer.delegate = self; ändert die sharedAccelerometer'S -Delegierter und nur die letzte Zuordnung hat einen Effekt.

Andere Tipps

Ich glaube, dass nur die vorderste Sicht die Beschleunigungsnachrichten erhalten. Möglicherweise möchten Sie, dass die Accelrometer -Nachrichten stattdessen an Ihren ViewController gesendet werden.

Was ich hier tun könnte. (Es ist vielleicht nicht das Beste, was langfristig das Beste ist, aber das unmittelbare Problem behebt) ist Folgendes:

Ich würde beschleunigte Schwerkraft zu einer statischen Variablen machen, die unter allen Fällen von Sprung geteilt wurde. Dies macht für mich zu, weil in der realen Welt (die, die wir simulieren) beschleunigte Schwerkraft für alle Hüpfer gleich wäre. (Ich würde Bounce auch in so etwas wie BouncingView umbenennen). Ich würde über einige Klassenmethoden auf diese Variable zugreifen. Außerdem würde ich das Beschleunigungsmesser gemeinsam genutzt und seine Delegate -Methode, eine Klassenmethode, haben. Setzen Sie dieses Zeug in Ihre Klasse und es sollte funktionieren: (Ich würde es testen, aber mein Entwicklungsgerät ist im Apple Store repariert.) Außerdem gibt es einige Syntaxfehler in dem von Ihnen geposteten Beispielcode.

  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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top