您现在的位置是:首页 > 文章详情

《iOS 6高级开发手册(第4版)》——1.8节使用加速度移动屏幕上的对象

日期:2017-05-01点击:272

本节书摘来自异步社区《iOS 6高级开发手册(第4版)》一书中的第1章,第1.8节使用加速度移动屏幕上的对象,作者 【美】Erica Sadun,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.8 使用加速度移动屏幕上的对象
iOS 6高级开发手册(第4版)
借助一点编程工作,iPhone的机载加速计就可以使对象在屏幕上四处“移动”,实时响应用户倾斜手机的方式。秘诀1-4创建了一只动画式的蝴蝶,用户可以使之快速移过屏幕。

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

只要力的方向仍然保持相同,蝴蝶就会加速。它的速度会依据加速力在x或y方向上的量度成比例地提高。
由计时器调用的tick例程将通过向蝴蝶的原点添加速度向量来移动蝴蝶。
蝴蝶移动的范围是有界限的。因此,当它撞到某个边缘时,将会停止在那个方向上移动。这可以一直把蝴蝶保留在屏幕上。tick方法将会检查界限条件。例如,如果蝴蝶撞到垂直边缘,那它仍然可以在水平方向上移动。
蝴蝶会改变它自身的方向,使之总是“下落”。可以在tick方法中应用一个简单的旋转变换来实现这一点。在使用变换时,还要关注画面或中心偏移。在应用偏移之前,总是要重置数学处理,然后重新应用任何角度改变。不这样做的话,可能导致画面出人意料地放大、收缩或扭曲。
注意:

{计时器在自然状态下不会处理块。如果你愿意使用基于块的设计,可以查询github,找到它的解决办法。} 秘诀1-4 基于加速计的反馈移动屏幕上的对象

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { // Extract the acceleration components float xx = -acceleration.x; float yy = acceleration.y; // Store the most recent angular offset 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; } - (void) tick { // Reset the transform before changing position 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; // Rotate the butterfly independently of position butterfly.transform = CGAffineTransformMakeRotation(mostRecentAngle + M_PI_2); } - (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]; }

获取这个秘诀的代码
{要查找这个秘诀的完整示例项目,可以浏览https://github.com/erica/iOS-6-Advanced-Cookbook,并进入第1章的文件夹。}

获取这个秘诀的代码

要查找这个秘诀的完整示例项目,可以浏览 https://github.com/erica/iOS-6-Advanced-Cookbook , 并进入第 1 章的文件夹。

原文链接:https://yq.aliyun.com/articles/97344
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章