IOS 加速计

加速计(UIAccelerometer)是一个单例模式的类,所以需要通过方法sharedAccelerometer获取其唯一的实例。
加速计需要设置的主要有两个:
一个是设置其代理,用以执行获取 加速计信息的方法;
 另一个是设置 加速计获取信息的频率。 最高支持每秒100次。

UIAccelerometer *accelerometer = [UIAccelerometersharedAccelerometer];

accelerometer.delegate =self;

accelerometer.updateInterval =1.0/30.0f;


下面是加速计的代理方法,需要符合协议<UIAccelerometerDelegate>.

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

{

//    NSString *str = [NSString stringWithFormat:@"x:%g\ty:%g\tz:%g",acceleration.x,acceleration.y,acceleration.z];

//    NSLog(@"%@",str);


   //检测摇动, 1.5为轻摇,2.0为重摇

//    if (fabsf(acceleration.x)>1.8||

//        fabsf(acceleration.y)>1.8||

//        fabsf(acceleration.z>1.8)) {

//        NSLog(@"你摇动我了~");

//    }

    static NSInteger shakeCount = 0;

    static NSDate *shakeStart;

    NSDate *now = [[NSDate alloc]init];

    NSDate *checkDate = [[NSDatealloc]initWithTimeInterval:1.5fsinceDate:shakeStart];

    if ([now compare:checkDate] == NSOrderedDescending || shakeStart ==nil) {

        shakeCount =0;

        [shakeStart release];

        shakeStart = [[NSDatealloc]init];

    }

    [now release];

    [checkDate release];

    

    if (fabsf(acceleration.x)>1.7||

        fabsf(acceleration.y)>1.7||

        fabsf(acceleration.z)>1.7) {

        shakeCount ++;

        if (shakeCount >4) {

            NSLog(@"你摇动我了~");

            shakeCount =0;

            [shakeStartrelease];

            shakeStart = [[NSDatealloc]init];

        }

    }

}



iphone静止时受到的地球引力为1g,这是加速计确定手机朝向的基础。分为三个轴x,y,z,如果手机以任何方式垂直水平放置,这1g的力将分布在一条轴上,如果设备倾斜,将分布在多条轴上。

    可通过UIAccelerometer单例来使用加速计。UIAccelerometer定义了一种协议————UIAcceleromerterDelegateProtocol,必须实现他才能获得加速计的测量值,代理将以设定的频率收到更新。

  让应用程序使用加速器有三步:获取单例,指定代理,指定频率

  UIAccelerometer *accelerometer=[UIAccelerometer sharedAccelerometer];

  accelerometer.delegate=self;

  accelerometer.updateInterval=0.1//10 times per sec

 其中UIAccelerometerDelegateProtocol只有一个方法:accelerometer:didAccelerate 他将UIAccelerate单例和一个UIAcceleration对象作为参数。UIAcceleration对象通过属性提供了三个轴的当前读数以及测量读数的时间。

   检测朝向,我们来创建个小实验,来指出iphone当前处于正立,倒立,左立,右立,正面朝向和正面朝下。

首先在h文件中添加一个label 并property一下

在xib中连接好设置的控件,我们用label显示手机的位置情况

   下面我们来实现UIAccelerometerDelegate协议,所以我们将视图控制器指定为加速器代理,频率也不用太高,每秒两次就够了。可以在viewdidload方法中指定代理和更新间隔。

    我们剩下的唯一工作就是实现accelerometer:didAccelerate方法了,我们使用UIAcceleration对象的xyz属性来判断那个轴上的重力最大,因此可将读数设置为大于0.5或小于-0.5

   下面我们来修改m中的代码,

   #pragma mark -

   #pragma mark UIAccelerometerDelegate

    -(void)accelerometer:(UIAccelerometer *)accelerometer

      didAcceler:(UIAcceleration *)acceleration

{

if(acceleration.x>0.5)

{

orientation.text=@"Right side";

}

else if(acceleration.x<-0.5)

{

orientation.text=@"left side";

}

else if(acceleration.y>0.5)

{

orientation.text=@"upsid down";

}

else if(acceleratrion.y<-0.5)

{

orientation.text=@"standing up";

}

else if(acceleration.z>.5)

{

orientation.text=@"facedown";

}

else if(acceleration.z<-0.5)

{

orientation.text=@"face up";

}

 

    

下面我在viewdidload中添加刚才上述的获取加速器的三步,就可以完成这个小实验了

 检测手机倾斜

 我们玩的赛车游戏中,应该就是用的这个检测倾斜来控制方向的,学会了这个,我们就可以做个小游戏了,下面我们来做个小实验

  首先还是在h中添加UIAccelerometerDelegate,然后创建个UIView,property一下,在xib中,吧background设置为一种颜色。把做好的背景和刚刚的UIview连接。

  下面我们在UIAccelerometerDelegate中实现协议,我们在这个试验中只考虑x轴的倾斜程度,也就是说读数越接近1.0 -1.0颜色越纯。接近0设置为透明。我们用fabs()方法来获取绝对值,这样就不用考虑iphone向哪个方向倾斜了

下面我们来实现这个delegate的方法

-(void)accelerometer:(UIAcclerometer *)accelerometer

  didAccelerate:(UIAcceleration *)acceleration

{

 UIAccelerationValue value=fabs(acceleration.x);

if(value>1.0){value=1.0}

colorView.alpha=value;

}

最后我们还是在viewdidload中加入开始提到的那三步。

 到深夜了,天津海河边上就是冷啊,这屋子里面和冰箱一样,很困了,我们再来说最后的,加速器如何检测iphone的移动呢。

  其实iphone有两种方法检测,一种是找出大于1g的力,适合快速移动时候的检测,一种是实现一个过滤器,来计算重力与加速计测量到的力的差,并认为这种差导致iphone在空间中移动。

  下面我们还是写一个小程序,让用户能在6个方向之一快速移动来改变屏幕颜色。

  -(void)setBaseColor:(UIAcceleration *)acceleration

{

if(acceleration.x>1.3)

{

colorView。backgroundcolor=[UIcolor greencolor];

}

else if(acceleration.x<-1.3)

{

colorVIew.backgroundcolor=[UIcolor orangecolor];

}

.....(此处略去其他方向的代码了)

}

 

-(void)accelerometer:(UIAcclerometer *)accelerometer

  didAccelerate:(UIAcceleration *)acceleration

{

[self setbasecoulor:acceleration];

 UIAccelerationValue value=fabs(acceleration.x);

if(value>1.0){value=1.0}

colorView.alpha=value;

}

 

}


UIAccelerometer加速计是用来检测iphone手机在x.y.z轴三个轴上的加速度。要获得此类调用:

UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
同时,你需要设置它的delegate。
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.delegate = self;
accelerometer.updateInterval = 1.0/60.0;
委托方法:- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration中的UIAcceleration是表示 加速度类。包含了来自 加速计UIAccelerometer的真是数据。它有3个属性的值x、y、z。iphone的 加速计支持最高以每秒100次的频率进行轮询。此时是60次。
1) 应用程序可以通过 加速计来检测摇动,如:用户可以通过摇动iphone擦除绘图。
也可以用户连续摇动几次iphone,执行一些特殊的代码:
- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
static NSInteger shakeCount = 0;
static NSDate *shakeStart;
NSDate *now = [[NSDate alloc] init];
NSDate *checkDate = [[NSDate alloc] initWithTimeInterval:1.5f sinceDate:shakeStart];
if ([now compare:checkDate] == NSOrderedDescending || shakeStart == nil)
{
shakeCount = 0;
[shakeStart release];
shakeStart = [[NSDate alloc] init];
}
[now release];
[checkDate release];
if (fabsf(acceleration.x) > 2.0 || fabsf(acceleration.y) > 2.0 || fabsf(acceleration.z) > 2.0)
{
shakeCount++;
if (shakeCount > 4)
{
// -- DO Something
shakeCount = 0;
[shakeStart release];
shakeStart = [[NSDate alloc] init];
}
}
}
2)  加速计最常见的是用作游戏控制器。在游戏中使用 加速计控制对象的移动!在简单情况下,可能只需获取一个轴的值,乘上某个数(灵敏度),然后添加到所控制对象的坐标系中。在复杂的游戏中,因为所建立的物理模型更加真实,所以必须根据 加速计返回的值调整所控制对象的速度。


在cocos2d中接收 加速计输入input.使其平滑运动,一般不会去直接改变对象的position.通过:
- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
// -- controls how quickly velocity decelerates(lower = quicker to change direction)
float deceleration = 0.4; 
// -- determins how sensitive the accelerometer reacts(higher = more sensitive)
float sensitivity = 6.0;
// -- how fast the velocity can be at most
float maxVelocity = 100;
// adjust velocity based on current accelerometer acceleration
playerVelocity.x = playerVelocity.x * deceleration + acceleration.x * sensitivity;
// -- we must limit the maximum velocity of the player sprite, in both directions
if (playerVelocity.x > maxVelocity)
{
playerVelocity.x = maxVelocity;
}
else if (playerVelocity.x < - maxVelocity)
{
playerVelocity.x = - maxVelocity;
}
}
上面deceleration是减速的比率,sensitivity是灵敏度。maxVelocity是最大速度,如果不限制则一直加大就很难停下来。
playerVelocity.x = playerVelocity.x * deceleration + acceleration.x * sensitivity;
中 playervelocity是一个速度向量。是累积的。
- (void) update: (ccTime)delta
{
// -- keep adding up the playerVelocity to the player's position
CGPoint pos = player.position;
pos.x += playerVelocity.x;
// -- The player should also be stopped from going outside the screen
CGSize screenSize = [[CCDirector sharedDirector] winSize];
float imageWidthHalved = [player texture].contentSize.width * 0.5f;
float leftBorderLimit = imageWidthHalved;
float rightBorderLimit = screenSize.width - imageWidthHalved;
// -- preventing the player sprite from moving outside the screen
if (pos.x < leftBorderLimit)
{
pos.x = leftBorderLimit;
playerVelocity = CGPointZero;
}
else if (pos.x > rightBorderLimit)
{
pos.x = rightBorderLimit;
playerVelocity = CGPointZero;
}
// assigning the modified position back
player.position = pos;

}

其他资料:
内置 加速计是iPhone和iPodTouch中最酷的特性之一,iPhone可以通过这个小设备知道用户握持手机的方式,以及用户是否移动了手机。iPhoneOS使用 加速计处理自动旋转,并且许多游戏都使用他做为控制机制。它还可以用于检测摇动和其他突发的运动。

 

加速计物理学
通过感知特定方向的惯性力总量,加速计可以测量出加速度和重力。iPhone内的加速计是一个三轴加速计,这意味着他能够检测到三维空间中的运动或重力引力。因此,加速计不但可以指示握持电话的方式(如自动旋转功能),而且如果电话放在桌子上的话,还可以指示电话的正面朝下还是朝上。
加速计可以测量g引力,因此加速计返回值为1.0时,表示在特定方向上感知到1g。如果是静止握持iPhone而没有任何运动,那么地球引力对其施加的力大约为1g。如果是纵向竖直地握持iPhone,那么iPhone会检测并报告其y轴上施加的力大约为1g。如果是以一定角度握持iPhone,那么1g的力会分布到不同的轴上,这取决于握持iPhone的方式。在以45度角握持时,1g的力会均匀地分解到两个轴上。


如果检测到的加速计值远大于1g,那么即可以判断这是突然运动。正常使用时,加速计在任一轴上都不会检测到远大于1g的值。如果摇动、坠落或投掷iPhone,那么加速计便会在一个或多个轴上检测到很大的力。
iPhone加速计使用的三轴结构是:iPhone长边的左右是X轴(右为正),短边的上下是Y轴(上为正),垂直于iPhone的是Z轴(正面为正)。需要注意的是,加速计对y坐标轴使用了更标准的惯例,即y轴伸长表示向上的力,这与Quartz2D的坐标系相反。如果加速计使用Quartz 2D做为控制机制,那么必须要转换y坐标轴。使用OpenGL ES时则不需要转换。


 访问加速
UIAccelerometer类是单独存在的。要获取对此类的引用,请调用sharedAccelerometer方法:

UIAccelerometer *accelerometer=[UIAccelerometersharedAccelerometer];

加速计获取信息与从CoreLocation获取信息相似。创建一个符合UIAccelerometerDelegate协议的类,执行可以获取加速计信息的方法。
在分配委托时,需要以秒指定更新间隔。iPhone的加速计支持最高以每秒100次的频率进行轮询,但无法保证真正达到这么多次更新,或者可以精确均匀分隔这些更新。要分配委托或指定轮询间隔为每秒60次,可以如下所示:

accelerometer.delegate=self;
accelerometer.updateInterval=1.0f/60.0f;

完成之后,剩余的事情是实现加速计用于更新委托的方法,accelerometer:didAccelerate:。第二个变量包含了来自加速计的真实数据,嵌入在类UIAcceleration的一个对象中。

 UIAcceleration
如前所述,iPhone加速计可以检测3个轴上的加速度,并且对使用UIAcceleration类实例的委托提供此信息。每个UIAcceleration实例都有x、y和z的属性,分别有一个带符号的浮点值。值0表示加速计在此轴上没有检测到任何运动。正值或负值表示一个方向上的力。例如,y的负值表示感受到了向下的力,这可能表示电话是纵向竖直握持的。y的正值表示在向上的方向施加了某些力,这可能意味着电话是倒置的或者电话正在向下运动。(这里有点疑问?说反了吧?)
请在头脑中牢记图15-1的示意图,并查看加速计结果。注意,在现实生活中,几乎不可能获得如此精确的值,因为加速计非常敏感,可以感知非常微笑的运动,而我们通常只能感知立体空间3个轴上的某一个微小受力。这是现实世界中的物理,而不是高中物理实验室。

iPhone开发基础教程笔记(十五)--第十五章 <strong>加速</strong>计 - supershll - 记忆里

 实现accelerometer:didAccelertae:方法

- (void)accelerometer:(UIAccelerometer *)accelerometerdidAccelerate:(UIAcceleration *)acceleration {
NSString *newText=[[NSString alloc] initWithFormat:@"Max: x:%g\ty:%g\tz:

%g",acceleration.x,acceleration.y,acceleration.z];
label.text=newText;
[newText release];
}

此方法可以在每次调用时更改界面上的标签,调用此方法的频率取决于以前指定的updateInterval的值。

1,检测摇动
加速计通常用于检测摇动。与手势相似,摇动可以作为应用程序输入的一种形式。例如,对于绘图程序GLPaint,iPhone的示例代码之一,用户可以通过摇动iPhone擦除绘图,就像Etch-a-Sketch一样。摇动检测功能相对来说是微不足道的,主需要检查某个轴上的绝对值是否大于阈值(yu)。在正常使用期间,3个轴之一所注册的值通常在1.3g左右,若要远高于此值,则需要刻意施加力量。加速计好像不能注册高于2.3g左右的值。因此,请勿将阈值设置得高于此值。

要检测摇动,请检查绝对值是否大于1.5(表示轻微摇动)和2.0(表示剧烈摇动),代码如下:

- (void)accelerometer:(UIAccelerometer *)accelerometerdidAccelerate:(UIAcceleration *)acceleration {
if (fbasf(acceleration.x)>2.0 ||fbasf(acceleration.y)>2.0 ||fbasf(acceleration.z)>2.0 ) {
//do something here...
}
}

上述方法可以检测到任一轴上任何超过2g力的运动。通过要求用户前后摇动一定次数才能注册为一次摇动,我们可以执行更复杂的摇动检测,代码如下:

- (void)accelerometer:(UIAccelerometer *)accelerometerdidAccelerate:(UIAcceleration *)acceleration {
static NSInteger shakeCount=0;
static NSDate *shakeStart;

NSDate *now=[[NSDate alloc] init];
NSDate *checkDate=[[NSDate alloc] initWithTimeInterval:1.5fsinceDate:shakeStart];

if ([now compare:checkDate]==NSOrderedDescending || shakeStart==nil) {
shakeCount=0;
[shakeStart release];
shakeStart=[[NSDate alloc] init];
}
[now release];
[checkDate release];

if (fbasf(acceleration.x)>2.0 ||fbasf(acceleration.y)>2.0 ||fbasf(acceleration.z)>2.0 ) {
shakeCount++;
if (shakeCount>4) {
//do something
shakeCount=0;
[shakeStart release];
shakeStart=[[NSDate alloc] init];
}
}
}

此方法可以查明加速计报告的值大于2的次数,如果在1.5s的时间内发送了4次,则注册为一次摇动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值