IOS 特定于设备的开发:使用加速器启动屏幕上的对象

借助一点编程工作,iPhone的机载加速计就可以使对象在屏幕上四处“移动”,实时响应用户倾斜手机的方式。下面的代码就是创建一个动画式的蝴蝶,用户可以使之快速移过屏幕。

使之工作的秘密在于:向程序中添加一个所谓的"物理计时器“。他不是直接响应加速中的变化,而是加速计回调用于测量当前的力。它取决于计时器例程随着 时间的推移通过改变他的画面对蝴蝶应用那些力。下面是列出要记住的关键点。

   (1).只要力的方向仍然保持相同,蝴蝶就会加速。他的速度会依据加速力在x或y方向上的量度成比例的提高。

   (2).由计时器用的rick例程将通过蝴蝶的原点添加速度向量来移动蝴蝶。

   (3).蝴蝶移动的范围是有界限的,因此,当他撞到某个边缘时,将会停止那个方向的移动。还可以一直讲蝴蝶保留在屏幕中。tick方法将会检查界限条件。

   (4).蝴蝶会改变它自身的方向,使之总是下落。可以在tick方法中应用一个简单的旋转变换来实现这一点。在使用变换时,还要关注画面或中心偏移。在应用偏移之前,总是要重置数学处理,然后重新应用任何角度改变。不这样的话,可能导致画面出人意料的放大,收缩或扭曲。

代码如下:

#define SIGN(_NUM_) ((_NUM_ < 0) ? (-1) : 1)

#define RECTCENTER(RECT) CGPointMake(CGRectGetMidX(RECT), CGRectGetMidY(RECT))



@interface ViewController ()

{

    UIImageView *butterfly;

    

    float xaccel;

    float xvelocity;

    float yaccel;

    float yvelocity;

    

    float mostRecentAngle;

}



@end



@implementation ViewController



- (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor greenColor];

    [self initButterfly];

    }





- (void) initButterfly

{

    CGSize size;

    

    // Load the animation cells

    NSMutableArray *butterflies = [NSMutableArray array];

    for (int i = 1; i <= 17; i++)

    {

        NSString *fileName = [NSString stringWithFormat:@"bf_%d.png", i];

        UIImage *image = [UIImage imageNamed:fileName];

        size = image.size;

        [butterflies addObject:image];

    }

    

    // Begin the animation

    butterfly = [[UIImageView alloc] initWithFrame:(CGRect){.size=size}];

    [butterfly setAnimationImages:butterflies];

    butterfly.animationDuration = 0.75f;

    [butterfly startAnimating];

    

    // Set the butterfly's initial speed and acceleration

    xaccel = 2.0f;

    yaccel = 2.0f;

    xvelocity = 0.0f;

    yvelocity = 0.0f;

    

    // Add the butterfly

    butterfly.center = RECTCENTER(self.view.bounds);

    [self.view addSubview:butterfly];

    

    

    // Activate the accelerometer

    [[UIAccelerometer sharedAccelerometer] setDelegate:self];

    

    // Start the physics timer

    [NSTimer scheduledTimerWithTimeInterval: 0.03f target: self selector: @selector(tick) userInfo: nil repeats: YES];

}



- (void) tick

{

    butterfly.transform = CGAffineTransformIdentity;

    

    // Move the butterfly according to the current velocity vector

    CGRect rect = CGRectOffset(butterfly.frame, xvelocity, 0.0f);

    if (CGRectContainsRect(self.view.bounds, rect))

        butterfly.frame = rect;

    

    rect = CGRectOffset(butterfly.frame, 0.0f, yvelocity);

    if (CGRectContainsRect(self.view.bounds, rect))

        butterfly.frame = rect;

    

    butterfly.transform = CGAffineTransformMakeRotation(mostRecentAngle + M_PI_2);

}



- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration

{

    // extract the acceleration components

    float xx = -acceleration.x;

    float yy = acceleration.y;

    mostRecentAngle = atan2(yy, xx);

    

    // Has the direction changed?

    float accelDirX = SIGN(xvelocity) * -1.0f;

    float newDirX = SIGN(xx);

    float accelDirY = SIGN(yvelocity) * -1.0f;

    float newDirY = SIGN(yy);

    

    // Accelerate. To increase viscosity lower the additive value

    if (accelDirX == newDirX) xaccel = (abs(xaccel) + 0.85f) * SIGN(xaccel);

    if (accelDirY == newDirY) yaccel = (abs(yaccel) + 0.85f) * SIGN(yaccel);

    

    // Apply acceleration changes to the current velocity

    xvelocity = -xaccel * xx;

    yvelocity = -yaccel * yy;

}

 

你可能感兴趣的:(ios)