Как анимировать изображение на эффект встряхивания? - PullRequest
2 голосов
/ 17 декабря 2009

Я реализовал игровое приложение. В котором я хочу анимировать некоторые области изображений на эффект встряхивания. Как это возможно, пожалуйста, дайте мне совет.

Edit: Мой точный запрос таков: В моем игровом приложении есть одно изображение. Теперь я выбрал некоторую область кадра изображения. Теперь я трясу iphone, тогда только выбранная область изображения кадра должна быть анимированной.

Ответы [ 2 ]

2 голосов
/ 19 декабря 2009

Вот скелет ... тогда вы можете получить более подробную информацию в предлагаемых документах. Это очень просто, но имеет рандомизацию, и вы можете создать экземпляр со своим собственным изображением. Я создал контейнер изображений как UIViewController, и в моем основном (или ваш AppDelegate или RootViewController) вы создаете экземпляр в viewDidLoad. Методы, которые должны быть перегружены в вашем AppDelegate (код находится в конце поста), чтобы он получал сотрясения, являются:

  • viewWillAppear
  • viewDidAppear
  • viewWillDisappear
  • viewDidDisappear
  • canBecomeFirstResponder
  • becomeFirstResponder
  • nextResponder

Вы становитесь респондентом в viewWillAppear, и вам нужно включить уведомления устройства (подтверждено, что есть задокументированная ошибка), чтобы вызывать методы движения.

  • motionBegan: withEvent
  • motionEnded: withEvent

Мне нравится ставить NSLog (@ "% s", FUNCTION ); утверждение во всех моих впервые написанных методах, таким образом я могу быстро определить, что чего-то не хватает, чтобы получить мои события, правильно инициализировать и т. д. Это просто мой стиль.

AnimatedImage.h isA ViewController

    @interface AnimatedImage : UIViewController {

    UIImageView     *image;
    UILabel         *label;

    float cx;
    float cy;
    float duration;
    float repeat;


}

@property (nonatomic, retain) UIImageView *image;
@property (nonatomic, retain) UILabel *label;

-(id) initWithImageName: (NSString*) imageName;

-(IBAction) shake;

AnimatedImage.m

    #include <stdlib.h>
#define random() (arc4random() % ((unsigned)RAND_MAX + 1))

#import "AnimatedImage.h"


@implementation AnimatedImage

@synthesize image;
@synthesize label;


-(id) initWithImageName: (NSString*) imageName {
    NSLog(@"%s", __FUNCTION__);

    image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];

    return self;             
}


-(IBAction) shake {

    cx = 0.90 + (random() % 10) / 100; // cx = 0.95;
    cy = 0.90 + (random() % 10) / 100; // cy = 0.95;
    duration = ( 5.0 + random() % 10) / 1000.0;
    repeat   = (65.0 + random() % 20); 

    image.transform = CGAffineTransformScale(CGAffineTransformIdentity, cx, cy);

    [UIView beginAnimations: @"identifier" context: @"shake"];
    [UIView setAnimationDelegate:image.superclass];
    [UIView setAnimationDuration: duration]; // 0.008];
    [UIView setAnimationRepeatCount: repeat]; // 85.0];
    [UIView setAnimationRepeatAutoreverses: YES];

    image.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);

    [UIView commitAnimations];
}


-(IBAction) bounce {

    image.transform = CGAffineTransformTranslate(image.transform, -20, -6);

    [UIView beginAnimations: @"identifier" context: @"bounce"];
    [UIView setAnimationDelegate:image.superclass];
    [UIView setAnimationDuration: duration];
    [UIView setAnimationRepeatCount: repeat];
    [UIView setAnimationRepeatAutoreverses: YES];

    image.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);

    [UIView commitAnimations];
}


@end

Этот «корневой или главный» делегат является UIViewController. Я оставил детали, чтобы показать его простоту, но все же оставил свой «трассировочный» код, который я считаю необходимым для первоначальной отладки. Кроме того, в качестве отступления, я считаю, что необходимо перегрузить motionBegan, даже если вам нужно только событие motionEnded. Я помню, что мое приложение не работало, а затем я добавил motionBegan, и он начал вызывать motionEnded. Это вроде «имеет смысл, что так будет, но у меня нет документации, подтверждающей это. Простой эксперимент после того, как вы его заработаете, может подтвердить или опровергнуть мой комментарий.

- (void)viewDidLoad {
    [super viewDidLoad];
    [super becomeFirstResponder];
    .
    .
    .
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"%s: I %s first responder! (%@)", __FUNCTION__, [self isFirstResponder] ? "am" : "am not", self);
    .
    .<created image in this ViewController's NIB using IB>
    .
    someImage   = (UIImageView *) [self.view viewWithTag:TAG_SOMEIMAGE];
    aniImage = [[AnimatedImage alloc] init];
    aniImage.image = someImage;
}


-(void) viewWillAppear: (BOOL) animated{
    NSLog(@"%s", __FUNCTION__);
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver: self 
                                             selector: @selector(receivedRotate:) 
                                                 name: UIDeviceOrientationDidChangeNotification 
                                               object: nil];
}



- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"%s", __FUNCTION__);
    [super becomeFirstResponder];
    assert( [self canPerformAction:@selector(motionEnded:withEvent:) withSender:self] ); 
}


- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"%s", __FUNCTION__);
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver: self];
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"%s", __FUNCTION__);

    [super resignFirstResponder];
}


- (BOOL)canBecomeFirstResponder {
    NSLog(@"%s", __FUNCTION__);
    return YES;
}

- (BOOL)becomeFirstResponder {
    NSLog(@"%s", __FUNCTION__);
    return YES;
}

- (UIResponder *)nextResponder {
    NSLog(@"%s", __FUNCTION__);

    return [self.view superview];
}

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    NSLog(@"%s", __FUNCTION__); 
}

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    NSLog(@"%s", __FUNCTION__);

    if( [self isFirstResponder] ) {
        [aniImage shake];
    }
}

Этот код работает, но если я вычеркнул слишком много деталей, просто спросите, и я обязательно добавлю достаточно, чтобы помочь вам в этом. Это было действительно полезным для меня заданием, и я с радостью делюсь им с кем-то, кто ищет помощь в этом же опыте.

0 голосов
/ 18 декабря 2009

Посмотрите на пример кода LocateMe, один из первых примеров в SDK, и используйте и измените отскок обратно на центральный код.

...