描述:用CoreMontion加速计控制小球的运动,通过屏幕触摸,暂停和恢复。
步骤
1. 添加MontionManager和CADisplayLink
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 |
- (void)viewDidLoad{ [super
viewDidLoad]; // 添加小球 UIImage *image = [UIImage imageNamed:@"black"]; _ball = [[UIImageView alloc] initWithImage:image]; _ball.center = self.view.center; [self.view addSubview:_ball]; _ballVelocity = CGPointZero; _queue = [[NSOperationQueue
alloc] init]; // 运动管理器方法 // 1) 实例化运动管理器MyMontionManager *montionManager = [MyMontionManager sharedMyMontionManager]; // 2) 判断加速计是否可用 if
(montionManager.isAccelerometerAvailable) { // 3) 设置采样数据的时间间隔 montionManager.accelerometerUpdateInterval = 1 / 60.0; // 4)开始采样数据 [self
startAccelerometerUpdates]; } else
{ NSLog(@"摔坏了"); } // 实例化游戏时钟 防止小球虚化显示 montionManager负责采集,CADisplayLink 负责显示_gameTimer = [CADisplayLink displayLinkWithTarget:selfselector:@selector(updateLocation)]; // 将时钟添加到主运行循环中[_gameTimer addToRunLoop:[NSRunLoop
mainRunLoop] forMode:NSDefaultRunLoopMode];} |
2. 设置MontionManager单例,方便使用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 |
static MyMontionManager *_instance;@implementation
MyMontionManager+ (id)allocWithZone:(struct
_NSZone *)zone{ static
dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super
allocWithZone:zone]; }); return
_instance;}+ (instancetype)sharedMyMontionManager{ if
(_instance == nil) { _instance = [[MyMontionManager alloc] init]; } return
_instance;}@end |
3. 采样方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
- (void)startAccelerometerUpdates{ // 操作队列是负责处理采样的数据[[MyMontionManager sharedMyMontionManager] startAccelerometerUpdatesToQueue:_queue withHandler:^(CMAccelerometerData *accelerometerData, NSError
*error) { // 处理采样数据,修改小球速度 _ballVelocity.x += accelerometerData.acceleration.x; _ballVelocity.y -= accelerometerData.acceleration.y; NSLog(@"%@", [NSThread
currentThread]); }];} |
4. 更改小球位置、
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 |
- (void)updateLocation{ NSLog(@"==== %@", [NSThread
currentThread]); // 设置小球的位置 CGPoint center = _ball.center; CGSize size = self.view.bounds.size; // 解决小球出界问题,碰撞检测 // 水平方向:左边,右边 if
(CGRectGetMinX(_ball.frame) <= 0 || CGRectGetMaxX(_ball.frame) >= size.width) { // 修改小球的速度方向 _ballVelocity.x *= -1; // 修复位置 < 0 if
(CGRectGetMinX(_ball.frame) <= 0) { center.x = _ball.bounds.size.width / 2.0; } else
{ center.x = size.width - _ball.bounds.size.width / 2.0; } } // 垂直方向 if
(CGRectGetMinY(_ball.frame) <= 0 || CGRectGetMaxY(_ball.frame) >= size.height) { // 修改小球的速度方向 _ballVelocity.y *= -1; // 修复位置 < 0 if
(CGRectGetMinY(_ball.frame) <= 0) { center.y = _ball.bounds.size.height / 2.0; } else
{ center.y = size.height - _ball.bounds.size.height / 2.0; } } center.x += _ballVelocity.x; center.y += _ballVelocity.y; _ball.center = center; //在mainloop中,所以不需要队列} |
5 触摸停止/启动
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event{ // 正在采样数据,说明游戏进行中,暂停if
([MyMontionManager sharedMyMontionManager].isAccelerometerActive) { // 定制采样数据 [[MyMontionManager sharedMyMontionManager] stopAccelerometerUpdates]; // 停止时钟 // invalidate停止时钟 // 1> 将时钟从主运行循环中撤销 // 2> 将时钟销毁// [_gameTimer invalidate]; // 直接从主运行循环中将游戏时钟删除,而不会销毁时钟,等到需要时再次添加即可。 [_gameTimer removeFromRunLoop:[NSRunLoop
mainRunLoop] forMode:NSDefaultRunLoopMode]; } else
{ // 开始采样加速计数据 [self
startAccelerometerUpdates]; [_gameTimer addToRunLoop:[NSRunLoop
mainRunLoop] forMode:NSDefaultRunLoopMode]; } } |
原文:http://www.cnblogs.com/dqxu/p/3595762.html